From wmiles@ft.newyorklife.com Mon Sep 1 02:04:16 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE,T_FRT_CONTACT autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 197F27F57 for ; Mon, 1 Sep 2014 02:04:16 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8B718AC005 for ; Mon, 1 Sep 2014 00:04:12 -0700 (PDT) X-ASG-Debug-ID: 1409555050-04cbb05485982120001-NocioJ Received: from mgwadcp05.newyorklife.com (obmail.newyorklife.com [206.210.16.25]) by cuda.sgi.com with ESMTP id NSurkdCoBkJvuEZ4 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 01 Sep 2014 00:04:11 -0700 (PDT) X-Barracuda-Envelope-From: wmiles@ft.newyorklife.com X-Barracuda-Apparent-Source-IP: 206.210.16.25 X-Barracuda-IPDD: Level2 [ft.newyorklife.com/206.210.16.25] X-IronPort-AV: E=Sophos;i="5.04,440,1406606400"; d="scan'208,217";a="187295079" X-Barracuda-IPDD: Level2 [ft.newyorklife.com/206.210.16.25] X-Barracuda-IPDD: Level2 [ft.newyorklife.com/206.210.16.25] X-IronPort-AV: E=Sophos;i="5.04,440,1406606400"; d="scan'208,217";a="187295063" Received: from nyp-cashbmb3-cj.ftmail.dist.us.newyorklife.com ([172.31.85.106]) by mgwadcp05.newyorklife.com with ESMTP/TLS/AES128-SHA; 01 Sep 2014 03:04:01 -0400 Received: from NYP-CASHBMB2-CJ.FTMAIL.DIST.US.NEWYORKLIFE.COM ([fe80::dc8c:759d:654:7346]) by NYP-CASHBMB3-CJ.ftmail.dist.us.newyorklife.com ([fe80::7c12:abb3:38c0:db41%22]) with mapi id 14.03.0158.001; Mon, 1 Sep 2014 03:04:00 -0400 From: Willie J Miles Subject: Thread-Index: Ac/FsufiidfYTyWtTY2y0KlELlflAA== X-ASG-Orig-Subj: Date: Mon, 1 Sep 2014 07:04:00 +0000 Message-ID: <11C6440AA2FB6E409B6505395B20654D3CEDF114@NYP-CASHBMB2-CJ.ftmail.dist.us.newyorklife.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [192.168.106.46] Content-Type: multipart/alternative; boundary="_000_11C6440AA2FB6E409B6505395B20654D3CEDF114NYPCASHBMB2CJft_" MIME-Version: 1.0 X-CFilter-Loop: Reflected X-Barracuda-Connect: obmail.newyorklife.com[206.210.16.25] X-Barracuda-Start-Time: 1409555050 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 To: undisclosed-recipients:; --_000_11C6440AA2FB6E409B6505395B20654D3CEDF114NYPCASHBMB2CJft_ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Haben Sie finanzielle Unterst=FCtzung jeder Art m=FCssen? Pers=F6nliche Darlehen? Business-Darlehen? Hypothekendarlehen? Agrar-und Projektfinanzierung? Wir geben Kredite bei 3% A.P.I. Rate! Kontakt; creditspa@admin.in.th =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Do you need Financial assistance of any kind? Personal Loans? Business Loans? Mortgage loans? Agricultural and project funding? We give out loans at 3% A.P.I. rate! Contact ;creditspa@admin.in.th --_000_11C6440AA2FB6E409B6505395B20654D3CEDF114NYPCASHBMB2CJft_ Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable
Haben Sie finanzielle Unterst=FCtzung jeder Art m=FCssen? 
Pers=F6nliche Darlehen? 
Business-Darlehen? 
Hypothekendarlehen? 
Agrar-und Projektfinanzierung? 

Wir geben Kredite bei 3% A.P.I. Rate! Kontakt; creditspa@admin.in.th
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D
Do you need Financial assistance of any kind?
Personal Loans?
Business Loans?
Mortgage loans?
Agricultural and project funding?

We give out loans at 3% A.P.I. rate! Contact ;creditspa@admin.in.th
--_000_11C6440AA2FB6E409B6505395B20654D3CEDF114NYPCASHBMB2CJft_-- From squatral@bidmc.harvard.edu Mon Sep 1 02:33:26 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=unavailable version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 0EC8F7F57 for ; Mon, 1 Sep 2014 02:33:26 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id D3CA3304048 for ; Mon, 1 Sep 2014 00:33:22 -0700 (PDT) X-ASG-Debug-ID: 1409556800-04bdf010a068c340001-NocioJ Received: from SR48Maunakea.caregroup.org (securemail.bidmc.harvard.edu [134.174.104.36]) by cuda.sgi.com with ESMTP id 4f3pIu3gbFYICOQL (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO); Mon, 01 Sep 2014 00:33:21 -0700 (PDT) X-Barracuda-Envelope-From: squatral@bidmc.harvard.edu X-Barracuda-Apparent-Source-IP: 134.174.104.36 Received: from pps.filterd (SR48Maunakea.caregroup.org [127.0.0.1]) by SR48Maunakea.caregroup.org (8.14.7/8.14.7) with SMTP id s817DR8p012998; Mon, 1 Sep 2014 00:16:27 -0700 Received: from sr61rouse.its.caregroup.org (sr61rouse.bidmc.harvard.edu [10.25.51.77]) by SR48Maunakea.caregroup.org with ESMTP id 1nwpaeq72m-1 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT); Mon, 01 Sep 2014 00:16:26 -0700 Received: from EVS4CCR.its.caregroup.org ([fe80::5509:c421:f730:1ef4]) by SR61ROUSE.its.caregroup.org ([::1]) with mapi; Mon, 1 Sep 2014 03:23:03 -0400 From: Date: Mon, 1 Sep 2014 03:23:02 -0400 Subject: Financiering Thread-Topic: Financiering X-ASG-Orig-Subj: Financiering Thread-Index: AQHPxbWQbXtQX3Jr5Uu+q1ec3biZ0w== Message-ID: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US Content-Type: multipart/alternative; boundary="_000_ED1FA742B8C9BC4F8A9ED7C111530AC94CE90A5A79EVS4CCRitscar_" MIME-Version: 1.0 x-recipient-trigger: true X-Barracuda-Connect: securemail.bidmc.harvard.edu[134.174.104.36] X-Barracuda-Start-Time: 1409556800 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-BRTS-Evidence: 11fb7d69a730025d4aaf1d7f5a17460e-2338-htm X-Barracuda-Spam-Score: 1.23 X-Barracuda-Spam-Status: No, SCORE=1.23 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE, MISSING_HEADERS, NO_REAL_NAME, THREAD_INDEX, THREAD_TOPIC, TO_CC_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9053 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.00 NO_REAL_NAME From: does not include a real name 0.01 THREAD_TOPIC Thread-Topic: ...(Japanese Subject)... 1.21 MISSING_HEADERS Missing To: header 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 TO_CC_NONE No To: or Cc: header To: undisclosed-recipients:; --_000_ED1FA742B8C9BC4F8A9ED7C111530AC94CE90A5A79EVS4CCRitscar_ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable We zijn momenteel aanbieden van zakelijke en persoonlijke leningen. Dit is om uw kennis die wij bieden lening / krediet bij 3% rente per jaa= r aan de individuele en bedrijf aan te brengen. Onze investeerders financie= ren ook projecten. Voor meer informatie, naar voren uw reactie alleen op de= ze E-mail: f-spa@webadicta.org Als u behoefte heeft aan een snelle lening of financiering van grote noodza= ak, vooruit uw antwoord alleen op deze e-mail: f-spa@webadicta.org Dank u voor uw tijd. Copyright 2014. SPA =AE =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Nous offrons actuellement des entreprises et des pr=EAts personnels. C'est =E0 porter =E0 votre connaissance que nous offrons pr=EAt / cr=E9= dit =E0 taux d'int=E9r=EAt de 3% par an =E0 l'individu et de la soci=E9t=E9= . Nos investisseurs financent aussi des projets. Pour plus d'informations, = faites parvenir votre r=E9ponse uniquement =E0 ce courriel: f-spa@webadicta= .org Si vous avez besoin d'un pr=EAt rapide ou le besoin de financement importan= t, faire parvenir votre r=E9ponse uniquement =E0 cet email : f-spa@webadict= a.org Je vous remercie pour votre temps. Copyright 2014. SPA =AE ________________________________ This message is intended for the use of the person(s) to whom it may be add= ressed. It may contain information that is privileged, confidential, or oth= erwise protected from disclosure under applicable law. If you are not the i= ntended recipient, any dissemination, distribution, copying, or use of this= information is prohibited. If you have received this message in error, ple= ase permanently delete it and immediately notify the sender. Thank you. --_000_ED1FA742B8C9BC4F8A9ED7C111530AC94CE90A5A79EVS4CCRitscar_ Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable
=  


We zijn momenteel aanbieden van zakelijke en persoonlijke leningen.
   Dit is om uw kennis die wij bieden lening / krediet bij 3% ren= te per jaar aan de individuele en bedrijf aan te brengen. Onze investeerder= s financieren ook projecten. Voor meer informatie, naar voren uw reactie al= leen op deze E-mail: f-spa@webadicta.org
 
Als u behoefte heeft aan een snelle lening of financiering van grote noodza= ak, vooruit uw antwoord alleen op deze e-mail: f-spa@webadicta.org

Dank u voor uw tijd.
Copyright 2014. SPA =AE
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Nous offrons actuellement des entreprises et des pr=EAts personnels.
    C'est =E0 porter =E0 votre connaissance que nous offrons= pr=EAt / cr=E9dit =E0 taux d'int=E9r=EAt de 3% par an =E0 l'individu et de= la soci=E9t=E9. Nos investisseurs financent aussi des projets. Pour plus d= 'informations, faites parvenir votre r=E9ponse uniquement =E0 ce courriel: f-spa@webadicta.org
 
Si vous avez besoin d'un pr=EAt rapide ou le besoin de financement importan= t, faire parvenir votre r=E9ponse uniquement =E0 cet email : f-spa@webadicta.org
Je vous remercie pour votre temps.
Copyright 2014. SPA =AE



This message is intended for= the use of the person(s) to whom it may be addressed. It may contain infor= mation that is privileged, confidential, or otherwise protected from disclo= sure under applicable law. If you are not the intended recipient, any dissemination, distribution, copying, or u= se of this information is prohibited. If you have received this message in = error, please permanently delete it and immediately notify the sender. Than= k you.
--_000_ED1FA742B8C9BC4F8A9ED7C111530AC94CE90A5A79EVS4CCRitscar_-- From eflorac@intellique.com Mon Sep 1 14:18:56 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B13347F66 for ; Mon, 1 Sep 2014 14:18:56 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9136A304032 for ; Mon, 1 Sep 2014 12:18:53 -0700 (PDT) X-ASG-Debug-ID: 1409599130-04bdf010a06aa8b0001-NocioJ Received: from smtp3-g21.free.fr (smtp3-g21.free.fr [212.27.42.3]) by cuda.sgi.com with ESMTP id yABqNnfq7FnLQPdN (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 01 Sep 2014 12:18:51 -0700 (PDT) X-Barracuda-Envelope-From: eflorac@intellique.com X-Barracuda-Apparent-Source-IP: 212.27.42.3 Received: from galadriel.home (unknown [82.235.234.79]) by smtp3-g21.free.fr (Postfix) with ESMTP id DEAC0A6263; Mon, 1 Sep 2014 21:18:49 +0200 (CEST) Date: Mon, 1 Sep 2014 21:19:32 +0200 From: Emmanuel Florac To: Samuel GRANJEAUD IR/INSERM Cc: xfs@oss.sgi.com Subject: Re: Run out of inodes? Message-ID: <20140901211932.342b4bb3@galadriel.home> X-ASG-Orig-Subj: Re: Run out of inodes? In-Reply-To: <8d5fff2548d35737c6cebcb1f6382e80@inserm.fr> References: <54005108.1020203@inserm.fr> <20140829114806.GA17610@bfoster.bfoster> <5400802C.5050005@inserm.fr> <54009603.9050404@sandeen.net> <8d5fff2548d35737c6cebcb1f6382e80@inserm.fr> Organization: Intellique X-Mailer: Claws Mail 3.10.0 (GTK+ 2.24.20; i486-slackware-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: smtp3-g21.free.fr[212.27.42.3] X-Barracuda-Start-Time: 1409599131 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9069 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Le Sat, 30 Aug 2014 21:33:46 +0200 vous =C3=A9criviez: > Final question: could some issues appear with SAMBA? >=20 > # smbstatus -V > Version 3.4.5 Is your whole distribution 64 bits, or only the kernel? However, I've never had any problem with samba, but some with NFS. --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From odon@prover.com.br Mon Sep 1 17:34:43 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 809937F66 for ; Mon, 1 Sep 2014 17:34:43 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1B6F3AC003 for ; Mon, 1 Sep 2014 15:34:43 -0700 (PDT) X-ASG-Debug-ID: 1409610881-04cbb054859a2bd0001-NocioJ Received: from hcsaturno.pib.com.br (hcsaturno.pib.com.br [200.194.176.52]) by cuda.sgi.com with ESMTP id ndudKin3efBLiV4I for ; Mon, 01 Sep 2014 15:34:41 -0700 (PDT) X-Barracuda-Envelope-From: odon@prover.com.br X-Barracuda-Apparent-Source-IP: 200.194.176.52 Received: from localhost (localhost [127.0.0.1]) by hcsaturno.pib.com.br (Postfix) with ESMTP id D93533A48BF5; Mon, 1 Sep 2014 19:20:41 -0300 (BRT) Received: from hcsaturno.pib.com.br ([127.0.0.1]) by localhost (hcsaturno.pib.com.br [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id t4ICIV8m4z7k; Mon, 1 Sep 2014 19:20:37 -0300 (BRT) Received: from localhost (localhost [127.0.0.1]) by hcsaturno.pib.com.br (Postfix) with ESMTP id 96A1E3F620D5; Mon, 1 Sep 2014 19:13:16 -0300 (BRT) X-Virus-Scanned: amavisd-new at skysat.com.br Received: from hcsaturno.pib.com.br ([127.0.0.1]) by localhost (hcsaturno.pib.com.br [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id dzRFZXG0_nFh; Mon, 1 Sep 2014 19:13:16 -0300 (BRT) Received: from hcsaturno.pib.com.br (hcsaturno.pib.com.br [200.194.176.52]) by hcsaturno.pib.com.br (Postfix) with ESMTP id D71913F67FCE; Mon, 1 Sep 2014 19:06:51 -0300 (BRT) Date: Mon, 1 Sep 2014 19:06:49 -0300 (BRT) From: Support! Reply-To: Support! Message-ID: <765495068.3746496.1409609209207.JavaMail.root@prover.com.br> Subject: Caro Membro (R) MIME-Version: 1.0 X-ASG-Orig-Subj: Caro Membro (R) Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Originating-IP: [103.253.181.24] X-Mailer: Zimbra 8.0.3_GA_5664 (ZimbraWebClient - GC36 (Win)/8.0.3_GA_5664) Thread-Topic: Caro Membro (R) Thread-Index: p5yR7rNxi7ixi/ZIRQbS6jSDNBK8fA== X-Barracuda-Connect: hcsaturno.pib.com.br[200.194.176.52] X-Barracuda-Start-Time: 1409610881 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.23 X-Barracuda-Spam-Status: No, SCORE=1.23 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=MISSING_HEADERS, THREAD_INDEX, THREAD_TOPIC, TO_CC_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9075 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.01 THREAD_TOPIC Thread-Topic: ...(Japanese Subject)... 1.21 MISSING_HEADERS Missing To: header 0.00 TO_CC_NONE No To: or Cc: header To: undisclosed-recipients:; Caro Membro (R).=20 Esta mensagem =C3=A9 do centro de mensagens do Webmail.Team a todos os noss= os novos propriet=C3=A1rios de conta de e-mail antigas /. Momento, estamos = atualizando nossa base de dados e um centro de conta de e-mail como n=C3=B3= s entramos em um novo m=C3=AAs de setembro. Estamos a excluir todas as cont= as de e-mail n=C3=A3o utilizados criar mais espa=C3=A7o para novas contas.= =20 Para evitar que sua conta seja fechada, voc=C3=AA ter=C3=A1 que atualiz=C3= =A1-lo abaixo para que possamos saber que =C3=A9 um presente usado account.= fill abaixo=20 =C2=A0=C2=A0 * Nome de usu=C3=A1rio:=20 * Senha:=20 * Data de nascimento:=20 * Pa=C3=ADs ou territ=C3=B3rio=20 Aviso !!! O n=C3=A3o cumprimento das directivas acima dentro de 24 horas=20 receber este aviso implicar=C3=A1 a exclus=C3=A3o de tal conta de e-mail.= =20 Obrigado.=20 Aviso C=C3=B3digo: KMM88117359V17087L0KM=20 Atenciosamente,=20 Webmail.Team Atendimento ao Cliente. From david@fromorbit.com Mon Sep 1 18:45:40 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 9236C7F66 for ; Mon, 1 Sep 2014 18:45:40 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 12E52AC001 for ; Mon, 1 Sep 2014 16:45:36 -0700 (PDT) X-ASG-Debug-ID: 1409615133-04cbb054869a4ef0001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id Cx1sDyWPS7jgwOvG for ; Mon, 01 Sep 2014 16:45:34 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AisSAKgDBVR5LDJ8PGdsb2JhbABZgw2BKoIshQenYwEBBAaaQIVyAYETFwUBAQEBODaEAwEBBAE6HCMQCAMYCSUPBSUDBxoTiDoHuiMBFxiFZIhvEQEHSQeETAWcW5cOFoFuKy+BBwgXgSkBAQE Received: from ppp121-44-50-124.lns20.syd6.internode.on.net (HELO dastard) ([121.44.50.124]) by ipmail06.adl2.internode.on.net with ESMTP; 02 Sep 2014 09:15:33 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XObHt-0005IT-W6; Tue, 02 Sep 2014 09:45:30 +1000 Date: Tue, 2 Sep 2014 09:45:29 +1000 From: Dave Chinner To: stan hoeppner Cc: xfs@oss.sgi.com Subject: Re: storage, libaio, or XFS problem? 3.4.26 Message-ID: <20140901234529.GI20518@dastard> X-ASG-Orig-Subj: Re: storage, libaio, or XFS problem? 3.4.26 References: <20140826075345.GJ20518@dastard> <8c29baf987467a84f0b7c1d09c863662@localhost> <20140828003226.GO20518@dastard> <7f9e5aef187b44e899077467aeb0809d@localhost> <20140828230817.GU20518@dastard> <2d2ce7bb38c00a7d35f4a324f6a36cbb@localhost> <20140829235538.GF20518@dastard> <20140831235749.GH20518@dastard> <5403E9B9.7040608@hardwarefreak.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5403E9B9.7040608@hardwarefreak.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1409615134 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9076 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sun, Aug 31, 2014 at 10:36:25PM -0500, stan hoeppner wrote: > On 08/31/2014 06:57 PM, Dave Chinner wrote: > > On Fri, Aug 29, 2014 at 09:55:53PM -0500, Stan Hoeppner wrote: > >> Have you played with bcache yet? > > > > Enough to scare me. So many ways for things to go wrong, no easy way > > to recover when things go wrong. And that's before I even get to > > performance warts, like having systems stall completely because > > there's tens or hundreds of GB of 4k random writes that have to be > > flushed to slow SATA RAID6 in the cache.... > > Yikes. I hadn't yet heard such opinions expressed. By go wrong I > assume you mean the btrees or cached sector data getting broken, corrupted? bcache is a complex filesystem hidden inside a block device. If bcache goes AWOL, so does the all the data on your block device. Need I say more? > > PS: can you wrap your text at 68 or 72 columns so quoted text > > doesn't overflow 80 columns and get randomly wrapped and messed up? > > This email should be. Lemme see what I can do with the others. The > lovely Cisco VPN client I must use kills routing to my local subnet, so > Icedovce can't connect to my IMAP server when the VPN is active. The > test hardness app requires a shell unfortunately so I have to keep the > tunnel open all the time, as the test runs are 40+ hours each. My last > test just crashed a bit ago so I can use Icedove for this reply. screen is your friend when it comes to keeping remote shells active as the network comes and goes. VPN drops out, just bring it back up when you need it and reconnect to the remote screen instance and it's like you never left.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From dgc@oss.sgi.com Mon Sep 1 21:19:16 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=NO_RELAYS autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: by oss.sgi.com (Postfix, from userid 10266) id 42C417F6C; Mon, 1 Sep 2014 21:19:16 -0500 (CDT) From: xfs@oss.sgi.com To: xfs@oss.sgi.com Subject: [XFS updates] XFS development tree branch, for-next, updated. xfs-for-linus-3.17-rc1-13183-g41b9d72 X-Git-Refname: refs/heads/for-next X-Git-Reftype: branch X-Git-Oldrev: 52addcf9d6669fa439387610bc65c92fa0980cef X-Git-Newrev: 41b9d7263ea1e270019c5d04fa0ab15db50b9725 Message-Id: <20140902021916.42C417F6C@oss.sgi.com> Date: Mon, 1 Sep 2014 21:19:14 -0500 (CDT) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "XFS development tree". The branch, for-next has been updated 41b9d72 xfs: trim eofblocks before collapse range 1669a8c xfs: xfs_file_collapse_range is delalloc challenged ca446d8 xfs: don't log inode unless extent shift makes extent modifications 7d4ea3c xfs: use ranged writeback and invalidation for direct IO 834ffca xfs: don't zero partial page cache pages during O_DIRECT writes 85e584d xfs: don't zero partial page cache pages during O_DIRECT writes 22e757a xfs: don't dirty buffers beyond EOF from 52addcf9d6669fa439387610bc65c92fa0980cef (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 41b9d7263ea1e270019c5d04fa0ab15db50b9725 Author: Brian Foster Date: Tue Sep 2 12:12:53 2014 +1000 xfs: trim eofblocks before collapse range xfs_collapse_file_space() currently writes back the entire file undergoing collapse range to settle things down for the extent shift algorithm. While this prevents changes to the extent list during the collapse operation, the writeback itself is not enough to prevent unnecessary collapse failures. The current shift algorithm uses the extent index to iterate the in-core extent list. If a post-eof delalloc extent persists after the writeback (e.g., a prior zero range op where the end of the range aligns with eof can separate the post-eof blocks such that they are not written back and converted), xfs_bmap_shift_extents() becomes confused over the encoded br_startblock value and fails the collapse. As with the full writeback, this is a temporary fix until the algorithm is improved to cope with a volatile extent list and avoid attempts to shift post-eof extents. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit 1669a8ca2105968f660cf7d84ba38fd18075cd99 Author: Dave Chinner Date: Tue Sep 2 12:12:53 2014 +1000 xfs: xfs_file_collapse_range is delalloc challenged If we have delalloc extents on a file before we run a collapse range opertaion, we sync the range that we are going to collapse to convert delalloc extents in that region to real extents to simplify the shift operation. However, the shift operation then assumes that the extent list is not going to change as it iterates over the extent list moving things about. Unfortunately, this isn't true because we can't hold the ILOCK over all the operations. We can prevent new IO from modifying the extent list by holding the IOLOCK, but that doesn't prevent writeback from running.... And when writeback runs, it can convert delalloc extents is the range of the file prior to the region being collapsed, and this changes the indexes of all the extents in the file. That causes the collapse range operation to Go Bad. The right fix is to rewrite the extent shift operation not to be dependent on the extent list not changing across the entire operation, but this is a fairly significant piece of work to do. Hence, as a short-term workaround for the problem, sync the entire file before starting a collapse operation to remove all delalloc ranges from the file and so avoid the problem of concurrent writeback changing the extent list. Diagnosed-and-Reported-by: Brian Foster Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit ca446d880c399bb31301e7d8eefbd7fe3c504c4e Author: Brian Foster Date: Tue Sep 2 12:12:53 2014 +1000 xfs: don't log inode unless extent shift makes extent modifications The file collapse mechanism uses xfs_bmap_shift_extents() to collapse all subsequent extents down into the specified, previously punched out, region. This function performs some validation, such as whether a sufficient hole exists in the target region of the collapse, then shifts the remaining exents downward. The exit path of the function currently logs the inode unconditionally. While we must log the inode (and abort) if an error occurs and the transaction is dirty, the initial validation paths can generate errors before the transaction has been dirtied. This creates an unnecessary filesystem shutdown scenario, as the caller will cancel a transaction that has been marked dirty. Modify xfs_bmap_shift_extents() to OR the logflags bits as modifications are made to the inode bmap. Only log the inode in the exit path if logflags has been set. This ensures we only have to cancel a dirty transaction if modifications have been made and prevents an unnecessary filesystem shutdown otherwise. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit 7d4ea3ce63a6bc532abb334c469c18481798af8c Author: Dave Chinner Date: Tue Sep 2 12:12:53 2014 +1000 xfs: use ranged writeback and invalidation for direct IO Now we are not doing silly things with dirtying buffers beyond EOF and using invalidation correctly, we can finally reduce the ranges of writeback and invalidation used by direct IO to match that of the IO being issued. Bring the writeback and invalidation ranges back to match the generic direct IO code - this will greatly reduce the perturbation of cached data when direct IO and buffered IO are mixed, but still provide the same buffered vs direct IO coherency behaviour we currently have. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit 834ffca6f7e345a79f6f2e2d131b0dfba8a4b67a Author: Dave Chinner Date: Tue Sep 2 12:12:52 2014 +1000 xfs: don't zero partial page cache pages during O_DIRECT writes Similar to direct IO reads, direct IO writes are using truncate_pagecache_range to invalidate the page cache. This is incorrect due to the sub-block zeroing in the page cache that truncate_pagecache_range() triggers. This patch fixes things by using invalidate_inode_pages2_range instead. It preserves the page cache invalidation, but won't zero any pages. cc: stable@vger.kernel.org Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit 85e584da3212140ee80fd047f9058bbee0bc00d5 Author: Chris Mason Date: Tue Sep 2 12:12:52 2014 +1000 xfs: don't zero partial page cache pages during O_DIRECT writes xfs is using truncate_pagecache_range to invalidate the page cache during DIO reads. This is different from the other filesystems who only invalidate pages during DIO writes. truncate_pagecache_range is meant to be used when we are freeing the underlying data structs from disk, so it will zero any partial ranges in the page. This means a DIO read can zero out part of the page cache page, and it is possible the page will stay in cache. buffered reads will find an up to date page with zeros instead of the data actually on disk. This patch fixes things by using invalidate_inode_pages2_range instead. It preserves the page cache invalidation, but won't zero any pages. [dchinner: catch error and warn if it fails. Comment.] cc: stable@vger.kernel.org Signed-off-by: Chris Mason Reviewed-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit 22e757a49cf010703fcb9c9b4ef793248c39b0c2 Author: Dave Chinner Date: Tue Sep 2 12:12:51 2014 +1000 xfs: don't dirty buffers beyond EOF generic/263 is failing fsx at this point with a page spanning EOF that cannot be invalidated. The operations are: 1190 mapwrite 0x52c00 thru 0x5e569 (0xb96a bytes) 1191 mapread 0x5c000 thru 0x5d636 (0x1637 bytes) 1192 write 0x5b600 thru 0x771ff (0x1bc00 bytes) where 1190 extents EOF from 0x54000 to 0x5e569. When the direct IO write attempts to invalidate the cached page over this range, it fails with -EBUSY and so any attempt to do page invalidation fails. The real question is this: Why can't that page be invalidated after it has been written to disk and cleaned? Well, there's data on the first two buffers in the page (1k block size, 4k page), but the third buffer on the page (i.e. beyond EOF) is failing drop_buffers because it's bh->b_state == 0x3, which is BH_Uptodate | BH_Dirty. IOWs, there's dirty buffers beyond EOF. Say what? OK, set_buffer_dirty() is called on all buffers from __set_page_buffers_dirty(), regardless of whether the buffer is beyond EOF or not, which means that when we get to ->writepage, we have buffers marked dirty beyond EOF that we need to clean. So, we need to implement our own .set_page_dirty method that doesn't dirty buffers beyond EOF. This is messy because the buffer code is not meant to be shared and it has interesting locking issues on the buffer dirty bits. So just copy and paste it and then modify it to suit what we need. Note: the solutions the other filesystems and generic block code use of marking the buffers clean in ->writepage does not work for XFS. It still leaves dirty buffers beyond EOF and invalidations still fail. Hence rather than play whack-a-mole, this patch simply prevents those buffers from being dirtied in the first place. cc: Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Signed-off-by: Dave Chinner ----------------------------------------------------------------------- Summary of changes: fs/xfs/libxfs/xfs_bmap.c | 18 +++++++------- fs/xfs/xfs_aops.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_bmap_util.c | 20 ++++++++++++++++ fs/xfs/xfs_file.c | 27 +++++++++++++++++---- 4 files changed, 114 insertions(+), 12 deletions(-) hooks/post-receive -- XFS development tree From dgc@oss.sgi.com Mon Sep 1 21:19:33 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=NO_RELAYS autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: by oss.sgi.com (Postfix, from userid 10266) id 51E217F74; Mon, 1 Sep 2014 21:19:33 -0500 (CDT) From: xfs@oss.sgi.com To: xfs@oss.sgi.com Subject: [XFS updates] XFS development tree branch, xfs-for-3.17-rc3, created. xfs-for-linus-3.17-rc1-13183-g41b9d72 X-Git-Refname: refs/heads/xfs-for-3.17-rc3 X-Git-Reftype: branch X-Git-Oldrev: 0000000000000000000000000000000000000000 X-Git-Newrev: 41b9d7263ea1e270019c5d04fa0ab15db50b9725 Message-Id: <20140902021933.51E217F74@oss.sgi.com> Date: Mon, 1 Sep 2014 21:19:32 -0500 (CDT) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "XFS development tree". The branch, xfs-for-3.17-rc3 has been created at 41b9d7263ea1e270019c5d04fa0ab15db50b9725 (commit) - Log ----------------------------------------------------------------- commit 41b9d7263ea1e270019c5d04fa0ab15db50b9725 Author: Brian Foster Date: Tue Sep 2 12:12:53 2014 +1000 xfs: trim eofblocks before collapse range xfs_collapse_file_space() currently writes back the entire file undergoing collapse range to settle things down for the extent shift algorithm. While this prevents changes to the extent list during the collapse operation, the writeback itself is not enough to prevent unnecessary collapse failures. The current shift algorithm uses the extent index to iterate the in-core extent list. If a post-eof delalloc extent persists after the writeback (e.g., a prior zero range op where the end of the range aligns with eof can separate the post-eof blocks such that they are not written back and converted), xfs_bmap_shift_extents() becomes confused over the encoded br_startblock value and fails the collapse. As with the full writeback, this is a temporary fix until the algorithm is improved to cope with a volatile extent list and avoid attempts to shift post-eof extents. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit 1669a8ca2105968f660cf7d84ba38fd18075cd99 Author: Dave Chinner Date: Tue Sep 2 12:12:53 2014 +1000 xfs: xfs_file_collapse_range is delalloc challenged If we have delalloc extents on a file before we run a collapse range opertaion, we sync the range that we are going to collapse to convert delalloc extents in that region to real extents to simplify the shift operation. However, the shift operation then assumes that the extent list is not going to change as it iterates over the extent list moving things about. Unfortunately, this isn't true because we can't hold the ILOCK over all the operations. We can prevent new IO from modifying the extent list by holding the IOLOCK, but that doesn't prevent writeback from running.... And when writeback runs, it can convert delalloc extents is the range of the file prior to the region being collapsed, and this changes the indexes of all the extents in the file. That causes the collapse range operation to Go Bad. The right fix is to rewrite the extent shift operation not to be dependent on the extent list not changing across the entire operation, but this is a fairly significant piece of work to do. Hence, as a short-term workaround for the problem, sync the entire file before starting a collapse operation to remove all delalloc ranges from the file and so avoid the problem of concurrent writeback changing the extent list. Diagnosed-and-Reported-by: Brian Foster Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit ca446d880c399bb31301e7d8eefbd7fe3c504c4e Author: Brian Foster Date: Tue Sep 2 12:12:53 2014 +1000 xfs: don't log inode unless extent shift makes extent modifications The file collapse mechanism uses xfs_bmap_shift_extents() to collapse all subsequent extents down into the specified, previously punched out, region. This function performs some validation, such as whether a sufficient hole exists in the target region of the collapse, then shifts the remaining exents downward. The exit path of the function currently logs the inode unconditionally. While we must log the inode (and abort) if an error occurs and the transaction is dirty, the initial validation paths can generate errors before the transaction has been dirtied. This creates an unnecessary filesystem shutdown scenario, as the caller will cancel a transaction that has been marked dirty. Modify xfs_bmap_shift_extents() to OR the logflags bits as modifications are made to the inode bmap. Only log the inode in the exit path if logflags has been set. This ensures we only have to cancel a dirty transaction if modifications have been made and prevents an unnecessary filesystem shutdown otherwise. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit 7d4ea3ce63a6bc532abb334c469c18481798af8c Author: Dave Chinner Date: Tue Sep 2 12:12:53 2014 +1000 xfs: use ranged writeback and invalidation for direct IO Now we are not doing silly things with dirtying buffers beyond EOF and using invalidation correctly, we can finally reduce the ranges of writeback and invalidation used by direct IO to match that of the IO being issued. Bring the writeback and invalidation ranges back to match the generic direct IO code - this will greatly reduce the perturbation of cached data when direct IO and buffered IO are mixed, but still provide the same buffered vs direct IO coherency behaviour we currently have. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit 834ffca6f7e345a79f6f2e2d131b0dfba8a4b67a Author: Dave Chinner Date: Tue Sep 2 12:12:52 2014 +1000 xfs: don't zero partial page cache pages during O_DIRECT writes Similar to direct IO reads, direct IO writes are using truncate_pagecache_range to invalidate the page cache. This is incorrect due to the sub-block zeroing in the page cache that truncate_pagecache_range() triggers. This patch fixes things by using invalidate_inode_pages2_range instead. It preserves the page cache invalidation, but won't zero any pages. cc: stable@vger.kernel.org Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit 85e584da3212140ee80fd047f9058bbee0bc00d5 Author: Chris Mason Date: Tue Sep 2 12:12:52 2014 +1000 xfs: don't zero partial page cache pages during O_DIRECT writes xfs is using truncate_pagecache_range to invalidate the page cache during DIO reads. This is different from the other filesystems who only invalidate pages during DIO writes. truncate_pagecache_range is meant to be used when we are freeing the underlying data structs from disk, so it will zero any partial ranges in the page. This means a DIO read can zero out part of the page cache page, and it is possible the page will stay in cache. buffered reads will find an up to date page with zeros instead of the data actually on disk. This patch fixes things by using invalidate_inode_pages2_range instead. It preserves the page cache invalidation, but won't zero any pages. [dchinner: catch error and warn if it fails. Comment.] cc: stable@vger.kernel.org Signed-off-by: Chris Mason Reviewed-by: Dave Chinner Reviewed-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit 22e757a49cf010703fcb9c9b4ef793248c39b0c2 Author: Dave Chinner Date: Tue Sep 2 12:12:51 2014 +1000 xfs: don't dirty buffers beyond EOF generic/263 is failing fsx at this point with a page spanning EOF that cannot be invalidated. The operations are: 1190 mapwrite 0x52c00 thru 0x5e569 (0xb96a bytes) 1191 mapread 0x5c000 thru 0x5d636 (0x1637 bytes) 1192 write 0x5b600 thru 0x771ff (0x1bc00 bytes) where 1190 extents EOF from 0x54000 to 0x5e569. When the direct IO write attempts to invalidate the cached page over this range, it fails with -EBUSY and so any attempt to do page invalidation fails. The real question is this: Why can't that page be invalidated after it has been written to disk and cleaned? Well, there's data on the first two buffers in the page (1k block size, 4k page), but the third buffer on the page (i.e. beyond EOF) is failing drop_buffers because it's bh->b_state == 0x3, which is BH_Uptodate | BH_Dirty. IOWs, there's dirty buffers beyond EOF. Say what? OK, set_buffer_dirty() is called on all buffers from __set_page_buffers_dirty(), regardless of whether the buffer is beyond EOF or not, which means that when we get to ->writepage, we have buffers marked dirty beyond EOF that we need to clean. So, we need to implement our own .set_page_dirty method that doesn't dirty buffers beyond EOF. This is messy because the buffer code is not meant to be shared and it has interesting locking issues on the buffer dirty bits. So just copy and paste it and then modify it to suit what we need. Note: the solutions the other filesystems and generic block code use of marking the buffers clean in ->writepage does not work for XFS. It still leaves dirty buffers beyond EOF and invalidations still fail. Hence rather than play whack-a-mole, this patch simply prevents those buffers from being dirtied in the first place. cc: Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Signed-off-by: Dave Chinner ----------------------------------------------------------------------- hooks/post-receive -- XFS development tree From samuel.granjeaud@inserm.fr Tue Sep 2 02:22:25 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 54C1B7F6A for ; Tue, 2 Sep 2014 02:22:25 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id F3D17AC001 for ; Tue, 2 Sep 2014 00:22:21 -0700 (PDT) X-ASG-Debug-ID: 1409642536-04bdf010976c6890001-NocioJ Received: from smtp.inserm.fr (smtp.inserm.fr [195.98.252.37]) by cuda.sgi.com with ESMTP id XUCvCIanFQfwldoe (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 02 Sep 2014 00:22:17 -0700 (PDT) X-Barracuda-Envelope-From: samuel.granjeaud@inserm.fr X-Barracuda-Apparent-Source-IP: 195.98.252.37 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.inserm.fr (SrvInserm) with ESMTP id 3F0B9168437 for ; Tue, 2 Sep 2014 09:22:15 +0200 (CEST) X-Virus-Scanned: amavisd-new at inserm.fr Received: from smtp.inserm.fr ([195.98.252.37]) by localhost (potentille.inserm.fr [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id T6RzsbPBXV4t for ; Tue, 2 Sep 2014 09:22:15 +0200 (CEST) Received: from cognac-lmde.crcm.mrs (236-ne1068.marseille.inserm.fr [195.220.68.236]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by smtp.inserm.fr (SrvInserm) with ESMTP id 0FDF1168481 for ; Tue, 2 Sep 2014 09:22:14 +0200 (CEST) Message-ID: <54057025.5090807@inserm.fr> Date: Tue, 02 Sep 2014 09:22:13 +0200 From: Samuel Granjeaud User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: xfs@oss.sgi.com Subject: Re: Run out of inodes? References: <54005108.1020203@inserm.fr> <20140829114806.GA17610@bfoster.bfoster> <5400802C.5050005@inserm.fr> <54009603.9050404@sandeen.net> <8d5fff2548d35737c6cebcb1f6382e80@inserm.fr> <20140901211932.342b4bb3@galadriel.home> X-ASG-Orig-Subj: Re: Run out of inodes? In-Reply-To: <20140901211932.342b4bb3@galadriel.home> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: smtp.inserm.fr[195.98.252.37] X-Barracuda-Start-Time: 1409642537 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9087 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Thanks Eric and Emmanuel. Here are the diagnosis of the installed samba distrib with openfiler 64 b= its # smb (auto-completion key) smbcontrol smbd smbpasswd smbprint smbstatus smbtar # which smbcontrol smbd smbpasswd smbprint smbstatus smbtar /usr/bin/smbcontrol /usr/sbin/smbd /usr/bin/smbpasswd /usr/bin/smbprint /usr/bin/smbstatus /usr/bin/smbtar # file /usr/sbin/smbd /usr/bin/smb* /usr/sbin/smbd: ELF 64-bit LSB shared object, x86-64, version 1=20 (SYSV), for GNU/Linux 2.4.0, stripped /usr/bin/smbcontrol: ELF 64-bit LSB shared object, x86-64, version 1=20 (SYSV), for GNU/Linux 2.4.0, stripped /usr/bin/smbpasswd: ELF 64-bit LSB shared object, x86-64, version 1=20 (SYSV), for GNU/Linux 2.4.0, stripped /usr/bin/smbprint: Bourne shell script text executable /usr/bin/smbstatus: ELF 64-bit LSB shared object, x86-64, version 1=20 (SYSV), for GNU/Linux 2.4.0, stripped /usr/bin/smbtar: Bourne shell script text executable [root@proteo-replica ~]# ldd /usr/sbin/smbd /usr/bin/smb* /usr/sbin/smbd: libldap-2.2.so.7 =3D> /usr/lib64/libldap-2.2.so.7 (0x00007fe4c97ff00= 0) liblber-2.2.so.7 =3D> /usr/lib64/liblber-2.2.so.7 (0x00007fe4c96f000= 0) libgssapi_krb5.so.2 =3D> /usr/kerberos/lib64/libgssapi_krb5.so.2=20 (0x00007fe4c95d8000) libkrb5.so.3 =3D> /usr/kerberos/lib64/libkrb5.so.3 (0x00007fe4c945e0= 00) libk5crypto.so.3 =3D> /usr/kerberos/lib64/libk5crypto.so.3=20 (0x00007fe4c933a000) libkrb5support.so.0 =3D> /usr/kerberos/lib64/libkrb5support.so.0=20 (0x00007fe4c9237000) libcom_err.so.3 =3D> /usr/kerberos/lib64/libcom_err.so.3=20 (0x00007fe4c9133000) libresolv.so.2 =3D> /lib64/libresolv.so.2 (0x00007fe4c9020000) libcrypt.so.1 =3D> /lib64/libcrypt.so.1 (0x00007fe4c8eed000) libpam.so.0 =3D> /lib64/libpam.so.0 (0x00007fe4c8de5000) libacl.so.1 =3D> /lib64/libacl.so.1 (0x00007fe4c8cdd000) libattr.so.1 =3D> /lib64/libattr.so.1 (0x00007fe4c8bd9000) libcap.so.1 =3D> /lib64/libcap.so.1 (0x00007fe4c8ad5000) libnsl.so.1 =3D> /lib64/libnsl.so.1 (0x00007fe4c89bf000) libdl.so.2 =3D> /lib64/libdl.so.2 (0x00007fe4c88bc000) librt.so.1 =3D> /lib64/tls/librt.so.1 (0x00007fe4c87a2000) libpopt.so.0 =3D> /usr/lib64/libpopt.so.0 (0x00007fe4c869a000) libtalloc.so.1 =3D> /usr/lib64/libtalloc.so.1 (0x00007fe4c8592000) libtdb.so.1 =3D> /usr/lib64/libtdb.so.1 (0x00007fe4c8485000) libwbclient.so.0 =3D> /usr/lib64/libwbclient.so.0 (0x00007fe4c837900= 0) libz.so.1 =3D> /usr/lib64/libz.so.1 (0x00007fe4c8264000) libc.so.6 =3D> /lib64/tls/libc.so.6 (0x00007fe4c803e000) libsasl2.so.2 =3D> /usr/lib64/libsasl2.so.2 (0x00007fe4c7f27000) libssl.so.5 =3D> /lib64/libssl.so.5 (0x00007fe4c7dde000) libcrypto.so.5 =3D> /lib64/libcrypto.so.5 (0x00007fe4c7b6e000) /lib64/ld-linux-x86-64.so.2 (0x00007fe4c9935000) libpthread.so.0 =3D> /lib64/tls/libpthread.so.0 (0x00007fe4c7a5a000) /usr/bin/smbcontrol: libcap.so.1 =3D> /lib64/libcap.so.1 (0x00007f6133e37000) libresolv.so.2 =3D> /lib64/libresolv.so.2 (0x00007f6133d24000) libnsl.so.1 =3D> /lib64/libnsl.so.1 (0x00007f6133c0e000) libdl.so.2 =3D> /lib64/libdl.so.2 (0x00007f6133b0b000) librt.so.1 =3D> /lib64/tls/librt.so.1 (0x00007f61339f1000) libldap-2.2.so.7 =3D> /usr/lib64/libldap-2.2.so.7 (0x00007f61338bb00= 0) liblber-2.2.so.7 =3D> /usr/lib64/liblber-2.2.so.7 (0x00007f61337ac00= 0) libpopt.so.0 =3D> /usr/lib64/libpopt.so.0 (0x00007f61336a4000) libtalloc.so.1 =3D> /usr/lib64/libtalloc.so.1 (0x00007f613359c000) libtdb.so.1 =3D> /usr/lib64/libtdb.so.1 (0x00007f613348f000) libc.so.6 =3D> /lib64/tls/libc.so.6 (0x00007f6133269000) /lib64/ld-linux-x86-64.so.2 (0x00007f6133f3b000) libpthread.so.0 =3D> /lib64/tls/libpthread.so.0 (0x00007f6133155000) libsasl2.so.2 =3D> /usr/lib64/libsasl2.so.2 (0x00007f613303e000) libssl.so.5 =3D> /lib64/libssl.so.5 (0x00007f6132ef5000) libcrypto.so.5 =3D> /lib64/libcrypto.so.5 (0x00007f6132c85000) libgssapi_krb5.so.2 =3D> /usr/kerberos/lib64/libgssapi_krb5.so.2=20 (0x00007f6132b6d000) libkrb5.so.3 =3D> /usr/kerberos/lib64/libkrb5.so.3 (0x00007f61329f30= 00) libcom_err.so.3 =3D> /usr/kerberos/lib64/libcom_err.so.3=20 (0x00007f61328ef000) libk5crypto.so.3 =3D> /usr/kerberos/lib64/libk5crypto.so.3=20 (0x00007f61327cb000) libz.so.1 =3D> /usr/lib64/libz.so.1 (0x00007f61326b6000) libkrb5support.so.0 =3D> /usr/kerberos/lib64/libkrb5support.so.0=20 (0x00007f61325b3000) /usr/bin/smbpasswd: libldap-2.2.so.7 =3D> /usr/lib64/libldap-2.2.so.7 (0x00007f9eaea1f00= 0) liblber-2.2.so.7 =3D> /usr/lib64/liblber-2.2.so.7 (0x00007f9eae91000= 0) libcap.so.1 =3D> /lib64/libcap.so.1 (0x00007f9eae80c000) libresolv.so.2 =3D> /lib64/libresolv.so.2 (0x00007f9eae6f9000) libnsl.so.1 =3D> /lib64/libnsl.so.1 (0x00007f9eae5e3000) libdl.so.2 =3D> /lib64/libdl.so.2 (0x00007f9eae4e0000) librt.so.1 =3D> /lib64/tls/librt.so.1 (0x00007f9eae3c6000) libpopt.so.0 =3D> /usr/lib64/libpopt.so.0 (0x00007f9eae2be000) libgssapi_krb5.so.2 =3D> /usr/kerberos/lib64/libgssapi_krb5.so.2=20 (0x00007f9eae1a6000) libkrb5.so.3 =3D> /usr/kerberos/lib64/libkrb5.so.3 (0x00007f9eae02c0= 00) libk5crypto.so.3 =3D> /usr/kerberos/lib64/libk5crypto.so.3=20 (0x00007f9eadf08000) libkrb5support.so.0 =3D> /usr/kerberos/lib64/libkrb5support.so.0=20 (0x00007f9eade05000) libcom_err.so.3 =3D> /usr/kerberos/lib64/libcom_err.so.3=20 (0x00007f9eadd01000) libtalloc.so.1 =3D> /usr/lib64/libtalloc.so.1 (0x00007f9eadbf9000) libtdb.so.1 =3D> /usr/lib64/libtdb.so.1 (0x00007f9eadaec000) libwbclient.so.0 =3D> /usr/lib64/libwbclient.so.0 (0x00007f9ead9e000= 0) libz.so.1 =3D> /usr/lib64/libz.so.1 (0x00007f9ead8cb000) libc.so.6 =3D> /lib64/tls/libc.so.6 (0x00007f9ead6a5000) libsasl2.so.2 =3D> /usr/lib64/libsasl2.so.2 (0x00007f9ead58e000) libssl.so.5 =3D> /lib64/libssl.so.5 (0x00007f9ead445000) libcrypto.so.5 =3D> /lib64/libcrypto.so.5 (0x00007f9ead1d5000) /lib64/ld-linux-x86-64.so.2 (0x00007f9eaeb55000) libpthread.so.0 =3D> /lib64/tls/libpthread.so.0 (0x00007f9ead0c1000) /usr/bin/smbprint: not a dynamic executable /usr/bin/smbstatus: libcap.so.1 =3D> /lib64/libcap.so.1 (0x00007ffc9b5d5000) libresolv.so.2 =3D> /lib64/libresolv.so.2 (0x00007ffc9b4c2000) libnsl.so.1 =3D> /lib64/libnsl.so.1 (0x00007ffc9b3ac000) libdl.so.2 =3D> /lib64/libdl.so.2 (0x00007ffc9b2a9000) librt.so.1 =3D> /lib64/tls/librt.so.1 (0x00007ffc9b18f000) libldap-2.2.so.7 =3D> /usr/lib64/libldap-2.2.so.7 (0x00007ffc9b05900= 0) liblber-2.2.so.7 =3D> /usr/lib64/liblber-2.2.so.7 (0x00007ffc9af4a00= 0) libpopt.so.0 =3D> /usr/lib64/libpopt.so.0 (0x00007ffc9ae42000) libtalloc.so.1 =3D> /usr/lib64/libtalloc.so.1 (0x00007ffc9ad3a000) libtdb.so.1 =3D> /usr/lib64/libtdb.so.1 (0x00007ffc9ac2d000) libc.so.6 =3D> /lib64/tls/libc.so.6 (0x00007ffc9aa07000) /lib64/ld-linux-x86-64.so.2 (0x00007ffc9b6d9000) libpthread.so.0 =3D> /lib64/tls/libpthread.so.0 (0x00007ffc9a8f3000) libsasl2.so.2 =3D> /usr/lib64/libsasl2.so.2 (0x00007ffc9a7dc000) libssl.so.5 =3D> /lib64/libssl.so.5 (0x00007ffc9a693000) libcrypto.so.5 =3D> /lib64/libcrypto.so.5 (0x00007ffc9a423000) libgssapi_krb5.so.2 =3D> /usr/kerberos/lib64/libgssapi_krb5.so.2=20 (0x00007ffc9a30b000) libkrb5.so.3 =3D> /usr/kerberos/lib64/libkrb5.so.3 (0x00007ffc9a1910= 00) libcom_err.so.3 =3D> /usr/kerberos/lib64/libcom_err.so.3=20 (0x00007ffc9a08d000) libk5crypto.so.3 =3D> /usr/kerberos/lib64/libk5crypto.so.3=20 (0x00007ffc99f69000) libz.so.1 =3D> /usr/lib64/libz.so.1 (0x00007ffc99e54000) libkrb5support.so.0 =3D> /usr/kerberos/lib64/libkrb5support.so.0=20 (0x00007ffc99d51000) /usr/bin/smbtar: not a dynamic executable [root@proteo-replica ~]# ldd /usr/sbin/smbd /usr/bin/smb* | grep -r "lib6= 4" libldap-2.2.so.7 =3D> /usr/lib64/libldap-2.2.so.7 (0x00007fe32220500= 0) liblber-2.2.so.7 =3D> /usr/lib64/liblber-2.2.so.7 (0x00007fe3220f600= 0) libgssapi_krb5.so.2 =3D> /usr/kerberos/lib64/libgssapi_krb5.so.2=20 (0x00007fe321fde000) libkrb5.so.3 =3D> /usr/kerberos/lib64/libkrb5.so.3 (0x00007fe321e640= 00) libk5crypto.so.3 =3D> /usr/kerberos/lib64/libk5crypto.so.3=20 (0x00007fe321d40000) libkrb5support.so.0 =3D> /usr/kerberos/lib64/libkrb5support.so.0=20 (0x00007fe321c3d000) libcom_err.so.3 =3D> /usr/kerberos/lib64/libcom_err.so.3=20 (0x00007fe321b39000) libresolv.so.2 =3D> /lib64/libresolv.so.2 (0x00007fe321a26000) libcrypt.so.1 =3D> /lib64/libcrypt.so.1 (0x00007fe3218f3000) libpam.so.0 =3D> /lib64/libpam.so.0 (0x00007fe3217eb000) libacl.so.1 =3D> /lib64/libacl.so.1 (0x00007fe3216e3000) libattr.so.1 =3D> /lib64/libattr.so.1 (0x00007fe3215df000) libcap.so.1 =3D> /lib64/libcap.so.1 (0x00007fe3214db000) libnsl.so.1 =3D> /lib64/libnsl.so.1 (0x00007fe3213c5000) libdl.so.2 =3D> /lib64/libdl.so.2 (0x00007fe3212c2000) librt.so.1 =3D> /lib64/tls/librt.so.1 (0x00007fe3211a8000) libpopt.so.0 =3D> /usr/lib64/libpopt.so.0 (0x00007fe3210a0000) libtalloc.so.1 =3D> /usr/lib64/libtalloc.so.1 (0x00007fe320f98000) libtdb.so.1 =3D> /usr/lib64/libtdb.so.1 (0x00007fe320e8b000) libwbclient.so.0 =3D> /usr/lib64/libwbclient.so.0 (0x00007fe320d7f00= 0) libz.so.1 =3D> /usr/lib64/libz.so.1 (0x00007fe320c6a000) libc.so.6 =3D> /lib64/tls/libc.so.6 (0x00007fe320a44000) libsasl2.so.2 =3D> /usr/lib64/libsasl2.so.2 (0x00007fe32092d000) libssl.so.5 =3D> /lib64/libssl.so.5 (0x00007fe3207e4000) libcrypto.so.5 =3D> /lib64/libcrypto.so.5 (0x00007fe320574000) /lib64/ld-linux-x86-64.so.2 (0x00007fe32233b000) libpthread.so.0 =3D> /lib64/tls/libpthread.so.0 (0x00007fe320460000) libcap.so.1 =3D> /lib64/libcap.so.1 (0x00007fad1f282000) libresolv.so.2 =3D> /lib64/libresolv.so.2 (0x00007fad1f16f000) libnsl.so.1 =3D> /lib64/libnsl.so.1 (0x00007fad1f059000) libdl.so.2 =3D> /lib64/libdl.so.2 (0x00007fad1ef56000) librt.so.1 =3D> /lib64/tls/librt.so.1 (0x00007fad1ee3c000) libldap-2.2.so.7 =3D> /usr/lib64/libldap-2.2.so.7 (0x00007fad1ed0600= 0) liblber-2.2.so.7 =3D> /usr/lib64/liblber-2.2.so.7 (0x00007fad1ebf700= 0) libpopt.so.0 =3D> /usr/lib64/libpopt.so.0 (0x00007fad1eaef000) libtalloc.so.1 =3D> /usr/lib64/libtalloc.so.1 (0x00007fad1e9e7000) libtdb.so.1 =3D> /usr/lib64/libtdb.so.1 (0x00007fad1e8da000) libc.so.6 =3D> /lib64/tls/libc.so.6 (0x00007fad1e6b4000) /lib64/ld-linux-x86-64.so.2 (0x00007fad1f386000) libpthread.so.0 =3D> /lib64/tls/libpthread.so.0 (0x00007fad1e5a0000) libsasl2.so.2 =3D> /usr/lib64/libsasl2.so.2 (0x00007fad1e489000) libssl.so.5 =3D> /lib64/libssl.so.5 (0x00007fad1e340000) libcrypto.so.5 =3D> /lib64/libcrypto.so.5 (0x00007fad1e0d0000) libgssapi_krb5.so.2 =3D> /usr/kerberos/lib64/libgssapi_krb5.so.2=20 (0x00007fad1dfb8000) libkrb5.so.3 =3D> /usr/kerberos/lib64/libkrb5.so.3 (0x00007fad1de3e0= 00) libcom_err.so.3 =3D> /usr/kerberos/lib64/libcom_err.so.3=20 (0x00007fad1dd3a000) libk5crypto.so.3 =3D> /usr/kerberos/lib64/libk5crypto.so.3=20 (0x00007fad1dc16000) libz.so.1 =3D> /usr/lib64/libz.so.1 (0x00007fad1db01000) libkrb5support.so.0 =3D> /usr/kerberos/lib64/libkrb5support.so.0=20 (0x00007fad1d9fe000) libldap-2.2.so.7 =3D> /usr/lib64/libldap-2.2.so.7 (0x00007f4551e9200= 0) liblber-2.2.so.7 =3D> /usr/lib64/liblber-2.2.so.7 (0x00007f4551d8300= 0) libcap.so.1 =3D> /lib64/libcap.so.1 (0x00007f4551c7f000) libresolv.so.2 =3D> /lib64/libresolv.so.2 (0x00007f4551b6c000) libnsl.so.1 =3D> /lib64/libnsl.so.1 (0x00007f4551a56000) libdl.so.2 =3D> /lib64/libdl.so.2 (0x00007f4551953000) librt.so.1 =3D> /lib64/tls/librt.so.1 (0x00007f4551839000) libpopt.so.0 =3D> /usr/lib64/libpopt.so.0 (0x00007f4551731000) libgssapi_krb5.so.2 =3D> /usr/kerberos/lib64/libgssapi_krb5.so.2=20 (0x00007f4551619000) libkrb5.so.3 =3D> /usr/kerberos/lib64/libkrb5.so.3 (0x00007f455149f0= 00) libk5crypto.so.3 =3D> /usr/kerberos/lib64/libk5crypto.so.3=20 (0x00007f455137b000) libkrb5support.so.0 =3D> /usr/kerberos/lib64/libkrb5support.so.0=20 (0x00007f4551278000) libcom_err.so.3 =3D> /usr/kerberos/lib64/libcom_err.so.3=20 (0x00007f4551174000) libtalloc.so.1 =3D> /usr/lib64/libtalloc.so.1 (0x00007f455106c000) libtdb.so.1 =3D> /usr/lib64/libtdb.so.1 (0x00007f4550f5f000) libwbclient.so.0 =3D> /usr/lib64/libwbclient.so.0 (0x00007f4550e5300= 0) libz.so.1 =3D> /usr/lib64/libz.so.1 (0x00007f4550d3e000) libc.so.6 =3D> /lib64/tls/libc.so.6 (0x00007f4550b18000) libsasl2.so.2 =3D> /usr/lib64/libsasl2.so.2 (0x00007f4550a01000) libssl.so.5 =3D> /lib64/libssl.so.5 (0x00007f45508b8000) libcrypto.so.5 =3D> /lib64/libcrypto.so.5 (0x00007f4550648000) /lib64/ld-linux-x86-64.so.2 (0x00007f4551fc8000) libpthread.so.0 =3D> /lib64/tls/libpthread.so.0 (0x00007f4550534000) libcap.so.1 =3D> /lib64/libcap.so.1 (0x00007f03c54c6000) libresolv.so.2 =3D> /lib64/libresolv.so.2 (0x00007f03c53b3000) libnsl.so.1 =3D> /lib64/libnsl.so.1 (0x00007f03c529d000) libdl.so.2 =3D> /lib64/libdl.so.2 (0x00007f03c519a000) librt.so.1 =3D> /lib64/tls/librt.so.1 (0x00007f03c5080000) libldap-2.2.so.7 =3D> /usr/lib64/libldap-2.2.so.7 (0x00007f03c4f4a00= 0) liblber-2.2.so.7 =3D> /usr/lib64/liblber-2.2.so.7 (0x00007f03c4e3b00= 0) libpopt.so.0 =3D> /usr/lib64/libpopt.so.0 (0x00007f03c4d33000) libtalloc.so.1 =3D> /usr/lib64/libtalloc.so.1 (0x00007f03c4c2b000) libtdb.so.1 =3D> /usr/lib64/libtdb.so.1 (0x00007f03c4b1e000) libc.so.6 =3D> /lib64/tls/libc.so.6 (0x00007f03c48f8000) /lib64/ld-linux-x86-64.so.2 (0x00007f03c55ca000) libpthread.so.0 =3D> /lib64/tls/libpthread.so.0 (0x00007f03c47e4000) libsasl2.so.2 =3D> /usr/lib64/libsasl2.so.2 (0x00007f03c46cd000) libssl.so.5 =3D> /lib64/libssl.so.5 (0x00007f03c4584000) libcrypto.so.5 =3D> /lib64/libcrypto.so.5 (0x00007f03c4314000) libgssapi_krb5.so.2 =3D> /usr/kerberos/lib64/libgssapi_krb5.so.2=20 (0x00007f03c41fc000) libkrb5.so.3 =3D> /usr/kerberos/lib64/libkrb5.so.3 (0x00007f03c40820= 00) libcom_err.so.3 =3D> /usr/kerberos/lib64/libcom_err.so.3=20 (0x00007f03c3f7e000) libk5crypto.so.3 =3D> /usr/kerberos/lib64/libk5crypto.so.3=20 (0x00007f03c3e5a000) libz.so.1 =3D> /usr/lib64/libz.so.1 (0x00007f03c3d45000) libkrb5support.so.0 =3D> /usr/kerberos/lib64/libkrb5support.so.0=20 (0x00007f03c3c42000) # ldd /usr/sbin/smbd /usr/bin/smb* | grep -v "lib64" /usr/sbin/smbd: /usr/bin/smbcontrol: /usr/bin/smbpasswd: /usr/bin/smbprint: not a dynamic executable /usr/bin/smbstatus: /usr/bin/smbtar: not a dynamic executable If there is no other binary in relation to Samba I didn't think about, I=20 guess the Samba package is 64 bits. This should prevent me from any=20 surprise. Best. Eric Sandeen wrote, On 31/08/14 04:46: > On 8/30/14, 2:33 PM, Samuel GRANJEAUD IR/INSERM wrote: >> Enabling the inode64 option has solved the problem. >> >> Final question: could some issues appear with SAMBA? > > ah, what sort of issues? > > Any application which uses i.e. a 32-bit stat() interface will return=20 > -EOVERFLOW on a 64-bit inode. > > http://sandeen.net/wordpress/computers/the-world-wants-32-bit-inodes/ > http://blog.fmeh.org/2013/05/11/does-the-world-need-32-bit-inodes/ > > -Eric > Emmanuel Florac wrote, On 01/09/14 21:19: > Le Sat, 30 Aug 2014 21:33:46 +0200 vous =C3=A9criviez: > >> Final question: could some issues appear with SAMBA? >> >> # smbstatus -V >> Version 3.4.5 > Is your whole distribution 64 bits, or only the kernel? However, I've > never had any problem with samba, but some with NFS. > From alex@zadarastorage.com Tue Sep 2 04:51:45 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: * X-Spam-Status: No, score=1.9 required=5.0 tests=STOX_REPLY_TYPE autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 3F5F57F51 for ; Tue, 2 Sep 2014 04:51:45 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1F4AB8F8050 for ; Tue, 2 Sep 2014 02:51:42 -0700 (PDT) X-ASG-Debug-ID: 1409651495-04cb6c54fe72e260001-NocioJ Received: from mail-wi0-f172.google.com (mail-wi0-f172.google.com [209.85.212.172]) by cuda.sgi.com with ESMTP id ySVJtjXfH6zaM0GT (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Tue, 02 Sep 2014 02:51:35 -0700 (PDT) X-Barracuda-Envelope-From: alex@zadarastorage.com X-Barracuda-Apparent-Source-IP: 209.85.212.172 Received: by mail-wi0-f172.google.com with SMTP id n3so13952010wiv.17 for ; Tue, 02 Sep 2014 02:51:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:message-id:from:to:cc:references:in-reply-to :subject:date:mime-version:content-type:content-transfer-encoding :importance; bh=C1w74Ahke2H7oGiiLlR30fMF9vExd0zun7s3UMnavKg=; b=d0lsmjouSAa2KkZh7Iw/dIAsiNjz8PLRUqCMtk5DUwGJ7hE1NQpuRiGXP3K6cfOzp6 wpk3J7gsS2YmMnflJV1iwEDgBfPBA501bD168TYOrZx8/VAjEjHTYv8lJIxHursbIBAx bgjhPOlC1IU/oLBpJjBM5NMvwJUXl6aoaDOi4pkXgy0iQcy9V9YZJsVkV3Lz1eme3IRx eoE7SdLOsnBSvbb1aThrF6+rEwvMm+NjigS14rjTpxLhV2XRqbRVsvOsB52c7/i7PpyA /iYTzSixw5Dz2PHHFj731BN4jngUAfDyH2pzOl999uOl+xYTQa5Mi/MIl2I5bt8M2e2i ni2Q== X-Gm-Message-State: ALoCoQmthf+ygSd1YyXyhsKZBkZBkMq16PufKRfPrxi/DiZL+opsNiZl8Mhpp1wWmBM8mMMfZOSf X-Received: by 10.194.185.230 with SMTP id ff6mr1564230wjc.120.1409651494506; Tue, 02 Sep 2014 02:51:34 -0700 (PDT) Received: from alyakaslap (bzq-169-168-31-234.red.bezeqint.net. [31.168.169.234]) by mx.google.com with ESMTPSA id lh11sm32626225wic.17.2014.09.02.02.51.33 for (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 02 Sep 2014 02:51:33 -0700 (PDT) Message-ID: <3476A2CBDE694DC6BD06DBDD15165151@alyakaslap> From: "Alex Lyakas" To: "Brian Foster" , "Dave Chinner" Cc: References: <1408648692-15957-1-git-send-email-bfoster@redhat.com> <20140825142025.GA10135@bfoster.bfoster> <20140831210507.GA11913@bfoster.bfoster> In-Reply-To: <20140831210507.GA11913@bfoster.bfoster> Subject: Re: [PATCH] xfs: fix double free of trans in log recovery on I/O error Date: Tue, 2 Sep 2014 12:51:35 +0300 X-ASG-Orig-Subj: Re: [PATCH] xfs: fix double free of trans in log recovery on I/O error MIME-Version: 1.0 Content-Type: text/plain; format=flowed; charset="iso-8859-1"; reply-type=original Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal Importance: Normal X-Mailer: Microsoft Windows Live Mail 15.4.3555.308 X-MimeOLE: Produced By Microsoft MimeOLE V15.4.3555.308 X-Barracuda-Connect: mail-wi0-f172.google.com[209.85.212.172] X-Barracuda-Start-Time: 1409651495 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, MARKETING_SUBJECT, STOX_REPLY_TYPE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9090 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 STOX_REPLY_TYPE STOX_REPLY_TYPE 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Hi Brian, Dave, I tested this patch on 3.8.13 kernel with the scenario I described in http://oss.sgi.com/pipermail/xfs/2014-August/037637.html, but I still see the issue. I placed the metadump at https://drive.google.com/file/d/0ByBy89zr3kJNV2UxMERNTkE4aHM/edit?usp=sharing During log recovery, 3 IO errors are encountered: [ 340.381199] XFS (dm-0): Mounting Filesystem [ 340.439897] XFS (dm-0): Sleep 10s before xlog_do_recover [ 350.440143] XFS (dm-0): Starting recovery (logdev: internal) [ 351.584647] XFS (dm-0): metadata I/O error: block 0x1 ("xlog_recover_iodone") error 28 numblks 1 [ 351.584660] XFS (dm-0): metadata I/O error: block 0x40 ("xlog_recover_iodone") error 28 numblks 16 [ 351.584665] XFS (dm-0): xfs_do_force_shutdown(0x1) called from line 377 of file /mnt/work/alex/zadara-btrfs/fs/xfs/xfs_log_recover.c. Return address = 0xffffffffa0372728 [ 351.584969] XFS (dm-0): I/O Error Detected. Shutting down filesystem [ 351.584970] XFS (dm-0): Please umount the filesystem and rectify the problem(s) [ 351.585047] XFS (dm-0): metadata I/O error: block 0x1e00040 ("xlog_recover_iodone") error 28 numblks 16 [ 351.585050] XFS (dm-0): xfs_do_force_shutdown(0x1) called from line 377 of file /mnt/work/alex/zadara-btrfs/fs/xfs/xfs_log_recover.c. Return address = 0xffffffffa0372728 [ 351.585068] XFS (dm-0): log mount/recovery failed: error 28 [ 351.585332] XFS (dm-0): log mount failed Two IO error callbacks are handled before XFS is unmounted, but the last one crashes with stack[1]. Do I need some or all of the 9 patches that Dave posted? (They do not apply to my kernel, so I need to apply them by hand). Thanks, Alex. [1] [ 351.592349] general protection fault: 0000 [#1] SMP [ 351.593440] Modules linked in: xfs(O) libcrc32c dm_linear_custom(O) nfsv3 deflate zlib_deflate ctr twofish_generic twofish_x86_64_3way glue_helper lrw xts gf128mul twofish_x86_64 twofish_common camellia_generic serpent_generic blowfish_generic blowfish_x86_64 blowfish_common cast5_generic cast_common des_generic xcbc rmd160 sha512_generic crypto_null af_key xfrm_algo kvm ppdev vfat fat dm_round_robin microcode nfsd nfs_acl parport_pc dm_iostat(O) dm_multipath(O) psmouse serio_raw mac_hid i2c_piix4 lp parport nfsv4 auth_rpcgss nfs fscache lockd sunrpc floppy [ 351.596118] CPU 3 [ 351.596118] Pid: 133, comm: kworker/3:1H Tainted: G W O 3.8.13-557-generic #1382000791 Bochs Bochs [ 351.596118] RIP: 0010:[] [] strnlen+0xb/0x30 [ 351.596118] RSP: 0018:ffff880035405b08 EFLAGS: 00010086 [ 351.596118] RAX: 0000000000000000 RBX: ffffffff81e6a4e7 RCX: 0000000000000000 [ 351.596118] RDX: e4e8390a265c0000 RSI: ffffffffffffffff RDI: e4e8390a265c0000 [ 351.596118] RBP: ffff880035405b08 R08: 000000000000ffff R09: 000000000000ffff [ 351.596118] R10: 0000000000000000 R11: 0000000000000331 R12: e4e8390a265c0000 [ 351.596118] R13: ffffffff81e6a8c0 R14: 0000000000000000 R15: 000000000000ffff [ 351.596118] FS: 0000000000000000(0000) GS:ffff88007fd80000(0000) knlGS:0000000000000000 [ 351.596118] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 351.596118] CR2: 00007fff7bfe1c38 CR3: 0000000035a59000 CR4: 00000000000006e0 [ 351.596118] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 351.596118] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 351.596118] Process kworker/3:1H (pid: 133, threadinfo ffff880035404000, task ffff880035ae5c00) [ 351.596118] Stack: [ 351.596118] ffff880035405b48 ffffffff8133dd5e ffff880035405b28 ffffffff81e6a4e7 [ 351.596118] ffffffffa03b2bc4 ffff880035405c80 ffffffffa03b2bc4 ffffffff81e6a8c0 [ 351.596118] ffff880035405bc8 ffffffff8133ef59 ffff880035405bc8 ffffffff81059aa7 [ 351.596118] Call Trace: [ 351.596118] [] string.isra.4+0x3e/0xd0 [ 351.596118] [] vsnprintf+0x219/0x640 [ 351.596118] [] ? msg_print_text+0xb7/0x1b0 [ 351.596118] [] vscnprintf+0x11/0x30 [ 351.596118] [] vprintk_emit+0xc1/0x490 [ 351.596118] [] ? vprintk_emit+0x170/0x490 [ 351.596118] [] printk+0x61/0x63 [ 351.596118] [] __xfs_printk+0x31/0x50 [xfs] [ 351.596118] [] xfs_notice+0x53/0x60 [xfs] [ 351.596118] [] xfs_do_force_shutdown+0xf5/0x180 [xfs] [ 351.596118] [] ? xlog_recover_iodone+0x48/0x70 [xfs] [ 351.596118] [] xlog_recover_iodone+0x48/0x70 [xfs] [ 351.596118] [] xfs_buf_iodone_work+0x4d/0xb0 [xfs] [ 351.596118] [] process_one_work+0x141/0x4a0 [ 351.596118] [] worker_thread+0x168/0x410 [ 351.596118] [] ? manage_workers+0x120/0x120 [ 351.596118] [] kthread+0xc0/0xd0 [ 351.596118] [] ? flush_kthread_worker+0xb0/0xb0 [ 351.596118] [] ret_from_fork+0x7c/0xb0 [ 351.596118] [] ? flush_kthread_worker+0xb0/0xb0 [ 351.596118] Code: 31 c0 80 3f 00 55 48 89 e5 74 11 48 89 f8 66 90 48 83 c0 01 80 38 00 75 f7 48 29 f8 5d c3 66 90 55 31 c0 48 85 f6 48 89 e5 74 23 <80> 3f 00 74 1e 48 89 f8 eb 0c 0f 1f 00 48 83 ee 01 80 38 00 74 [ 351.596118] RIP [] strnlen+0xb/0x30 [ 351.596118] RSP [ 351.596118] ---[ end trace cb6b9820566f6848 ]--- -----Original Message----- From: Brian Foster Sent: 01 September, 2014 12:05 AM To: Alex Lyakas Cc: xfs@oss.sgi.com ; Dave Chinner Subject: Re: [PATCH] xfs: fix double free of trans in log recovery on I/O error On Sun, Aug 31, 2014 at 11:50:52AM +0300, Alex Lyakas wrote: > Hi Brian, Dave, > I tested this patch on kernel 3.16, top commit: > > commit 19583ca584d6f574384e17fe7613dfaeadcdc4a6 > Author: Linus Torvalds > Date: Sun Aug 3 15:25:02 2014 -0700 > > Linux 3.16 > > and, yes, it appears to fix the issue. > Thanks. That settles that then, I think. We're reproducing different problems on the 3.8 stable kernel vs. a recent kernel using the same test case. > Trouble is that our production kernel is 3.8.13, and we cannot upgrade to > mainline kernel easily. Question is whether we can expect some patch > suitable for our kernel, or, since our kernel is EOL and not a long-term > one, we cannot? > Dave wrote a patch specifically to resolve this problem on older kernels: http://oss.sgi.com/archives/xfs/2014-08/msg00204.html Brian > Thanks for your help, > Alex. > > > -----Original Message----- From: Brian Foster > Sent: 25 August, 2014 5:20 PM > To: Alex Lyakas > Cc: xfs@oss.sgi.com ; Dave Chinner > Subject: Re: [PATCH] xfs: fix double free of trans in log recovery on I/O > error > > On Sun, Aug 24, 2014 at 12:20:20PM +0300, Alex Lyakas wrote: > >Hi Brian, > > > >On Thu, Aug 21, 2014 at 10:18 PM, Brian Foster > >wrote: > >> XFS log recovery builds up an xlog_recover object as it passes through > >> the log operations on the physical log. These structures are managed > >> via > >> a hash table and are allocated when a new transaction is encountered > >> and > >> freed once a commit operation for the transaction is encountered. > >> > >> This state machine for active transactions is implemented by a > >> combination of xlog_do_recovery_pass(), which walks through the log > >> buffers and xlog_recover_process_data() which processes log operations > >> within each buffer. The latter function decides whether to allocate a > >> new xlog_recover, add to it or commit and ultimately free it. If an > >> error occurs at any point during the lifecycle of a particular > >> xlog_recover, xlog_recover_process_data() frees the object and returns > >> an error. > >> > >> xlog_recover_commit_trans() handles the final processing of the > >> transaction. It submits whatever I/O is required for the transaction > >> and > >> frees xlog_recover object along with the transaction items it tracks. > >> If > >> an error occurs at the final stages of the commit operation, such as > >> I/O > >> failure, both xlog_recover_commit_trans() and > >> xlog_recover_process_data() attempt to free the trans object. > >> > >> Modify xlog_recover_commit_trans() to only free the trans object on > >> successful completion of the trans, including any I/O errors that might > >> occur when recovering the log. > >> > >> Signed-off-by: Brian Foster > >> --- > >> > >> Hi all, > >> > >> I found that the recent buffer I/O rework fixes didn't address the > >> crash > >> reproduced by the dm-flakey/log recovery test case I posted recently. I > >> tracked the crash down to this, which allows the test to pass. This > >> addresses the crash I saw when running the reproducer manually with the > >> metadump that Alex posted as well. > >> > >> FWIW, I also went back and tested the xfs_buf_iowait() experiment in > >> both scenarios (Alex's metadump and xfstests test) and they all > >> reproduce the same crash for me. I think that either I'm still not > >> reproducing the original problem, something else might have > >> contaminated > >> the original xfs_buf_iowait() test to give a false positive, or > >> something else entirely is going on. > >> > >> Alex, > >> > >> If you have a chance, I think it might be interesting to see whether > >> you > >> reproduce any problems with this patch. It looks like this is a > >> regression introduced by: > >> > >> 2a84108f xfs: free the list of recovery items on error > >> > >> ... but I have no idea if that's in whatever kernel you're running. > >I am running kernel 3.8.13 with some changes (published at > >https://github.com/zadarastorage/zadara-xfs-pushback), but this > >problem also happens on pristine 3.8.13 from > >git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git, > >branch linux-stable-3.8.y. > > > >I do not have commit 2a84108f in this kernel. It was introduced in 3.14. > >I applied your patch to 3.8.13, but it doesn't fix the issue. Same > >problem happens when testing scenario that I described in > >http://oss.sgi.com/pipermail/xfs/2014-August/037637.html. > > > > Ok, thanks. Yeah, I don't see the double free regression in the 3.8.13 > stable branch. I went back to that kernel to try and confirm some > things. I do reproduce the problem with your metadump as well as the > test case I put together. I tested Dave's buf hold across sync I/O patch > and that does indeed prevent the problem. > > For whatever reason, neither the test case nor your metadump reproduce > the same problem on latest kernels. Instead, they reproduce this double > free regression. I suspect this is what you ran into when you reproduced > on a more recent kernel. If you'd like, feel free to try and verify that > by running your reproducer again on a recent kernel with this patch and > see if you can still reproduce a crash as with the 3.8.13 kernel. > > Brian > > >Thanks, > >Alex. > > > >> > >> Brian > >> > >> fs/xfs/xfs_log_recover.c | 11 ++++++++--- > >> 1 file changed, 8 insertions(+), 3 deletions(-) > >> > >> diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c > >> index 176c4b3..daca9a6 100644 > >> --- a/fs/xfs/xfs_log_recover.c > >> +++ b/fs/xfs/xfs_log_recover.c > >> @@ -3528,10 +3528,15 @@ out: > >> if (!list_empty(&done_list)) > >> list_splice_init(&done_list, &trans->r_itemq); > >> > >> - xlog_recover_free_trans(trans); > >> - > >> error2 = xfs_buf_delwri_submit(&buffer_list); > >> - return error ? error : error2; > >> + > >> + if (!error) > >> + error = error2; > >> + /* caller frees trans on error */ > >> + if (!error) > >> + xlog_recover_free_trans(trans); > >> + > >> + return error; > >> } > >> > >> STATIC int > >> -- > >> 1.8.3.1 > >> > From bfoster@redhat.com Tue Sep 2 07:36:47 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 696D57F6F for ; Tue, 2 Sep 2014 07:36:47 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 44A1B8F8050 for ; Tue, 2 Sep 2014 05:36:47 -0700 (PDT) X-ASG-Debug-ID: 1409661405-04cbb054859c15c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id fi9qAcBfjARZCd3m (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 02 Sep 2014 05:36:46 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s82Cah5K023873 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 2 Sep 2014 08:36:44 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s82CahfC003564; Tue, 2 Sep 2014 08:36:43 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 2B4FB12577F; Tue, 2 Sep 2014 08:36:42 -0400 (EDT) Date: Tue, 2 Sep 2014 08:36:42 -0400 From: Brian Foster To: Alex Lyakas Cc: Dave Chinner , xfs@oss.sgi.com Subject: Re: [PATCH] xfs: fix double free of trans in log recovery on I/O error Message-ID: <20140902123641.GA24452@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs: fix double free of trans in log recovery on I/O error References: <1408648692-15957-1-git-send-email-bfoster@redhat.com> <20140825142025.GA10135@bfoster.bfoster> <20140831210507.GA11913@bfoster.bfoster> <3476A2CBDE694DC6BD06DBDD15165151@alyakaslap> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <3476A2CBDE694DC6BD06DBDD15165151@alyakaslap> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1409661406 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Sep 02, 2014 at 12:51:35PM +0300, Alex Lyakas wrote: > Hi Brian, Dave, > I tested this patch on 3.8.13 kernel with the scenario I described in > http://oss.sgi.com/pipermail/xfs/2014-August/037637.html, but I still see > the issue. > I placed the metadump at > https://drive.google.com/file/d/0ByBy89zr3kJNV2UxMERNTkE4aHM/edit?usp=sharing > > During log recovery, 3 IO errors are encountered: > [ 340.381199] XFS (dm-0): Mounting Filesystem > [ 340.439897] XFS (dm-0): Sleep 10s before xlog_do_recover > [ 350.440143] XFS (dm-0): Starting recovery (logdev: internal) > [ 351.584647] XFS (dm-0): metadata I/O error: block 0x1 > ("xlog_recover_iodone") error 28 numblks 1 > [ 351.584660] XFS (dm-0): metadata I/O error: block 0x40 > ("xlog_recover_iodone") error 28 numblks 16 > [ 351.584665] XFS (dm-0): xfs_do_force_shutdown(0x1) called from line 377 > of file /mnt/work/alex/zadara-btrfs/fs/xfs/xfs_log_recover.c. Return > address = 0xffffffffa0372728 > [ 351.584969] XFS (dm-0): I/O Error Detected. Shutting down filesystem > [ 351.584970] XFS (dm-0): Please umount the filesystem and rectify the > problem(s) > [ 351.585047] XFS (dm-0): metadata I/O error: block 0x1e00040 > ("xlog_recover_iodone") error 28 numblks 16 > [ 351.585050] XFS (dm-0): xfs_do_force_shutdown(0x1) called from line 377 > of file /mnt/work/alex/zadara-btrfs/fs/xfs/xfs_log_recover.c. Return > address = 0xffffffffa0372728 > [ 351.585068] XFS (dm-0): log mount/recovery failed: error 28 > [ 351.585332] XFS (dm-0): log mount failed > > Two IO error callbacks are handled before XFS is unmounted, but the last one > crashes with stack[1]. > I don't reproduce this with the metadump posted above. I suppose hardware/timing could make a difference, however. > Do I need some or all of the 9 patches that Dave posted? (They do not apply > to my kernel, so I need to apply them by hand). > Only the first patch is required for the stable tree. Did you have to manually apply that one? I had to, so it might be a good idea to post it as applied to your tree just to verify. That aside, I suppose the problem could be that we still don't wait for the I/O completion mechanism fully on the mount/log recovery side. E.g., we have a buffer reference, but the caller can still proceed to free the mp from which the error message derives the fs name. Brian > Thanks, > Alex. > > > [1] > [ 351.592349] general protection fault: 0000 [#1] SMP > [ 351.593440] Modules linked in: xfs(O) libcrc32c dm_linear_custom(O) nfsv3 > deflate zlib_deflate ctr twofish_generic twofish_x86_64_3way glue_helper lrw > xts gf128mul twofish_x86_64 twofish_common camellia_generic serpent_generic > blowfish_generic blowfish_x86_64 blowfish_common cast5_generic cast_common > des_generic xcbc rmd160 sha512_generic crypto_null af_key xfrm_algo kvm > ppdev vfat fat dm_round_robin microcode nfsd nfs_acl parport_pc dm_iostat(O) > dm_multipath(O) psmouse serio_raw mac_hid i2c_piix4 lp parport nfsv4 > auth_rpcgss nfs fscache lockd sunrpc floppy > [ 351.596118] CPU 3 > [ 351.596118] Pid: 133, comm: kworker/3:1H Tainted: G W O > 3.8.13-557-generic #1382000791 Bochs Bochs > [ 351.596118] RIP: 0010:[] [] > strnlen+0xb/0x30 > [ 351.596118] RSP: 0018:ffff880035405b08 EFLAGS: 00010086 > [ 351.596118] RAX: 0000000000000000 RBX: ffffffff81e6a4e7 RCX: > 0000000000000000 > [ 351.596118] RDX: e4e8390a265c0000 RSI: ffffffffffffffff RDI: > e4e8390a265c0000 > [ 351.596118] RBP: ffff880035405b08 R08: 000000000000ffff R09: > 000000000000ffff > [ 351.596118] R10: 0000000000000000 R11: 0000000000000331 R12: > e4e8390a265c0000 > [ 351.596118] R13: ffffffff81e6a8c0 R14: 0000000000000000 R15: > 000000000000ffff > [ 351.596118] FS: 0000000000000000(0000) GS:ffff88007fd80000(0000) > knlGS:0000000000000000 > [ 351.596118] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b > [ 351.596118] CR2: 00007fff7bfe1c38 CR3: 0000000035a59000 CR4: > 00000000000006e0 > [ 351.596118] DR0: 0000000000000000 DR1: 0000000000000000 DR2: > 0000000000000000 > [ 351.596118] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: > 0000000000000400 > [ 351.596118] Process kworker/3:1H (pid: 133, threadinfo ffff880035404000, > task ffff880035ae5c00) > [ 351.596118] Stack: > [ 351.596118] ffff880035405b48 ffffffff8133dd5e ffff880035405b28 > ffffffff81e6a4e7 > [ 351.596118] ffffffffa03b2bc4 ffff880035405c80 ffffffffa03b2bc4 > ffffffff81e6a8c0 > [ 351.596118] ffff880035405bc8 ffffffff8133ef59 ffff880035405bc8 > ffffffff81059aa7 > [ 351.596118] Call Trace: > [ 351.596118] [] string.isra.4+0x3e/0xd0 > [ 351.596118] [] vsnprintf+0x219/0x640 > [ 351.596118] [] ? msg_print_text+0xb7/0x1b0 > [ 351.596118] [] vscnprintf+0x11/0x30 > [ 351.596118] [] vprintk_emit+0xc1/0x490 > [ 351.596118] [] ? vprintk_emit+0x170/0x490 > [ 351.596118] [] printk+0x61/0x63 > [ 351.596118] [] __xfs_printk+0x31/0x50 [xfs] > [ 351.596118] [] xfs_notice+0x53/0x60 [xfs] > [ 351.596118] [] xfs_do_force_shutdown+0xf5/0x180 [xfs] > [ 351.596118] [] ? xlog_recover_iodone+0x48/0x70 [xfs] > [ 351.596118] [] xlog_recover_iodone+0x48/0x70 [xfs] > [ 351.596118] [] xfs_buf_iodone_work+0x4d/0xb0 [xfs] > [ 351.596118] [] process_one_work+0x141/0x4a0 > [ 351.596118] [] worker_thread+0x168/0x410 > [ 351.596118] [] ? manage_workers+0x120/0x120 > [ 351.596118] [] kthread+0xc0/0xd0 > [ 351.596118] [] ? flush_kthread_worker+0xb0/0xb0 > [ 351.596118] [] ret_from_fork+0x7c/0xb0 > [ 351.596118] [] ? flush_kthread_worker+0xb0/0xb0 > [ 351.596118] Code: 31 c0 80 3f 00 55 48 89 e5 74 11 48 89 f8 66 90 48 83 > c0 01 80 38 00 75 f7 48 29 f8 5d c3 66 90 55 31 c0 48 85 f6 48 89 e5 74 23 > <80> 3f 00 74 1e 48 89 f8 eb 0c 0f 1f 00 48 83 ee 01 80 38 00 74 > [ 351.596118] RIP [] strnlen+0xb/0x30 > [ 351.596118] RSP > [ 351.596118] ---[ end trace cb6b9820566f6848 ]--- > > > > -----Original Message----- From: Brian Foster > Sent: 01 September, 2014 12:05 AM > To: Alex Lyakas > Cc: xfs@oss.sgi.com ; Dave Chinner > Subject: Re: [PATCH] xfs: fix double free of trans in log recovery on I/O > error > > On Sun, Aug 31, 2014 at 11:50:52AM +0300, Alex Lyakas wrote: > >Hi Brian, Dave, > >I tested this patch on kernel 3.16, top commit: > > > >commit 19583ca584d6f574384e17fe7613dfaeadcdc4a6 > >Author: Linus Torvalds > >Date: Sun Aug 3 15:25:02 2014 -0700 > > > > Linux 3.16 > > > >and, yes, it appears to fix the issue. > > > > Thanks. That settles that then, I think. We're reproducing different > problems on the 3.8 stable kernel vs. a recent kernel using the same > test case. > > >Trouble is that our production kernel is 3.8.13, and we cannot upgrade to > >mainline kernel easily. Question is whether we can expect some patch > >suitable for our kernel, or, since our kernel is EOL and not a long-term > >one, we cannot? > > > > Dave wrote a patch specifically to resolve this problem on older > kernels: > > http://oss.sgi.com/archives/xfs/2014-08/msg00204.html > > Brian > > >Thanks for your help, > >Alex. > > > > > >-----Original Message----- From: Brian Foster > >Sent: 25 August, 2014 5:20 PM > >To: Alex Lyakas > >Cc: xfs@oss.sgi.com ; Dave Chinner > >Subject: Re: [PATCH] xfs: fix double free of trans in log recovery on I/O > >error > > > >On Sun, Aug 24, 2014 at 12:20:20PM +0300, Alex Lyakas wrote: > >>Hi Brian, > >> > >>On Thu, Aug 21, 2014 at 10:18 PM, Brian Foster > >>wrote: > >>> XFS log recovery builds up an xlog_recover object as it passes through > >>> the log operations on the physical log. These structures are managed >> > >via > >>> a hash table and are allocated when a new transaction is encountered >> > >and > >>> freed once a commit operation for the transaction is encountered. > >>> > >>> This state machine for active transactions is implemented by a > >>> combination of xlog_do_recovery_pass(), which walks through the log > >>> buffers and xlog_recover_process_data() which processes log operations > >>> within each buffer. The latter function decides whether to allocate a > >>> new xlog_recover, add to it or commit and ultimately free it. If an > >>> error occurs at any point during the lifecycle of a particular > >>> xlog_recover, xlog_recover_process_data() frees the object and returns > >>> an error. > >>> > >>> xlog_recover_commit_trans() handles the final processing of the > >>> transaction. It submits whatever I/O is required for the transaction >> > >and > >>> frees xlog_recover object along with the transaction items it tracks. > >>> If > >>> an error occurs at the final stages of the commit operation, such as >> > >I/O > >>> failure, both xlog_recover_commit_trans() and > >>> xlog_recover_process_data() attempt to free the trans object. > >>> > >>> Modify xlog_recover_commit_trans() to only free the trans object on > >>> successful completion of the trans, including any I/O errors that might > >>> occur when recovering the log. > >>> > >>> Signed-off-by: Brian Foster > >>> --- > >>> > >>> Hi all, > >>> > >>> I found that the recent buffer I/O rework fixes didn't address the >> > >crash > >>> reproduced by the dm-flakey/log recovery test case I posted recently. I > >>> tracked the crash down to this, which allows the test to pass. This > >>> addresses the crash I saw when running the reproducer manually with the > >>> metadump that Alex posted as well. > >>> > >>> FWIW, I also went back and tested the xfs_buf_iowait() experiment in > >>> both scenarios (Alex's metadump and xfstests test) and they all > >>> reproduce the same crash for me. I think that either I'm still not > >>> reproducing the original problem, something else might have >> > >contaminated > >>> the original xfs_buf_iowait() test to give a false positive, or > >>> something else entirely is going on. > >>> > >>> Alex, > >>> > >>> If you have a chance, I think it might be interesting to see whether >> > >you > >>> reproduce any problems with this patch. It looks like this is a > >>> regression introduced by: > >>> > >>> 2a84108f xfs: free the list of recovery items on error > >>> > >>> ... but I have no idea if that's in whatever kernel you're running. > >>I am running kernel 3.8.13 with some changes (published at > >>https://github.com/zadarastorage/zadara-xfs-pushback), but this > >>problem also happens on pristine 3.8.13 from > >>git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git, > >>branch linux-stable-3.8.y. > >> > >>I do not have commit 2a84108f in this kernel. It was introduced in 3.14. > >>I applied your patch to 3.8.13, but it doesn't fix the issue. Same > >>problem happens when testing scenario that I described in > >>http://oss.sgi.com/pipermail/xfs/2014-August/037637.html. > >> > > > >Ok, thanks. Yeah, I don't see the double free regression in the 3.8.13 > >stable branch. I went back to that kernel to try and confirm some > >things. I do reproduce the problem with your metadump as well as the > >test case I put together. I tested Dave's buf hold across sync I/O patch > >and that does indeed prevent the problem. > > > >For whatever reason, neither the test case nor your metadump reproduce > >the same problem on latest kernels. Instead, they reproduce this double > >free regression. I suspect this is what you ran into when you reproduced > >on a more recent kernel. If you'd like, feel free to try and verify that > >by running your reproducer again on a recent kernel with this patch and > >see if you can still reproduce a crash as with the 3.8.13 kernel. > > > >Brian > > > >>Thanks, > >>Alex. > >> > >>> > >>> Brian > >>> > >>> fs/xfs/xfs_log_recover.c | 11 ++++++++--- > >>> 1 file changed, 8 insertions(+), 3 deletions(-) > >>> > >>> diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c > >>> index 176c4b3..daca9a6 100644 > >>> --- a/fs/xfs/xfs_log_recover.c > >>> +++ b/fs/xfs/xfs_log_recover.c > >>> @@ -3528,10 +3528,15 @@ out: > >>> if (!list_empty(&done_list)) > >>> list_splice_init(&done_list, &trans->r_itemq); > >>> > >>> - xlog_recover_free_trans(trans); > >>> - > >>> error2 = xfs_buf_delwri_submit(&buffer_list); > >>> - return error ? error : error2; > >>> + > >>> + if (!error) > >>> + error = error2; > >>> + /* caller frees trans on error */ > >>> + if (!error) > >>> + xlog_recover_free_trans(trans); > >>> + > >>> + return error; > >>> } > >>> > >>> STATIC int > >>> -- > >>> 1.8.3.1 > >>> > > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Tue Sep 2 09:08:19 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 9B40D7F55 for ; Tue, 2 Sep 2014 09:08:19 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7C1A38F8059 for ; Tue, 2 Sep 2014 07:08:19 -0700 (PDT) X-ASG-Debug-ID: 1409666897-04cbb054889c4770001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id pJtnD8iqYoMoqIko (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 02 Sep 2014 07:08:18 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s82E8HCg000354 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 2 Sep 2014 10:08:17 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s82E8GsA008525 for ; Tue, 2 Sep 2014 10:08:16 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id AFCEF12577D; Tue, 2 Sep 2014 10:08:15 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 1/2] xfs: add debug sysfs attribute set Date: Tue, 2 Sep 2014 10:08:14 -0400 X-ASG-Orig-Subj: [PATCH v2 1/2] xfs: add debug sysfs attribute set Message-Id: <1409666895-49799-2-git-send-email-bfoster@redhat.com> In-Reply-To: <1409666895-49799-1-git-send-email-bfoster@redhat.com> References: <1409666895-49799-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1409666897 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Create a top-level debug directory for global debug sysfs attributes. This directory is added and removed on XFS module initialization and removal respectively for DEBUG mode kernels only. It typically resides at /sys/fs/xfs/debug. It is located at the top level of the xfs sysfs hierarchy as attributes might define global behavior or behavior that must be configured before an xfs mount is available (e.g., log recovery behavior). Define the global debug kobject that represents the debug sysfs directory and add generic attribute show/store helpers to support future attributes. No debug attributes are exported as of yet. Signed-off-by: Brian Foster --- fs/xfs/xfs_super.c | 23 +++++++++++++++++++++-- fs/xfs/xfs_sysfs.c | 43 +++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_sysfs.h | 1 + 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index b194652..919a64c 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -47,6 +47,7 @@ #include "xfs_dinode.h" #include "xfs_filestream.h" #include "xfs_quota.h" +#include "xfs_sysfs.h" #include #include @@ -61,7 +62,11 @@ static const struct super_operations xfs_super_operations; static kmem_zone_t *xfs_ioend_zone; mempool_t *xfs_ioend_pool; -struct kset *xfs_kset; + +struct kset *xfs_kset; /* top-level xfs sysfs dir */ +#ifdef DEBUG +static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */ +#endif #define MNTOPT_LOGBUFS "logbufs" /* number of XFS log buffers */ #define MNTOPT_LOGBSIZE "logbsize" /* size of XFS log buffers */ @@ -1768,9 +1773,16 @@ init_xfs_fs(void) goto out_sysctl_unregister;; } - error = xfs_qm_init(); +#ifdef DEBUG + xfs_dbg_kobj.kobject.kset = xfs_kset; + error = xfs_sysfs_init(&xfs_dbg_kobj, &xfs_dbg_ktype, NULL, "debug"); if (error) goto out_kset_unregister; +#endif + + error = xfs_qm_init(); + if (error) + goto out_remove_kobj; error = register_filesystem(&xfs_fs_type); if (error) @@ -1779,7 +1791,11 @@ init_xfs_fs(void) out_qm_exit: xfs_qm_exit(); + out_remove_kobj: +#ifdef DEBUG + xfs_sysfs_del(&xfs_dbg_kobj); out_kset_unregister: +#endif kset_unregister(xfs_kset); out_sysctl_unregister: xfs_sysctl_unregister(); @@ -1802,6 +1818,9 @@ exit_xfs_fs(void) { xfs_qm_exit(); unregister_filesystem(&xfs_fs_type); +#ifdef DEBUG + xfs_sysfs_del(&xfs_dbg_kobj); +#endif kset_unregister(xfs_kset); xfs_sysctl_unregister(); xfs_cleanup_procfs(); diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c index 9835139..32ddf0c 100644 --- a/fs/xfs/xfs_sysfs.c +++ b/fs/xfs/xfs_sysfs.c @@ -51,6 +51,49 @@ struct kobj_type xfs_mp_ktype = { .release = xfs_sysfs_release, }; +#ifdef DEBUG +/* debug */ + +static struct attribute *xfs_dbg_attrs[] = { + NULL, +}; + +STATIC ssize_t +xfs_dbg_show( + struct kobject *kobject, + struct attribute *attr, + char *buf) +{ + struct xfs_sysfs_attr *xfs_attr = to_attr(attr); + + return xfs_attr->show ? xfs_attr->show(buf, NULL) : 0; +} + +STATIC ssize_t +xfs_dbg_store( + struct kobject *kobject, + struct attribute *attr, + const char *buf, + size_t count) +{ + struct xfs_sysfs_attr *xfs_attr = to_attr(attr); + + return xfs_attr->store ? xfs_attr->store(buf, count, NULL) : 0; +} + +static struct sysfs_ops xfs_dbg_ops = { + .show = xfs_dbg_show, + .store = xfs_dbg_store, +}; + +struct kobj_type xfs_dbg_ktype = { + .release = xfs_sysfs_release, + .sysfs_ops = &xfs_dbg_ops, + .default_attrs = xfs_dbg_attrs, +}; + +#endif /* DEBUG */ + /* xlog */ STATIC ssize_t diff --git a/fs/xfs/xfs_sysfs.h b/fs/xfs/xfs_sysfs.h index 54a2091..240eee3 100644 --- a/fs/xfs/xfs_sysfs.h +++ b/fs/xfs/xfs_sysfs.h @@ -20,6 +20,7 @@ #define __XFS_SYSFS_H__ extern struct kobj_type xfs_mp_ktype; /* xfs_mount */ +extern struct kobj_type xfs_dbg_ktype; /* debug */ extern struct kobj_type xfs_log_ktype; /* xlog */ static inline struct xfs_kobj * -- 1.8.3.1 From bfoster@redhat.com Tue Sep 2 09:08:22 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 55BAD7F5A for ; Tue, 2 Sep 2014 09:08:22 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 28EBD8F804C for ; Tue, 2 Sep 2014 07:08:18 -0700 (PDT) X-ASG-Debug-ID: 1409666897-04bdf010a16d7ce0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 4b3Vflei9BiN6Rsa (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 02 Sep 2014 07:08:17 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s82E8Hw5024860 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 2 Sep 2014 10:08:17 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s82E8GQS024865 for ; Tue, 2 Sep 2014 10:08:16 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id BE4F0125780; Tue, 2 Sep 2014 10:08:15 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 2/2] xfs: export log_recovery_delay to delay mount time log recovery Date: Tue, 2 Sep 2014 10:08:15 -0400 X-ASG-Orig-Subj: [PATCH v2 2/2] xfs: export log_recovery_delay to delay mount time log recovery Message-Id: <1409666895-49799-3-git-send-email-bfoster@redhat.com> In-Reply-To: <1409666895-49799-1-git-send-email-bfoster@redhat.com> References: <1409666895-49799-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1409666897 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 XFS log recovery has been discovered to have race conditions with buffers when I/O errors occur. External tools are available to simulate I/O errors to XFS, but this alone is not sufficient for testing log recovery. XFS unconditionally resets the inactive region of the log prior to log recovery to avoid confusion over processing any partially written log records that might have been written before an unclean shutdown. Therefore, unconditional write I/O failures at mount time are caught by the reset sequence rather than log recovery and hinder the ability to test the latter. The device-mapper dm-flakey module uses an up/down timer to define a cycle for when to fail I/Os. Create a pre log recovery delay tunable that can be used to coordinate XFS log recovery with I/O errors simulated by dm-flakey. This facilitates coordination in userspace that allows the reset of stale log blocks to succeed and writes due to log recovery to fail. For example, define a dm-flakey instance with an uptime long enough to allow log reset to succeed and a log recovery delay long enough to allow the dm-flakey uptime to expire. The 'log_recovery_delay' sysfs tunable is exported under /sys/fs/xfs/debug and is only enabled for kernels compiled in XFS debug mode. The value is exported in units of seconds and allows for a delay of up to 60 seconds. Note that this is for XFS debug and test instrumentation purposes only and should not be used by applications. No delay is enabled by default. Signed-off-by: Brian Foster --- fs/xfs/xfs_globals.c | 4 ++++ fs/xfs/xfs_log_recover.c | 12 ++++++++++++ fs/xfs/xfs_sysctl.h | 5 +++++ fs/xfs/xfs_sysfs.c | 31 +++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+) diff --git a/fs/xfs/xfs_globals.c b/fs/xfs/xfs_globals.c index 5399ef2..4d41b24 100644 --- a/fs/xfs/xfs_globals.c +++ b/fs/xfs/xfs_globals.c @@ -43,3 +43,7 @@ xfs_param_t xfs_params = { .fstrm_timer = { 1, 30*100, 3600*100}, .eofb_timer = { 1, 300, 3600*24}, }; + +struct xfs_globals xfs_globals = { + .log_recovery_delay = 0, /* no delay by default */ +}; diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 1fd5787..176c4b3 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4509,6 +4509,18 @@ xlog_recover( return -EINVAL; } + /* + * Delay log recovery if the debug hook is set. This is debug + * instrumention to coordinate simulation of I/O failures with + * log recovery. + */ + if (xfs_globals.log_recovery_delay) { + xfs_notice(log->l_mp, + "Delaying log recovery for %d seconds.", + xfs_globals.log_recovery_delay); + msleep(xfs_globals.log_recovery_delay * 1000); + } + xfs_notice(log->l_mp, "Starting recovery (logdev: %s)", log->l_mp->m_logname ? log->l_mp->m_logname : "internal"); diff --git a/fs/xfs/xfs_sysctl.h b/fs/xfs/xfs_sysctl.h index bd8e157..ffef453 100644 --- a/fs/xfs/xfs_sysctl.h +++ b/fs/xfs/xfs_sysctl.h @@ -92,6 +92,11 @@ enum { extern xfs_param_t xfs_params; +struct xfs_globals { + int log_recovery_delay; /* log recovery delay (secs) */ +}; +extern struct xfs_globals xfs_globals; + #ifdef CONFIG_SYSCTL extern int xfs_sysctl_register(void); extern void xfs_sysctl_unregister(void); diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c index 32ddf0c..aa03670 100644 --- a/fs/xfs/xfs_sysfs.c +++ b/fs/xfs/xfs_sysfs.c @@ -54,7 +54,38 @@ struct kobj_type xfs_mp_ktype = { #ifdef DEBUG /* debug */ +STATIC ssize_t +log_recovery_delay_store( + const char *buf, + size_t count, + void *data) +{ + int ret; + int val; + + ret = kstrtoint(buf, 0, &val); + if (ret) + return ret; + + if (val < 0 || val > 60) + return -EINVAL; + + xfs_globals.log_recovery_delay = val; + + return count; +} + +STATIC ssize_t +log_recovery_delay_show( + char *buf, + void *data) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.log_recovery_delay); +} +XFS_SYSFS_ATTR_RW(log_recovery_delay); + static struct attribute *xfs_dbg_attrs[] = { + ATTR_LIST(log_recovery_delay), NULL, }; -- 1.8.3.1 From bfoster@redhat.com Tue Sep 2 09:08:22 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BDCD47F5A for ; Tue, 2 Sep 2014 09:08:22 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5D426AC004 for ; Tue, 2 Sep 2014 07:08:19 -0700 (PDT) X-ASG-Debug-ID: 1409666897-04cb6c54fe7386b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 3GprteEyIBxb6u9z (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 02 Sep 2014 07:08:18 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s82E8GCj027856 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 2 Sep 2014 10:08:17 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s82E8GRX001634 for ; Tue, 2 Sep 2014 10:08:16 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id A52A612577F; Tue, 2 Sep 2014 10:08:15 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 0/2] xfs log recovery delay instrumentation Date: Tue, 2 Sep 2014 10:08:13 -0400 X-ASG-Orig-Subj: [PATCH v2 0/2] xfs log recovery delay instrumentation Message-Id: <1409666895-49799-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1409666897 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Here's v2 of the log recovery delay instrumentation set. v1 is available here: http://oss.sgi.com/archives/xfs/2014-08/msg00276.html After a brief conversation with Dave, we thought it best to tie in this functionality with DEBUG mode to express/ensure that these attributes are for debugging/hacking purposes only. Everything else should be equivalent to v1. Brian v2: - Enable /sys/fs/xfs/debug for DEBUG mode kernels only. v1: http://oss.sgi.com/archives/xfs/2014-08/msg00276.html Brian Foster (2): xfs: add debug sysfs attribute set xfs: export log_recovery_delay to delay mount time log recovery fs/xfs/xfs_globals.c | 4 +++ fs/xfs/xfs_log_recover.c | 12 ++++++++ fs/xfs/xfs_super.c | 23 +++++++++++++-- fs/xfs/xfs_sysctl.h | 5 ++++ fs/xfs/xfs_sysfs.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_sysfs.h | 1 + 6 files changed, 117 insertions(+), 2 deletions(-) -- 1.8.3.1 From bfoster@redhat.com Tue Sep 2 09:22:45 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 494377F59 for ; Tue, 2 Sep 2014 09:22:45 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 355C28F8040 for ; Tue, 2 Sep 2014 07:22:44 -0700 (PDT) X-ASG-Debug-ID: 1409667763-04cbb054859c5020001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id jMYotLnvPnUkBdUM (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 02 Sep 2014 07:22:44 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s82EMhol029010 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 2 Sep 2014 10:22:43 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s82EMgj7010153; Tue, 2 Sep 2014 10:22:43 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id F350212577D; Tue, 2 Sep 2014 10:22:41 -0400 (EDT) From: Brian Foster To: fstests@vger.kernel.org Cc: xfs@oss.sgi.com Subject: [PATCH 1/2] xfstests/common: don't assume sysfs attrs all reside under test dev Date: Tue, 2 Sep 2014 10:22:40 -0400 X-ASG-Orig-Subj: [PATCH 1/2] xfstests/common: don't assume sysfs attrs all reside under test dev Message-Id: <1409667761-50248-2-git-send-email-bfoster@redhat.com> In-Reply-To: <1409667761-50248-1-git-send-email-bfoster@redhat.com> References: <1409667761-50248-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1409667764 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 _require_xfs_sysfs() currently assumes that all sysfs attributes reside under a device-specific subdirectory in the XFS sysfs hierarchy. It is hardcoded to use the TEST_DEV mount and expect the relative attribute path as a parameter. Not all sysfs attributes are associated with specific devices or mount points, however. Remove the hardcoded device name part of the attribute path from _require_xfs_sysfs() and let the caller construct the relative path based on the sysfs XFS root directory. Signed-off-by: Brian Foster --- common/rc | 3 +-- tests/xfs/011 | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/common/rc b/common/rc index 16da898..01f573e 100644 --- a/common/rc +++ b/common/rc @@ -1224,13 +1224,12 @@ _require_xfs_sysfs() { attr=$1 sysfsdir=/sys/fs/xfs - testdev=`_short_dev $TEST_DEV` if [ ! -e $sysfsdir ]; then _notrun "no kernel support for XFS sysfs attributes" fi - if [ ! -z $1 ] && [ ! -e $sysfsdir/$testdev/$attr ]; then + if [ ! -z $1 ] && [ ! -e $sysfsdir/$attr ]; then _notrun "sysfs attribute '$attr' is not supported" fi } diff --git a/tests/xfs/011 b/tests/xfs/011 index 658a822..197752c 100755 --- a/tests/xfs/011 +++ b/tests/xfs/011 @@ -85,7 +85,7 @@ _supported_os Linux _require_scratch _require_freeze -_require_xfs_sysfs log +_require_xfs_sysfs $(_short_dev $TEST_DEV)/log rm -f $seqres.full -- 1.8.3.1 From bfoster@redhat.com Tue Sep 2 09:22:47 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 9BF1A7F62 for ; Tue, 2 Sep 2014 09:22:47 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 15C24AC003 for ; Tue, 2 Sep 2014 07:22:47 -0700 (PDT) X-ASG-Debug-ID: 1409667765-04cb6c54fe738eb0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id D5eZzs7IAQDU43JH (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 02 Sep 2014 07:22:46 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s82EMhN7030989 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 2 Sep 2014 10:22:44 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s82EMhik017624; Tue, 2 Sep 2014 10:22:43 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 0E165125780; Tue, 2 Sep 2014 10:22:41 -0400 (EDT) From: Brian Foster To: fstests@vger.kernel.org Cc: xfs@oss.sgi.com Subject: [PATCH 2/2] xfs/051: test buffer use after free race on I/O failure in XFS log recovery Date: Tue, 2 Sep 2014 10:22:41 -0400 X-ASG-Orig-Subj: [PATCH 2/2] xfs/051: test buffer use after free race on I/O failure in XFS log recovery Message-Id: <1409667761-50248-3-git-send-email-bfoster@redhat.com> In-Reply-To: <1409667761-50248-1-git-send-email-bfoster@redhat.com> References: <1409667761-50248-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1409667765 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 A buffer use after free race was discovered in the XFS log recovery codepath if I/O failures occur during recovery. The I/O submission path can abort the mount and release the only reference held on some buffers before I/O completion processing (e.g., async workqueue processing) might have completed. Badness ensues if the I/O completion path subsequently attempts to access said buffers. The test manufactures the race by forcing all writes to fail (via dm-flakey) after a fixed period of time. A delay is inserted into the mount codepath to synchronize write failures with log recovery. Credit for discovery of the race and definition of the reproducible test case goes to Alex Lyakas. Signed-off-by: Brian Foster Reported-by: Alex Lyakas --- tests/xfs/051 | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/xfs/051.out | 2 ++ tests/xfs/group | 1 + 3 files changed, 98 insertions(+) create mode 100755 tests/xfs/051 create mode 100644 tests/xfs/051.out diff --git a/tests/xfs/051 b/tests/xfs/051 new file mode 100755 index 0000000..a84746b --- /dev/null +++ b/tests/xfs/051 @@ -0,0 +1,95 @@ +#! /bin/bash +# FS QA Test No. 051 +# +# Simulate a buffer use after free race in XFS log recovery. The race triggers +# on I/O failures during log recovery. Note that this test is dangerous as it +# causes BUG() errors or a panic. +# +#----------------------------------------------------------------------- +# Copyright (c) 2013 Oracle, Inc. All Rights Reserved. +# +# This program 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. +# +# This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -f $tmp.* + killall -9 $FSSTRESS_PROG > /dev/null 2>&1 + _scratch_unmount > /dev/null 2>&1 +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/dmflakey + +# Modify as appropriate. +_supported_fs xfs +_supported_os Linux + +_require_scratch +_require_dm_flakey +_require_xfs_sysfs debug/log_recovery_delay + +echo "Silence is golden." + +_scratch_mkfs_xfs >/dev/null 2>&1 +_scratch_mount + +# Start a workload and shutdown the fs. The subsequent mount will require log +# recovery. +$FSSTRESS_PROG -n 9999 -p 2 -w -d $SCRATCH_MNT > /dev/null 2>&1 & +sleep 5 +src/godown -f $SCRATCH_MNT +killall -q $FSSTRESS_PROG +wait +_scratch_unmount + +# Initialize a dm-flakey device that will pass I/Os for 5s and fail thereafter. +_init_flakey +BLK_DEV_SIZE=`blockdev --getsz $SCRATCH_DEV` +FLAKEY_TABLE="0 $BLK_DEV_SIZE flakey $SCRATCH_DEV 0 5 180" +_load_flakey_table $FLAKEY_ALLOW_WRITES + +# Set a 10s log recovery delay and mount the flakey device. This should allow +# initial writes to proceed (e.g., stale log block reset) and then let the +# flakey uptime timer expire such that I/Os will fail by the time log recovery +# starts. +echo 10 > /sys/fs/xfs/debug/log_recovery_delay + +# The mount should fail due to dm-flakey. Note that this is dangerous on kernels +# without the xfs_buf log recovery race fixes. +_mount_flakey > /dev/null 2>&1 + +echo 0 > /sys/fs/xfs/debug/log_recovery_delay + +_cleanup_flakey + +# replay the log +_scratch_mount +_scratch_unmount + +# success, all done +status=0 +exit diff --git a/tests/xfs/051.out b/tests/xfs/051.out new file mode 100644 index 0000000..5180bc4 --- /dev/null +++ b/tests/xfs/051.out @@ -0,0 +1,2 @@ +QA output created by 051 +Silence is golden. diff --git a/tests/xfs/group b/tests/xfs/group index 4d35df5..9784dea 100644 --- a/tests/xfs/group +++ b/tests/xfs/group @@ -47,6 +47,7 @@ 048 other auto quick 049 rw auto quick 050 quota auto quick +051 dangerous 052 quota db auto quick 054 quota auto quick 055 dump ioctl remote tape -- 1.8.3.1 From bfoster@redhat.com Tue Sep 2 09:22:48 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id F17CA7F62 for ; Tue, 2 Sep 2014 09:22:48 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id D2987304039 for ; Tue, 2 Sep 2014 07:22:45 -0700 (PDT) X-ASG-Debug-ID: 1409667764-04cbb054879c5030001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id bTAHBgOq5Qi9QJcB (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 02 Sep 2014 07:22:44 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s82EMhdL002270 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 2 Sep 2014 10:22:43 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s82EMgIi006107; Tue, 2 Sep 2014 10:22:43 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id E296312577F; Tue, 2 Sep 2014 10:22:41 -0400 (EDT) From: Brian Foster To: fstests@vger.kernel.org Cc: xfs@oss.sgi.com Subject: [PATCH 0/2] xfs buf I/O error race test Date: Tue, 2 Sep 2014 10:22:39 -0400 X-ASG-Orig-Subj: [PATCH 0/2] xfs buf I/O error race test Message-Id: <1409667761-50248-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1409667764 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hi all, Here's a complete test for the XFS buf I/O error race problem reported by Alex. An incomplete rfc of this test was previously posted here: http://oss.sgi.com/archives/xfs/2014-08/msg00261.html This version utilizes the recently posted log recovery delay mechanism. As such, this test only runs on kernels compiled with XFS debug support. The first patch updates the generic require sysfs helper to support global (i.e., non-device specific) sysfs attributes. Brian v1: - Use the log recovery delay mechanism to coordinate I/O failures with log recovery. rfc: http://oss.sgi.com/archives/xfs/2014-08/msg00261.html Brian Foster (2): xfstests/common: don't assume sysfs attrs all reside under test dev xfs/051: test buffer use after free race on I/O failure in XFS log recovery common/rc | 3 +- tests/xfs/011 | 2 +- tests/xfs/051 | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/xfs/051.out | 2 ++ tests/xfs/group | 1 + 5 files changed, 100 insertions(+), 3 deletions(-) create mode 100755 tests/xfs/051 create mode 100644 tests/xfs/051.out -- 1.8.3.1 From stan@hardwarefreak.com Tue Sep 2 12:15:11 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 951A17F53 for ; Tue, 2 Sep 2014 12:15:11 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 32B14AC003 for ; Tue, 2 Sep 2014 10:15:07 -0700 (PDT) X-ASG-Debug-ID: 1409678106-04cb6c54fd741290001-NocioJ Received: from greer.hardwarefreak.com (mo-65-41-216-221.sta.embarqhsd.net [65.41.216.221]) by cuda.sgi.com with ESMTP id fV9YsJOgMCmCGKtG for ; Tue, 02 Sep 2014 10:15:06 -0700 (PDT) X-Barracuda-Envelope-From: stan@hardwarefreak.com X-Barracuda-Apparent-Source-IP: 65.41.216.221 X-Barracuda-User-Whitelist: xfs@oss.sgi.com Received: from [134.64.128.151] (unknown [192.65.45.20]) by greer.hardwarefreak.com (Postfix) with ESMTPA id CDE116C149; Tue, 2 Sep 2014 12:15:05 -0500 (CDT) Message-ID: <5405FB19.2020208@hardwarefreak.com> Date: Tue, 02 Sep 2014 12:15:05 -0500 From: stan hoeppner User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Icedove/24.7.0 MIME-Version: 1.0 To: Dave Chinner CC: xfs@oss.sgi.com Subject: Re: storage, libaio, or XFS problem? 3.4.26 References: <20140826075345.GJ20518@dastard> <8c29baf987467a84f0b7c1d09c863662@localhost> <20140828003226.GO20518@dastard> <7f9e5aef187b44e899077467aeb0809d@localhost> <20140828230817.GU20518@dastard> <2d2ce7bb38c00a7d35f4a324f6a36cbb@localhost> <20140829235538.GF20518@dastard> <20140831235749.GH20518@dastard> <5403E9B9.7040608@hardwarefreak.com> <20140901234529.GI20518@dastard> X-ASG-Orig-Subj: Re: storage, libaio, or XFS problem? 3.4.26 In-Reply-To: <20140901234529.GI20518@dastard> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mo-65-41-216-221.sta.embarqhsd.net[65.41.216.221] X-Barracuda-Start-Time: 1409678106 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On 09/01/2014 06:45 PM, Dave Chinner wrote: > On Sun, Aug 31, 2014 at 10:36:25PM -0500, stan hoeppner wrote: >> On 08/31/2014 06:57 PM, Dave Chinner wrote: >>> On Fri, Aug 29, 2014 at 09:55:53PM -0500, Stan Hoeppner wrote: >>>> Have you played with bcache yet? >>> >>> Enough to scare me. So many ways for things to go wrong, no easy way >>> to recover when things go wrong. And that's before I even get to >>> performance warts, like having systems stall completely because >>> there's tens or hundreds of GB of 4k random writes that have to be >>> flushed to slow SATA RAID6 in the cache.... >> >> Yikes. I hadn't yet heard such opinions expressed. By go wrong I >> assume you mean the btrees or cached sector data getting broken, corrupted? > > bcache is a complex filesystem hidden inside a block device. If > bcache goes AWOL, so does the all the data on your block device. > Need I say more? So it's no different in that regard than the black box implementations such as LSI's CacheCade and various SAN vendor SSD caching implementations. Or are you saying the bcache code complexity is so much greater that failure is more likely that the vendor implementations? >>> PS: can you wrap your text at 68 or 72 columns so quoted text >>> doesn't overflow 80 columns and get randomly wrapped and messed up? >> >> This email should be. Lemme see what I can do with the others. The >> lovely Cisco VPN client I must use kills routing to my local subnet, so >> Icedovce can't connect to my IMAP server when the VPN is active. The >> test hardness app requires a shell unfortunately so I have to keep the >> tunnel open all the time, as the test runs are 40+ hours each. My last >> test just crashed a bit ago so I can use Icedove for this reply. > > screen is your friend when it comes to keeping remote shells > active as the network comes and goes. VPN drops out, just bring it > back up when you need it and reconnect to the remote screen instance > and it's like you never left.... Thanks for this tip. I'd heard of screen before but never used it. I will say the man page is a bit intimidating for such an apparently simple tool... Stan From bfoster@redhat.com Tue Sep 2 14:16:30 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id AA72D7F4E for ; Tue, 2 Sep 2014 14:16:30 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 56B72AC004 for ; Tue, 2 Sep 2014 12:16:27 -0700 (PDT) X-ASG-Debug-ID: 1409685383-04bdf010a16e5780001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 7rbufw64z0TzcAYm (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 02 Sep 2014 12:16:23 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s82JGM6b018512 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 2 Sep 2014 15:16:22 -0400 Received: from laptop.bfoster (vpn-51-136.rdu2.redhat.com [10.10.51.136]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s82JGKZF013899 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 2 Sep 2014 15:16:22 -0400 Date: Tue, 2 Sep 2014 15:16:20 -0400 From: Brian Foster To: xfs@oss.sgi.com Subject: Re: [RFC PATCH 0/4] clean up collapse range and handle post-eof delalloc Message-ID: <20140902191620.GA5304@laptop.bfoster> X-ASG-Orig-Subj: Re: [RFC PATCH 0/4] clean up collapse range and handle post-eof delalloc References: <1409344178-44817-1-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1409344178-44817-1-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1409685383 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Aug 29, 2014 at 04:29:34PM -0400, Brian Foster wrote: > Here's a drop of what I'm testing over the weekend. It passes some quick > tests, but only lightly tested so far. > fsx has been running for over 3 days without a failure and I've kicked off a parallel fsstress today that so far hasn't caused any problems. Given that, I think the patches here help reduce the likelihood of errors from collapse. > My biggest question at this point is whether there is any risk to the > shift of the post-eof extent if the subsequent truncate happens to fail. > If it's not worth dealing with that, we could just drop patch 3 and > leave the eofblocks trim permanently. > That said, a test to skip the post-collapse truncate confirms that the behavior of patch 3 is potentially problematic in the event of failure. E.g., there is no behavior analogous to the zeroing of prealloc space for extending truncates. I think the right thing to do here might be for the collapse to writeback and invalidate the range following the space that was freed to EOF and to retain the eofblocks trim. Brian > In fact, it might even be a good idea to go back to the original > [start,-1] writeback in collapse range given that the free file space > helper could change at some point to only write and punch out the range > being freed... and then we're left shifting a bunch of extents after the > freed range that could have dirty data in pagecache, which sounds bad. > Thoughts? > > Brian > > Brian Foster (4): > xfs: track collapse via file offset rather than extent index > xfs: refactor xfs_bmap_shift_extents() into multiple functions > xfs: allow collapse to handle delalloc extents > xfs: remove file writeback and eofblocks trim from collapse range > > fs/xfs/libxfs/xfs_bmap.c | 302 ++++++++++++++++++++++++++++++++--------------- > fs/xfs/libxfs/xfs_bmap.h | 7 +- > fs/xfs/xfs_bmap_util.c | 32 +---- > 3 files changed, 214 insertions(+), 127 deletions(-) > > -- > 1.8.3.1 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From david@fromorbit.com Tue Sep 2 17:02:36 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 66EC67F52 for ; Tue, 2 Sep 2014 17:02:36 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 13512AC006 for ; Tue, 2 Sep 2014 15:02:32 -0700 (PDT) X-ASG-Debug-ID: 1409695350-04bdf010a06ea920001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id mcVlGR21r4ER0eRN for ; Tue, 02 Sep 2014 15:02:31 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AowgAHA9BlR5LDJ8/2dsb2JhbABagw1TV4IsrQ8BAQEBBphlgVuFaQEDAQEBgRIXd4QEAQU6HCMQCAMYCSUPBSUDIROIQQ69CQEXGIVkh0GCEAeETAWFBQKQWIZ8lR+DcysvAYJOAQEB Received: from ppp121-44-50-124.lns20.syd6.internode.on.net (HELO dastard) ([121.44.50.124]) by ipmail07.adl2.internode.on.net with ESMTP; 03 Sep 2014 07:32:29 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XOw9Y-0008Tk-9W; Wed, 03 Sep 2014 08:02:16 +1000 Date: Wed, 3 Sep 2014 08:02:16 +1000 From: Dave Chinner To: Alex Lyakas Cc: Brian Foster , xfs@oss.sgi.com Subject: Re: [PATCH] xfs: fix double free of trans in log recovery on I/O error Message-ID: <20140902220216.GJ20518@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs: fix double free of trans in log recovery on I/O error References: <1408648692-15957-1-git-send-email-bfoster@redhat.com> <20140825142025.GA10135@bfoster.bfoster> <20140831210507.GA11913@bfoster.bfoster> <3476A2CBDE694DC6BD06DBDD15165151@alyakaslap> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <3476A2CBDE694DC6BD06DBDD15165151@alyakaslap> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1409695350 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=MARKETING_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9109 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words On Tue, Sep 02, 2014 at 12:51:35PM +0300, Alex Lyakas wrote: > Hi Brian, Dave, > I tested this patch on 3.8.13 kernel with the scenario I described > in http://oss.sgi.com/pipermail/xfs/2014-August/037637.html, but I > still see the issue. > I placed the metadump at https://drive.google.com/file/d/0ByBy89zr3kJNV2UxMERNTkE4aHM/edit?usp=sharing > > During log recovery, 3 IO errors are encountered: > [ 340.381199] XFS (dm-0): Mounting Filesystem > [ 340.439897] XFS (dm-0): Sleep 10s before xlog_do_recover > [ 350.440143] XFS (dm-0): Starting recovery (logdev: internal) > [ 351.584647] XFS (dm-0): metadata I/O error: block 0x1 > ("xlog_recover_iodone") error 28 numblks 1 > [ 351.584660] XFS (dm-0): metadata I/O error: block 0x40 > ("xlog_recover_iodone") error 28 numblks 16 > [ 351.584665] XFS (dm-0): xfs_do_force_shutdown(0x1) called from > line 377 of file > /mnt/work/alex/zadara-btrfs/fs/xfs/xfs_log_recover.c. Return > address = 0xffffffffa0372728 > [ 351.584969] XFS (dm-0): I/O Error Detected. Shutting down filesystem > [ 351.584970] XFS (dm-0): Please umount the filesystem and rectify > the problem(s) > [ 351.585047] XFS (dm-0): metadata I/O error: block 0x1e00040 > ("xlog_recover_iodone") error 28 numblks 16 > [ 351.585050] XFS (dm-0): xfs_do_force_shutdown(0x1) called from > line 377 of file > /mnt/work/alex/zadara-btrfs/fs/xfs/xfs_log_recover.c. Return > address = 0xffffffffa0372728 > [ 351.585068] XFS (dm-0): log mount/recovery failed: error 28 > [ 351.585332] XFS (dm-0): log mount failed > > Two IO error callbacks are handled before XFS is unmounted, but the > last one crashes with stack[1]. > > Do I need some or all of the 9 patches that Dave posted? (They do > not apply to my kernel, so I need to apply them by hand). No, I suspect that there are other problems that have been fixed since 3.8 that you are missing. e.g. 9c23ecc xfs: unmount does not wait for shutdown during unmount THere's bound to be others, so you're really going to need to look at the differences between 3.8 and a current mainline to determine what other patches you are going to need... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Tue Sep 2 17:20:00 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 890A37F55 for ; Tue, 2 Sep 2014 17:20:00 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7660A304066 for ; Tue, 2 Sep 2014 15:19:57 -0700 (PDT) X-ASG-Debug-ID: 1409696392-04cb6c54ff74d560001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id igUdXgNIV7wivOyJ for ; Tue, 02 Sep 2014 15:19:52 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoEgACNCBlR5LDJ8/2dsb2JhbABagw2BKoIsrQ8BAQEBBppAhWkBAwEBAYESF3eEAwEBBAE6HCMQCAMYCSUPBSUDIROIOge9HwEXGIVkiQhJB4RMBZoLglCBNpNpgW8WgW4rL4EHAR4GgSMBAQE Received: from ppp121-44-50-124.lns20.syd6.internode.on.net (HELO dastard) ([121.44.50.124]) by ipmail07.adl2.internode.on.net with ESMTP; 03 Sep 2014 07:49:29 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XOwPz-00005R-8o; Wed, 03 Sep 2014 08:19:15 +1000 Date: Wed, 3 Sep 2014 08:19:15 +1000 From: Dave Chinner To: stan hoeppner Cc: xfs@oss.sgi.com Subject: Re: storage, libaio, or XFS problem? 3.4.26 Message-ID: <20140902221915.GK20518@dastard> X-ASG-Orig-Subj: Re: storage, libaio, or XFS problem? 3.4.26 References: <20140828003226.GO20518@dastard> <7f9e5aef187b44e899077467aeb0809d@localhost> <20140828230817.GU20518@dastard> <2d2ce7bb38c00a7d35f4a324f6a36cbb@localhost> <20140829235538.GF20518@dastard> <20140831235749.GH20518@dastard> <5403E9B9.7040608@hardwarefreak.com> <20140901234529.GI20518@dastard> <5405FB19.2020208@hardwarefreak.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5405FB19.2020208@hardwarefreak.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1409696392 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9109 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 02, 2014 at 12:15:05PM -0500, stan hoeppner wrote: > On 09/01/2014 06:45 PM, Dave Chinner wrote: > > On Sun, Aug 31, 2014 at 10:36:25PM -0500, stan hoeppner wrote: > >> On 08/31/2014 06:57 PM, Dave Chinner wrote: > >>> On Fri, Aug 29, 2014 at 09:55:53PM -0500, Stan Hoeppner wrote: > >>>> Have you played with bcache yet? > >>> > >>> Enough to scare me. So many ways for things to go wrong, no easy way > >>> to recover when things go wrong. And that's before I even get to > >>> performance warts, like having systems stall completely because > >>> there's tens or hundreds of GB of 4k random writes that have to be > >>> flushed to slow SATA RAID6 in the cache.... > >> > >> Yikes. I hadn't yet heard such opinions expressed. By go wrong I > >> assume you mean the btrees or cached sector data getting broken, corrupted? > > > > bcache is a complex filesystem hidden inside a block device. If > > bcache goes AWOL, so does the all the data on your block device. > > Need I say more? > > So it's no different in that regard than the black box implementations > such as LSI's CacheCade and various SAN vendor SSD caching > implementations. Or are you saying the bcache code complexity is so > much greater that failure is more likely that the vendor implementations? No, not the code complexity in particular. It's more that compared to vendor SSD caching implementations there's an awful lot less testing and validation, and people tend to use random, unreliable hardware for cache devices. It's great when it works, but the configuration and validation of correct behaviour in error conditions falls to the user... > > screen is your friend when it comes to keeping remote shells > > active as the network comes and goes. VPN drops out, just bring it > > back up when you need it and reconnect to the remote screen instance > > and it's like you never left.... > > Thanks for this tip. I'd heard of screen before but never used it. I > will say the man page is a bit intimidating for such an apparently > simple tool... Yeah, I use about 0.0001% of what screen can do. It could lose most of it's functionality and I wouldn't notice or care. tmux is another option for this functionality, but I've never used it because I found out about screen first... Cheers, Dave. -- Dave Chinner david@fromorbit.com From clarifylzx@gmail.com Tue Sep 2 20:49:37 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 0E5107F57 for ; Tue, 2 Sep 2014 20:49:37 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9FC2AAC002 for ; Tue, 2 Sep 2014 18:49:33 -0700 (PDT) X-ASG-Debug-ID: 1409708969-04bdf010976f5980001-NocioJ Received: from mail-lb0-f194.google.com (mail-lb0-f194.google.com [209.85.217.194]) by cuda.sgi.com with ESMTP id LnvkchBPVjdK2FuI (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Tue, 02 Sep 2014 18:49:30 -0700 (PDT) X-Barracuda-Envelope-From: clarifylzx@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.217.194 X-Barracuda-IPDD: Level1 [gmail.com/209.85.217.194] Received: by mail-lb0-f194.google.com with SMTP id p9so3205944lbv.9 for ; Tue, 02 Sep 2014 18:49:28 -0700 (PDT) X-Barracuda-IPDD: Level1 [gmail.com/209.85.217.194] X-Barracuda-IPDD: Level1 [gmail.com/209.85.217.194] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=AKuQ7wU5hphnuVFMMYcT5ag/a0zFkSxyqjq/ZOf5Wt4=; b=pDurJ5MhZ2eKqG1X/8+DCwWr2LrGVNNxvJDrmCc4IR75SE61BqC1cSSJeDZcOPXBgf 7LyKzpoKPrfbUY2l/yuDYp6JpnpbKCsUkhjvCg49UDxuFAY3D/KU9dkUU+h5CSorJgLD kmRP9iiUQ+3O44yldwkBDHKy0btiN7ErTunqNONEJB6CWltvoip53z55An8vdZ7N2kdn KTh15hBMRFKvZULNwbd7lpfSnrukmQd7saW3XSk597Shd/VfRYAMZDepalolJWB7KuY9 FWB3hXjXmgahYqrPHJLTd/pYZfz/fFctI0sSLeA/5EsaftkSGCKE6o7JtE7tJbzT6PEX DJJw== MIME-Version: 1.0 X-Received: by 10.152.170.228 with SMTP id ap4mr3315442lac.66.1409708968630; Tue, 02 Sep 2014 18:49:28 -0700 (PDT) Received: by 10.114.229.164 with HTTP; Tue, 2 Sep 2014 18:49:26 -0700 (PDT) Date: Wed, 3 Sep 2014 09:49:26 +0800 Message-ID: Subject: color box, display box, corrugated box, color card, blister card, color sleeve, hang tag, label From: Jinghao Printing - CHINA X-ASG-Orig-Subj: color box, display box, corrugated box, color card, blister card, color sleeve, hang tag, label To: undisclosed-recipients:; Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f194.google.com[209.85.217.194] X-Barracuda-Start-Time: 1409708970 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9116 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature Hi, this is David Wu from Shanghai, China. We are a printing company, we can print color box, corrugated box, label, hang tag etc. Please let me know if you need these. I will send you the website then. Best regards, David Wu From bo.li.liu@oracle.com Tue Sep 2 22:26:33 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 1DFCC7F57 for ; Tue, 2 Sep 2014 22:26:33 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id E377D8F8054 for ; Tue, 2 Sep 2014 20:26:32 -0700 (PDT) X-ASG-Debug-ID: 1409714787-04bdf0109a6fa8d0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 0EdKRISESCHcPIH8 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 02 Sep 2014 20:26:28 -0700 (PDT) X-Barracuda-Envelope-From: bo.li.liu@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from acsinet22.oracle.com (acsinet22.oracle.com [141.146.126.238]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id s833QQIj009281 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 3 Sep 2014 03:26:27 GMT Received: from userz7022.oracle.com (userz7022.oracle.com [156.151.31.86]) by acsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id s833QPUN026906 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 3 Sep 2014 03:26:26 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by userz7022.oracle.com (8.14.5+Sun/8.14.4) with ESMTP id s833QOg4014937; Wed, 3 Sep 2014 03:26:25 GMT Received: from localhost.jp.oracle.com (/10.191.5.50) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 02 Sep 2014 20:26:24 -0700 From: Liu Bo To: xfs@oss.sgi.com Cc: linux-btrfs Subject: [PATCH] xfstests: remove check_scratch_fs in btrfs/012 Date: Wed, 3 Sep 2014 11:25:59 +0800 X-ASG-Orig-Subj: [PATCH] xfstests: remove check_scratch_fs in btrfs/012 Message-Id: <1409714759-9805-1-git-send-email-bo.li.liu@oracle.com> X-Mailer: git-send-email 1.8.1.4 X-Source-IP: acsinet22.oracle.com [141.146.126.238] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1409714788 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9119 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines From: Liu Bo btrfs/012 is a case to verify btrfs-convert feature, it converts an ext4 to btrfs firstly and do something, then rolls back to ext4. So at last we have a ext4 on the scratch device, but setting _require_scratch will force a btrfsck on a ext4 fs because $FSTYP here is btrfs, and it ends up with a failure report of _check_btrfs_filesystem. Now that we have deliberately check the final ext4 fs in btrfs/012, just do not set _require_scratch in this case. Signed-off-by: Liu Bo --- tests/btrfs/012 | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/btrfs/012 b/tests/btrfs/012 index f7e5da5..12f6462 100755 --- a/tests/btrfs/012 +++ b/tests/btrfs/012 @@ -52,7 +52,6 @@ _cleanup() # Modify as appropriate. _supported_fs btrfs _supported_os Linux -_require_scratch BTRFS_CONVERT_PROG="`set_prog_path btrfs-convert`" MKFS_EXT4_PROG="`set_prog_path mkfs.ext4`" -- 1.8.1.4 From shudesmond2@outlook.com Wed Sep 3 11:23:48 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.3 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,HTML_MESSAGE,T_FREEMAIL_DOC_PDF autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 175407F37 for ; Wed, 3 Sep 2014 11:23:48 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 89023AC002 for ; Wed, 3 Sep 2014 09:23:47 -0700 (PDT) X-ASG-Debug-ID: 1409761421-04cb6c550077f540001-NocioJ Received: from COL004-OMC3S9.hotmail.com (col004-omc3s9.hotmail.com [65.55.34.147]) by cuda.sgi.com with ESMTP id dVoFrd5ZcX8Sz2Vr (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO) for ; Wed, 03 Sep 2014 09:23:42 -0700 (PDT) X-Barracuda-Envelope-From: shudesmond2@outlook.com X-Barracuda-Apparent-Source-IP: 65.55.34.147 Received: from COL125-W35 ([65.55.34.136]) by COL004-OMC3S9.hotmail.com with Microsoft SMTPSVC(7.5.7601.22701); Wed, 3 Sep 2014 09:23:41 -0700 X-TMN: [0e1L4Zto/5SZFsTzgTBWFR2VVTwkjkC1] X-Originating-Email: [shudesmond2@outlook.com] Message-ID: Content-Type: multipart/mixed; boundary="_253d505f-363b-4857-9c14-3a09b91662dd_" From: Desmond Shu Subject: Proposal Date: Wed, 3 Sep 2014 18:23:40 +0200 X-ASG-Orig-Subj: Proposal Importance: Normal MIME-Version: 1.0 X-OriginalArrivalTime: 03 Sep 2014 16:23:41.0079 (UTC) FILETIME=[6C757270:01CFC793] X-Barracuda-Connect: col004-omc3s9.hotmail.com[65.55.34.147] X-Barracuda-Start-Time: 1409761421 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.21 X-Barracuda-Spam-Status: No, SCORE=1.21 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE, MISSING_HEADERS, TO_CC_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9135 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 1.21 MISSING_HEADERS Missing To: header 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 TO_CC_NONE No To: or Cc: header To: undisclosed-recipients:; --_253d505f-363b-4857-9c14-3a09b91662dd_ Content-Type: multipart/alternative; boundary="_a929280e-9726-40d2-b330-12199cee62f8_" --_a929280e-9726-40d2-b330-12199cee62f8_ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Please go through the content of the attachment and get back to me for mor= e information.Thanks for your understanding=2CDesmond Shu = --_a929280e-9726-40d2-b330-12199cee62f8_ Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable
 =3BPlease go through t= he content of the attachment and get back to me for more information.
=
Thanks for your understanding=2C
Desmond Shu

<= /div>
= --_a929280e-9726-40d2-b330-12199cee62f8_-- --_253d505f-363b-4857-9c14-3a09b91662dd_ Content-Type: application/pdf Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="Energy & Min.Resources Dept..pdf" JVBERi0xLjUKJeLjz9MKNiAwIG9iago8PCAKICAgL1R5cGUgL1hPYmplY3QKICAgL1N1YnR5cGUg L0ltYWdlCiAgIC9CaXRzUGVyQ29tcG9uZW50IDgKICAgL1dpZHRoIDE2NQogICAvSGVpZ2h0IDIx NgogICAvQ29sb3JTcGFjZSBbL0luZGV4ZWQgL0RldmljZVJHQiAyNTUgNyAwIFIgXQogICAvRmls dGVyIC9GbGF0ZURlY29kZQogICAvTGVuZ3RoIDk0NjQKPj4Kc3RyZWFtCnhe5Vxpe9pItn7E5ogl OIAC6aZjQkKC2GIwq5FtBKhnbvAyTtL//6/cs1SVSkICnJ6Z++GeZ6aDpFLVq7O851SpZMP4fymJ Yw2iJJk61iJG0pmzY02i5NWxBlFiZtPHmkRKLpcvHGsTJa+PNYiSfL54fqxNhJjFfD5/rFGEvHn9 K6qEwXIv0WWilMT/5gBj/hc8pfz6V1SJo5HdkidBPS8W8Z8KYswnj7U2DCt0XC6/DZ054UlTNFoV fxaPazRRzOUz+OOcbqsdaw+g3gUO35TLr38LnPntd+OoWDRaGX+CTktHWqPa6/JHPl850txA8/4R OCyH7P2ufAJIthuZsChVGisMDX8V6NcJ4f2m/FZHiSDfJvTjsPWjhMct4H008CHuS/nICv6zHZZU ufy7Zl/S5B/64SkgCyGQuQNtS9Q2b/q3neD0iMryD/DwlXZ4SrCzcgikpqcYSRQUSDbA8UgTQCz/ AI4krvd4dAJtmnkFrXQUpIjpC/h1wfftRU5j7x6G9Yc68I/eh2wvZe9MmgcrgibPWDlGNHOVkHlM 9RwCZHmv3btXoTE+MK7f5G88+F07CDV/8+HdXglSFiAN6WZIQrmLcDPIgrmmbJNLSFKIiJyP5ddB TkkxLjpbFiDR3hJwoPGbD+XXphEW9i1kHnY41FKqUAjnCaQnzPCkylxFuUlxX+lA129facpISWCW BvIPbLYHEiCGHxElKUCaSjdwMlPmaNekJC4ZGfyBNCVu3Nc5quj127MAzRCw178rYK9ff9CVyvKG wigi2AWpoP4yeXRKBJcFXwuFbV5iS8sn+ZRX58LCoysO95GVQz/xx6tAq1fBlMmSP1MgAVk+/8kQ wEODMyJMRzmhPxlxEZ1KNhQjKqWVNZB08Pa1jJt34koksxd5qJQYFMEmsgKGLqZCxL8MlXOiCqE3 Esrb1wnD9749kPhvQngtH36M6C3hp2DSENIenwq35ofB0Ec7F0xFQhFOqQULOOLvCkIYJP/7vuyf j6w1hM0AW0OCNQltIDkmWvJxcqDyJN0C/7JX7jMlynsNjgD3VgPDZ33lloP+GRTWGvIelb7IJ3ji DNH6djwvAnskMxI83ZMSgR6XoQJ4WG9hkCdi9I3YLPC/bMQcgEpl5PDJAiUk1jpat8DYTCbWmBrj nRpbV6d+zj8jHDi6oxRrMsnjYlhwkYExnlMzmEyeq3FunGDXYD5AiSl8E0FEr5W1g05wFKOfrVNy NB7X4PDg4RPEAKDlRD6X44u5Ap1Iq9ZRkghi8kHtgaTDV3tJTggPcs7uhe5GxkbblpA12d4+A9Qo ptK4LMA5ieDH1pTvAyD2QAaDPaIYYhEFZMJI5Xgszj+AonKey5+VBVFTFJczFfEs+Axl1m1LPmQi YgjJfgJH8Mg/Iw7exs10ynIMBFdhw37Gwc0cFY6fuFkin5caA6We42nSbkqQK7rLm1cwTkiCuPZB vtYPylFiySFgrDSPBMfF/OcMocrlNa5MqblCKiNVzdeZPKm2Sn3Qxw+PLJN1oE0Ib0CA2LnGoREL 7Jo1THjlM9IXa06rwlJitgZuWcj7ZJnSKieU9wEKD4/9+pCEAPrGr9EAJkCgGGEPTUvPlEm5gpCY yRGdpHSgoXKV5+x66HwMQdKP0AOUaD91jHxJ83A2YgXUdObrT+ZkGvjzBUEGvSe5EjkTYVSR+YYk Eygy3ukqYb97K8odv0iFX38EQcqfr/7QS1mhBuLKsiC9jMrdKSqIc0gznz/DQepzXqAr8CMIZiIJ TYPflDVBhK/iWCrxx6ugSsNzB+FPZcSZ4DFzkrppElHM5D8niLgp9xD4QpXX04C30j7I/dW1N1KV b387NjUHoALg230i8zWBqVrkRR9jE5cE4UyGMGGhTowFLEmm/yItQRKVGhHj2Wlrz6nfAGc54mlM f4gihmkOx2dKxOorTSRUFCx5Vqyoc6zD8rmGMbIUKr86YSVKycfIWrKsjQHhDXnZYpsXcZJwUUR1 ZUkRF6qyYMJMGNV8SIr709BUXJ6LlX2tJ4qhcTIwTivHIZP6BP6YL8iiO5UTwSJoCp8wF7g5d8LK 1S+IFpssF1wUEZTPnyH3cDQkaMUyTY90xsYvlgIExHIsPH5JwoNUiISKJaxuC+igNKc1jS85xGSk uD6CX5+K6LSpoCZjC/S/JQG3R0mgcnJULGYKxXwGNZMs5r4guBx6aYWiPMlsXsrsgTwtjl8iifAY +TKewYUU+G828wUbZSGYzhtFjDDS0wU8BPAk2f4sowceyrGF7JdLeg9kngOlDL5aJIjc4otRPDs7 u+CkQjYGlI09h86ftOj7QokaJQemhHKSq590RrF6LkdK+4RqtgpElMmI26Mn4H9DLqIGSXKBjlON WpELRXoZIhgIYGIslfLnQKhR97cODvlyKUUNgtVXhiL5E4Atfy4W/VioiiII+SmXy0U5y6G19l+T qEEKXEPKmKoGwjVRYt2mcf10jyRR4ob6GxLONySYnyt0hfhSSDXFrF4tFHNcauxzA3lJ4ggLVbPZ lplKpk5412dQktRLGCHlhCwmBeklTHorV8wXzik1JzjvQEIP0w9P49r7i/q62J2u0evUi8VMf/D1 69fB5XB0NY5t3Wzj7HWPzi0jmQUdlotpgmjmC7xIeYHQWmT9hJXLn59FUANWS+1J+0BuTGSnQ2Ns TGldsTMbzOZXi8vrUVzz1GQySUW4ZTlXAEZvkfYSjITLRDG/ydMSgxmFsWAixsmkHWfw8+Jy6lwa xpAwfr5xZtPZYngV0xowyt4iQrRwQbpAJaIIfj6XsAr0ptvcJzCgSOwV+o0cEjsAf7zpdHrcT2cw c5zhaBirSNVbJTAM/D93gYpI+ZhkvV0B0EQ7kBbRcxP5oGC1fABkNXueC6g/M531Rlfz2Ww2nd5G AU1NuLeEDBKWXI6JTs8l2pwA6kg1zPl56iwfkLR8dJCIIdGBEqkvfvtMbzb4Orwax4aN7K29lxvP 9H4oSeqS+JiPcEaWFPsQyX6JrndSo4kf1NeJ2gIsPphFuqXqDCIxFRpLSyTRVJasRtIrlHmq24MR buAEJA3j5nIXqSYcXQ3vbvdxJvzeJnsg8+h0QIqHhknUSgXOPf4EoqA9e1zsKDnHOqWRy2WAL3lF crgKNQl0Fvb/fKFwFm2tq57brfnaTZqVTyXgeBKqLFJax3GLoSypnDEEJ61+qjTyxWIpahqrYYQo rWaKYpx85iKtJetkrbvu6JtAOsvNZrNctmq1ZExSm7TbAmj7MMqCkdxshEbNYjEXhjlRUdOOikKU ZK1mu31EtNFPdwEhyGZDWLfuPICVDxIJAfMwykQVHrkPKYIrAjMTnA5bbQbYtkhnoXHmi8V6ySBQ OnP9VqPeWQZkE5StUHvqKEqoWhPGZrmGmkCeSlV9JCJoRK3SCg2zCYHwQp13+6EWofZLj3AeSjwk tbWRBsN0QGfarEi6lsCIuq3Z3vLgkJ1N1K4kz/PWa0/IzXYbummDrpayGGUsQ3DXHjrTfpmc8jF2 IgCqwenH3t37Uu2v93ux4YLw+rhS42a5QeNiHXMefm2s6dHe75xvPE2StVJYh343N9gi1TyAEhS0 6YrRQq8luZCin94BQ3ul0gG07hZM2t9z31AX2JI0EmnxJN4MgbbGgyBINgH+OuKMHELbKI9UPCQa 1usxPbgCZKRftmSzLhwEXvy3Jcj15mZ5E9Fzva6rhzqIku6G9bD0iJ8iOgLpb+SI7Yj0JYfZ4DqT 9hQJEXDUJArikjxpbm8EhjiMKAvbpn8hJ/WjukJZyzBtp/YcU6ofKEjnKa0cncd1u+wKA8+9Rbjb fUkmxfPEuM4Gn0NkjhBKV7YBkA3/WsL3j5iQESZUMXdEbpbCNdxOvxZpmGUHoydBSTiYfAABPkGf yMr3WZ7RTBJGLEavu2aN4NjeUaALtjKoEv0yG9mlcGuRI5tKYzXASCZbw3XI9HxWmBohd+HWyOfG JZyu5JXOdh9WSOadDjQmtXtR/bFsllcqYJU2l5t1wvjjz3/AnfQIeE5VJTIuY/rDp4baDID27Vhs e5Ksi8ooptuFZD7SJipq0YHu//Hnn3/+E+83qdaR9R2CDNUwSoT/149aOSQ1W0ZO14jmSyIZhZIV Bdr4558kRrBORo+MozS4qyv98ZR8raQny0sYNhnd93ITKNgBJPLnn1L+EZjKUNBUY2yyBQ1KnWwC Ve4R2WJmqnM9E901CJknxTYlXv/Hn778D7kjCzlnK7ajDW7HTnqYCl+kSpj20CTPE7G+jYqhzVpV jBQ6v/9TSDEL//lk6Otw3joK4430ewKXjF+WiZeagigKh30BN+p2BR9+u/yIb+3f86v7D9VvYm2g 1vXiwhp00d9QzbVZvzRsWNS8BwkztnrjmsUwxrv7+2/qVfiHj8Pb+x3MZYe9Q1VVH5B1e5Smtpvg fOZEqW22/f5igY7Zis3jKJhk7u5RvgmM781vePjwaPglR/gmqAE4+oz51nXB8Cd8wrAvnlzJT/L0 p+9GRzrOjZ/uWW5baOv359/E8b0RPVFYJhPbDltHmDmRrccBOSDuBYdabSvMPtfqB1/QYcf3Sh4u v7x/5z74J0bIL3t3bUH5V5KKWYVe+uYQnEixM1XW5M0GM0Ufsn5ShqJG7xiX4903TS6Lrn54exms pj0O6C1al9Bv+qyMZCbzYq9cW0r9V7aHmVVoFOzjg8ShVovfGuXyuwZGzbuPH0tT+2NDRtC7d+9a j4GE0ALv4Vtd6NP2PEVjnvlSg9er6eBzyVj3dKPj/O5f9/dZtWutXP4y+Ncu5x+Wz77e78ZYF8lb 6n6CCIZKt5R2jZdIN9vMBE5ATkOqudEZcwMl+miHjreSmnu/oONLpckFHiIX+Qlng45DnYUCetvM vijCt2ZI9616qUZJiLRwc4P8CIcrER7fqozp246PB+d8fClCCExeU/UUWiOJS2P1YBasp821cbrY 1WYpMBPyKqI/OdJmi9efVRDvLsHkJcU897drUGvWP0YuUjA3LneWLQU0UcuYldNjJ9kym1n9BLgL Y056WHosPV4Yur7+/ijk+3f3Q+vb4+PzMx9fP7ofM9++f7++Fg2eMUnW1mRne8jdzs1WQBV108ye nB090yzp5XEy++LAO03qZlZH2a2a6ZPrIHyiwLH15dA0+Nel+2Wiz2dAGSercl41TZ397bQVUmQi lUolhOBxMpHQD/0jLtW01qEpcH3S1Ee6Mc30iTYDRaY1zV1lzUqIGhLpHC90Fwo5eoFVkIe0SUYd FGn1D99S46I4Xg2BrJUCBu6WgFVOUuU8bZotraVtTSKezrrgtxNl/sawki/LNxVyU3Ze7rsU712K OXN/JW5tWRlfIRCxZuWkyWK9aZpaw207ImrwXVySYYKy7oCseaMt7nkZ026yXD6H61U/IA/g+6NC 7lPki49axtK7ByOepEpgK7Pqm6BbtdoREfdIrwzT+Br/wjCocCT9ZYzxNb2byeVqWHrcGQlCT68I xxHvGesNq+H3D3x+klcC/5jaSrxnWZFrmnc7GrFKRoWyfMz7fEzj7pleY+Pa5Gr3gL9z/GHhaBf1 LrTWsiw/ojG+zRNYqBVotm5YVvRNq939CgnaKuSo6MX3XrhH/fvOMD4V8C3OA1aTqSK/Ilnd7yK7 gQC32n6Ek4qOZnAPFO67ZKtqWeHQloKl7iPCTCVphgPuZ6QR2hgyM096QKlkhvH1/e4xuhejW7Es HxZq0jy6FoSuW1UZtG5NwhypCaTu3Q+eE15j/iZz7u7v8B+a9PC18fWOCqEYWetjIEcfTW9AXEBA 8sirWJOosJHC0y8an8qfO0L7BId04RkvrH7iz9g9BKDKNFhLDYKqLB3Jb+u0/iRZeMjMIQ8RpdpK /NpRDfwgMKIiucHDgS4Ql6ZKtGTziCptaJOWmpybADKQxfdEzMGeGddPihaoxEnF10K/bP94sdsT S9VoGLfNw2PaJR0kKHLSPuYgXNaOSGfXxogPEDsE0iOp94CpWb5ourCrR+29xuCqiuDuNuDms6N8 8CgM+oD2JRU+CfohNe/2dmLsdrvHgHLRqxpyUFTTYapEmjJLAheE9jFrk9A8B6CgS7L1EflPjqun veb0UPcPGna7OfG9MoMQDo3aoscQ1u5+QWuL5uPxaLRa3QkJ8cn4iVT59FOABOWNduyv+8xzzc+h O2oNSMSqCBOTMQ/Zu4WxLYMbPdLya7bR4+Pdarxa/QWIdmHaGz+j592NRZDDv2M0eYQ3Soz3Orln YKiJMDFGTqDCCcuN6WsymQlbezx6eHoc4W6f8RiUGvK11YqKIzQmeCOcuNuHOJZrRkFNGi0cSnBd N32EhOgpqqw8r4F3hjx4vAKvf7peCYBBnAxKcHjomjG+e3rYPYOriElvIOaJ60QxVCMQ8TuIKSdJ kBQ2io00uXsEoD/uRqCvR4zTkMJG4UJidHcNza6Vg1zvYYQMb/mhw5qKjW/b9J0W8j7cd3zf9nj0 9Ndud7fyB/VVOFrd7XYP369DSr17+nEdPAMF4USFDjtlbHxnNZdEN5lYp64ojFcYTY8jCXU0Anii SDpF5vSmglWZPQgyWddAZgnkCSzpy3j8IBzuHlR7Kj4SojsxGoOMi5wksaRJK1VQmgDIxoum2yPy NoiNB1yJfhHIecXnO6aYTMxMh4JfKNpD/Vvnp4Ec310/U67z1TdaQVA9XMfvlw0JRs5kQuzIPlmN GXpp+iDZ2kfjBkID4f24VjE+XGn5aERM8LiKr3ilZHzv6jKMZXRDdgZavEie000RBCQFQgNCBUjz ScIbj4a3tzMHt03e3l6OfB2unh7uoV5fHdLqDY1HNp5XfF3tiwCJyLwGan8S8zQoELwPyrrjq6+3 tw7IdNpz3d7UIbm9XYyU/Sn+42HWaTwqha5Kh0Cynsl7PXKR9gFNShmvvoLunBn8p+fapeYE7my2 Wm6v56BSncHXr6cEepc4yEKQtSrrKvIlHucjApkiP46dJwoZLhYzZ4BQQH9eGvCZ9GyTCXTTbjcz 6x4qlZ9hNjzYV+0LB0FSgSxFDl47VyCxdoJbvsSDHH9lkwK+datK+ARAJRaca5vVFiBl+w/2618l AiSqReKIHLxbVReF8g9U5ZfgfoCvmm6bAC+MTwOKUBvpqtcBpLfxk52rKvXRnitNpiM5SNAkBk6d 7rDiCBVkMOtAEKYEPmnmfZB0xSJpuM5tbH/MQZQZBcjonCNB1kXiPkSTq5njSWTWxGyVohCClFoN S26CMKvOIN7ezOZIehJHZHiv+RpOgsQd8SAHM6dh8dhWdTpzpvIoIFZzOp311aXmdBbP6nLImiTz aJBZBbLbEHcEruuUMHBcObTpQuxOm/JQF8ucAjVV1aXOAXsLkOZcgYzkv20zneYn6IoxtGbDAMjV YFqSQ1uNKbBMVyHRxLIB5LSiWnrOQBtvnjQ0WsqKRl09Nval3uSrN0ZL3OAr/Gph6D3eDTT7gr0d x1aHmlgugEz7DU1nIOIbH/jKM7SPYTzRyD6sSWnuLFcXEx3kxjM811BAZ7MeNzEpcjuLis9Clv6z 6vR0fprOvnIH2M9waKxdNQLHKtYY9ZNA1nKiXx/kekHbW6QyNc2l0iVvOuu40vxWo9oUv6zSoudM W1VFUJZPQgv8MMKw/T2IEmROlGpHQJY2wkKaT17R/1xXHDkyGqxJdSoyH6d7jPUeu0IbwGNK90Pf 6iqndGFiEniPKHzSSnvFl4EU0Z0Uz+vaotuvsyk3sSrmAvMySo81lurNerjP2zJLPXHFWZi82cqq TCVT1sRmUqMvRpeaTG9KZvoXQBp9F/+7WMsOv0qXtBoQoQgDC4iRCxrD/fm4A9SquHOoj0iGRk1w mjmVkWPYfZrkreW+baXJwyBFYW5Wt40wyDU+truVWXLmdEzRpV1DVTqz6aWBhb+NzprypnaqnoCH ofLHGcIFhmD2HLW6skD7zDfywbPysevpU8xt1iVIuXnAXt7AYw9VuTGQcWO2nN4cCRtyDgybAIfE K+50Wkv1sB16ZQ+qYAmh44jw7lIUzt2lDB0ZeG0F46Amza0yt4CF+y/IhTi6x7eCuyHtzZyWS6qc lRyn1nM6eKEJQe0CA7C13ZIz6wnNZ2XkDNEq9jLbl0wpQFppyUDRabEl9ZytiBtUPdmnPZ3GXATO YCaC25zNOlaWnbLZgswzo7JwgvTu2I0pgeya7mzGW7jNtdQkZgfDXW5dObqogqxK6SDImgRZrYdB GhuMnbn0H0eAtGoQ5maa7D0tmZmeTJZWCUpNs0ogHagnpwIkkLskStz6P1ehKIpeaFGvSpCRqycy Z5ppnhXBvEiBrF3hfhShyJGkSXBJDAmmmhKUtz5tw0+IIjzfaWO7ZEqCFBxko6HnqrCtSS5VcRNd 9NaUousy33LdaTPW/lL4j+JyCNa0KIMQ5CQoAA0ViY/RdGyTQc4kSMPt8Kjs5y3JpMolY0AqRWel 1YRb0Nbl+VZOcCVIKBhmKbTtIZBE+6ao5TRNGostGqZb5ycXxrNKNxJE9PujWkZer0rGECywwF3V 846s1iRI03OmtM39IEhs0XRm5wKkWL0EgPgB2LAvNvHKEW+UplrREyzFUNUb+VxM33P65stQBYbj 8CrM2ulRu94BkNQCil/PZJAiupkeh/ZaZEcR3M2tb04jUjxTNajQPWrBqr/duPCPKFrGzqyP10GT VJ9b5JT7IClwuILvOQzSVrUaPu/CVbWaKMwrWR+DESnKHUxPzMTk0l/tZgm9JV0O7/GA8gqCpHhg le2DRF/lFtaC4gd0L0FeQUIy+jc3shKS8zBfUTFLPC2l6irXXRNTRpiLmXbbF8lbgLRqCw6gEqbF PZAQygCS10KaLlGQeaNy97qHWdEVR12mSY0lo4NbrbOgiBrDX45GnlzKLmHSTXrx2CVTxhyKRn+a IAU80emmsDK3Kj3WeW8g35C5+FGGmpHw1M9q+MaMnalqThmYeXNpYa+lbUBvOHKa/jHTvYWR6E33 ME6sHmir1wH0puk4SPRWz3kWfcyFOzJOLlisrK+m2LcPPsgS85YlNum4qPsrV7aDopee3CsRVFBj Qk3edKkiEaCOrWbXo+6mjlLeArvuirzIvmL61o4HaasmshISi3/zjmAKHuJKGtfCmgE9D8waATI1 p5yzBkvTdAwYaKD3A9zG2y1aFbqc3jbl+PGbUjWnbGU5j3FivOpzHS3n3o4/47c4Q0+1L0p8oQpj upbXrJasL7ifhb0Ur24oKZqatQ/sV/D9Nl3nhTWxZjV3667hOzprhwdudpBpotZZrPSU6NwvO25U EYS9rde2y0dUdlmmKi6CG/pC4vmtlrweJnc/bbbulVGTJeodF7c8csrF6WLE6gAreZHyr0xnl2Kk Tc24usE+UZJizXatRj+0jdIvhMDe3LdI3952XTM2cqfw0JlqVVkPSnDH15cSC9NlT7M2cJJ4ytrN DX5EJBjOZgLSwiZ6mVeIKpTM9A2rUmYnLKXVrAmcUs6tsFJb9EBleyCJzHs9p6dA2v6ClbtOGgtJ afyKMO0r8vDOINtvV+Iigt9KkjPaS/WqfOCISe3EakN0oFsu9kDCrGG6wDpIXlHTMPzEknTKMGnF RFdk1MthXzR7i9JXvPFGlPO1IrkhFIgCShocEtcBpiGMuBzp9MAtVS5qTgeqgzl9U2cTUrtB/fhW PLZ7SW9JC10W7/cc0sTJbwe5WlgREve0XZrOpmKWIgVIceZ4KUctUELBoS1PojuKz1HZ2p6mnyMv h21dleRmvJOoJosq4flf1SoqaLIHaRq8NAgSayMn3e75mnSdy0AftkvhUaN9FKamnvg38ixJv6Az W5QbReis+1SoXcnJ2EAmnUYHggjXKKWXCgGXdDyYjc0khVanA4Eui//aC5ddnKLfymoDH32Bbftt mSvlC3273x/iB2mi3e1szWND0QD2NLs039GkMXWgBVS+cinTVUtqOLuBAkPoi7Y2mEufoo/u+jO6 fmoSZYbM9S765Vp+WPjVmfE6Of49Cwgis2YHMqPVtGs4S5Of3AJJOorJAaS7EVVtl2Y/dc3N4t4i +5LUfMOsY3So1Rb84+L+14+OKLrb7rzWhjBJGgkdZDNlJPF67YpzkaZImBzDf2SnaBBtJmuetF12 XlGliFnagrasj6R+9icf5KUzpYQH5nbSkHagJtNeQcAJetVTdZjMrfRMVGlXYkGNvgqG0MYNcaY/ STycEpXoD5WlyBOlr1xbEgthDidwhOdClEG95vkGxzm5c24hodPZ9loqUjp1y+XRcICMFjXHNk+y 2PpTYV1pCd5abNZkI2YOVCUGuNVFosQFtpkW3zBJg/IN0xHNckxTlrs1Xriw+1wH4BYpK61HTeWo R5LYpm/wLMaOxRkg2d/0EeBCqHRAVQUuR82qFtKi/t6khwssoF9xsjcTRN7d4LTT9RaUI7oU2jr9 HA9tlm7GBwneAt18EHe6fQjMpJzjjcRq/tqB2TU64cwvhU0qMREqNoEncMTyCi5Z2JuN6OKGAlN3 sJM8EsWvfUH7SJbWF8Hh+Jdz3HVHtLukbAKWRsMjEJV0gMOdEq354YQSq18Z2pslml3MjYk9zLVa SIP/H/+DA0K6Xk2BbOJCQbM1968uqEgnmU3RmBjCLVBlx+kLPkd0wDwwXXDQbRs+RmPhVymg0ozZ Diiy1Drp8wyS5NyzM1UMoHS6tKx7GkSQrjqEGRm5ZRa9E5BNTY5vqCWmH9EDHJwqWe5ArKVdGWrR S/Qwt7PLKqkwXcpk6zGrVLGS8LxWq5X1PP3rj25fxh6PMiS3tKwFciLGDgWC1ZpOIZ836V0EBvog iAzmdVqfKa+VhZGCA/2CjFc78f6l6/Z5hifev3wdTFu4PQDKXrcFE9GpDXTjTb20VV3gmxSLFtBF PqR7ajeemNoYq4NbhY7L/cPPkRTce6b29HQ3a/yzSir1QKKpIg95vekSyYaWI3GTyLTjem102OlU sM8C+cvdbuR0bry7p81Fo7GQ1eFN83uifWgsRV6yiYLUfGdAnA6oJjK0J4Sz3cYTiFGyzwY/k7b9 j81VzzuWiN3eR+RxD2TwMftrqY8B6TJaTCjZZRXZVRUUi/9lppTw1s/jon2jLSSwYcbeqDC4dZy9 dT+BsQoYZWDP+RWllNV9WML7bE+Qu71O7veswTjHtzO9ttAwlqayGr+SjyRlH+MvKDJKlTJ45Pqa KBZw6ReYyApjBCaSepSVU1cGdoQKlNO/REYR/QiUyeFiuQWQ8u+UjKAucwOBAxAn3nSqHgv/vsLc VUsgEXo89q1JjOzudSEiUnvwr/rrBUaPPARd9tQiAIrZcB1J4liZdY2Oq5wyCuMveCRKgIbuhGZ9 +r3CNWWVxgBlR1uRhppCS9g1FyjSd8sVPb76wOA+1PHLRKOhO+Wj+iapRaemlgNxi510TMvyYCIu MQ6NpKv/VSr5fUQA468ZG0XFzoqoly0e6m4hUY6AinoNhGk21o6j5oaunqgNGTPjIE++MNfown9R 4B4SN6awkej/h96ktfXp7yvkSLcKhcXUURRurJfLQPn1qB77zv+kZJ/dXiDs4ZC/CePomf3yWV2/ Gi6X674rS6MReOa004NYl2qEEhlaaMZm/T3fU8WiLPWrDsnCnx+ip7Mvfg93WttuN2u1ScG4HODO NbXCl1wv7b7rEzk/5G5l/CCUu79GUR70YpHBQ/0gWP6kRvvkJznvr32Tjwe3/ibo+dp2tYJ5zJ39 Zazoj7lgl+OHYGe/KIwR9Ygfnu6kC+z0p79aL9eKjJR71RYbW59WyU9xfoi+IA/SP7+UakJCkIzR Ck1PSpLKDezYTA61uQvJ0K3pkypJ4OMn+riNEP+4/zdhlB+nUQbC7yUff95LOf65gBSVq3fol3Sf RH3s1hOFbDIec+ryIaKEvxSLlLGWXIDEKQrHMoqO3XyyCKrY4XdgQic7mdkfjoXmnSKaZ3zC7xQ0 Y2P089+LUaIcG3cKGwz+L/ETiCTuvvHqSS9TkL3J3qBQsvbfSDQRQmM8qs8OaTYCjKwBCE/98DOT sJAfjrTyKnqwXxYK6R/S239QxvxrHFW7xsuOHvbZ+CFPHBv0xUL1lfzocGyMn9G9ogrDsDys/hK/ dqTEnbzr73P4vox9K/00ODbVmf2phi8//PJ5Rdxwx19Un85fLxI57I6+GfIFY+E5UMPSZYh7yno+ Jf7Q5jancNcvyZ0cKzCRAiv+BCXtqJS/Qw3fkaKFvuG8VOVOTZx+Hhvqb4goMJ9Iq4opUVNPTKE7 CjGs5eCc8Z18BOoJiW0l9H2MW/+m+Cq8Ft8Yc8J8EE7LtjXu8cigp6IZVsBpH/5jppYykuONxMiP lEIAyg86IKMb+KU3kek95QB96vnw9yrcE0Xajsd94FmlmKlB+Y54DLL6yKDSCdx15KvyP2xpX661 2L4jJWF+Y5ckpRlUKt4Zz1TzjH2C/U9wY5xon7zLPzHxA01LufiOUwnR9liz8wu+Uv53ySoQC6MV 1WBPxiPRDP5pIDi70hcQ/zu+GJbxStcS6fRfYFksLJ6eQknoP5VfTpHRYxBntOwi/kbCf1fww98D +HbXJxXv/wUZX39/2O2CWOH4r8f/QyNHyhhmBLLQfRzh33b492nwfwHHoopyCmVuZHN0cmVhbQpl bmRvYmoKMSAwIG9iago8PCAKICAgL1R5cGUgL0NhdGFsb2cKICAgL1BhZ2VzIDIgMCBSCiAgIC9Q YWdlTGF5b3V0IC9PbmVDb2x1bW4KICAgL1BhZ2VNb2RlIC9Vc2VOb25lCiAgIC9PQ1Byb3BlcnRp ZXMgPDwgCiAgIC9EIDw8IAogICAvT3JkZXIgW10KICAgL0FTIFs8PCAKICAgL0V2ZW50IC9WaWV3 CiAgIC9DYXRlZ29yeSBbL1ZpZXcgXQo+PiA8PCAKICAgL0V2ZW50IC9QcmludAogICAvQ2F0ZWdv cnkgWy9QcmludCBdCj4+IDw8IAogICAvRXZlbnQgL0V4cG9ydAogICAvQ2F0ZWdvcnkgWy9FeHBv cnQgXQo+PiBdCj4+Cj4+Cj4+CmVuZG9iagoyIDAgb2JqCjw8IAogICAvVHlwZSAvUGFnZXMKICAg L0tpZHMgWzMgMCBSIF0KICAgL0NvdW50IDEKPj4KZW5kb2JqCjMgMCBvYmoKPDwgCiAgIC9UeXBl IC9QYWdlCiAgIC9QYXJlbnQgMiAwIFIKICAgL1Jlc291cmNlcyA8PCAKICAgL1Byb2NTZXQgWy9Q REYgL1RleHQgXQogICAvWE9iamVjdCA8PCAKICAgL0ltZzEgNiAwIFIKPj4KICAgL0ZvbnQgPDwg CiAgIC9GMSA4IDAgUgogICAvRjIgMTEgMCBSCiAgIC9GMyAxNCAwIFIKICAgL0Y0IDE3IDAgUgo+ Pgo+PgogICAvTWVkaWFCb3ggWzAgMCA2MTIgNzkyXQogICAvQ29udGVudHMgNCAwIFIKPj4KZW5k b2JqCjQgMCBvYmoKPDwgCiAgIC9GaWx0ZXIgL0ZsYXRlRGVjb2RlCiAgIC9MZW5ndGggNTc5MQo+ PgpzdHJlYW0KeF61XVuz5ERyfj+/Qg820YqlG1WV1FLvk8GAgdj1Xjx+2PD6YbgcGDO9HIYZ2vx7 V96zSjqnZ6rHQXBo3bKysvLyZVZK/Hz3c/4ndEP+J3RhHLsY0iEdu2/Od2mcD8OIl9JpPoz0M1/4 6Mvz96H79Ke7v+R/fr775NndR5+H7nQY5yl0z+7vBrzx1fd3w+F0WoT4cTmEYzdnoiF2z853/7X7 rA/D7t/7QD/+Cn/+rY/D7m/9Pu26fh+n3Qd9iLvuj/28+7IPY3Xzx/mWZfeHDg/w9H/0+/z3T/n2 /+z3I931r/0oF/+7e/bV3WfP3oXrmJbDVLLdtdDh2ad0OC5E5qs+HZHVLz6G+cLUaHoN1EM4HaZY kG+abYhTTeeTLORTFmf0K/RhE/FpOSxLQfwWUcZBJpoVQ5f8WdaA3RcdivTz/JuVALUHNOHjPsbd oWXYMJ7AHHTcDd5jXohDXK6yPhwPi5jAcXcGlp5nhuPuxcvfr6mma1TDMGR6juoGayWRQ8z/HjcI JTBzR+lbZOu7Psy7X/ops5pl+VMWa9j9oz/B1fwLLvyQj97g0b/kv8fdQz7+CZ/9pY/H3eusREMW +37afQO0iMT5Gpsbc435esni1ck+ug7HU3JGnXnr+jCh45n159ucfPfxwxAPcSwY+LSFTBgOJRW3 UvtqqRrIj1NWFE9+30QF7caTqTVm3L18gRrya59CnkO2XdaV/OsWXRkPw1Itc6vRHueTuq0/gzf5 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 aaDzU0iWDLPAU67uZ4VwhWqzts4Ro+16Mc/Qm8/+K3A9s4pgGx/bvU4fPkJbDaCQiwBFXXyNG5/x I0UygKIwm31BFofzG0Rk5d5JkTRw2GW8UL9q7MLOo6+kwX2qrq5oaUizRszgobbfgnOKb2bilt/q YVUaIfu+fNLqd0XdVYriocgy3o9TOeK23bt5FYOAg3sXegjSYbrXuj4ScpFfCjMF6uSHH9mL9nhc DykcJ9+DF3lHWHUEReNB18UkVgnQA+dH2HBfF/Z4ql533X1i5ZvkQlFq43nosEPYVYmq5xvbcWiG YmoFHGIEawkCkuMQ+9oBf+QCPu30IN1AZAoE7Np1aDpqMaQKBeganQ6X6n/2ZuaSDafk6rMNaFqr WJGc0CmcImmgmvl2A1316pT19RBrpaFJj4FIs7LBVFS6rS9XvM3TqYvzIG3fsFnwRSi/DE2rmZYJ Pq7h6ZhP3YRcVS2541r9RtmmduhiYGP0Mt1Y41e6LiBITKmbK8WsruOk1TJkW/zR1id2WAnRsqr6 i1nwejONdI9UMfFLj6SGT3wTzNxVw9xiwDf0/OTc53Iv+m1MW4fyO87b8+gEMYcoH7qo+hDZ2XHI eig1Wzp/mkqtaR7r5WqSDK96mrSUVe7o2nei6cOPVppx1m8w31B00ychw5itq+Cm7UPyI3ZHezq3 CCeOWpaD/zPPK9PXFqI5URmWgqh9tQwEfbYgTl/fpW1MdAzNnysGabgRmxhnaYSkX2L/rPq62T7w N7XRQ32ANrL9KbO94KiXZobyLbNUpKSsglJZoNjVwH0csJfEs98khTjQ+jk6n/bRf10CDYNRIHXJ rb8wLt+WLL4wnqSVxlB24zc7B/xA9dW5XvnfbKRhBufyGJm/3P0fuIKTlgplbmRzdHJlYW0KZW5k b2JqCjUgMCBvYmoKPDwgCiAgIC9Qcm9kdWNlciA8RkVGRjAwNjQwMDZGMDA1MDAwNDQwMDQ2MDAy MDAwNTYwMDY1MDA3MjAwMjAwMDM3MDAyRTAwMzIwMDIwMDA0MjAwNzUwMDY5MDA2QzAwNjQwMDIw MDAzMzAwMzcwMDMwMDAyMDAwMjgwMDU3MDA2OTAwNkUwMDY0MDA2RjAwNzcwMDczMDAyMDAwNTYw MDY5MDA3MzAwNzQwMDYxMDAyMDAwNDIwMDc1MDA3MzAwNjkwMDZFMDA2NTAwNzMwMDczMDAyMDAw NDUwMDY0MDA2OTAwNzQwMDY5MDA2RjAwNkUwMDIwMDAyODAwNTMwMDUwMDAyMDAwMzIwMDI5MDAy MDAwMkQwMDIwMDA1NjAwNjUwMDcyMDA3MzAwNjkwMDZGMDA2RTAwM0EwMDIwMDAzNjAwMkUwMDMw MDAyRTAwMzYwMDMwMDAzMDAwMzIwMDIwMDAyODAwNzgwMDM4MDAzNjAwMjkwMDI5PgogICAvQ3Jl YXRpb25EYXRlIChEOjIwMTQwNzExMTQwODIxKzAyJzAwJykKPj4KZW5kb2JqCjcgMCBvYmoKPDwg CiAgIC9MZW5ndGggNzY4Cj4+CnN0cmVhbQoAAAD///////j///H//+H//7z/9KD//6H//6z//8n/ 457/95j/+pT/+Jj/+Zj/7pj//6P//9X/+6///5j//6///8j/8Jj//77//93//6L//7f//8L/1pn/ /97//6T//6n//7v//7b//8r//73/96H/76//+pj//6j//7//5Lf/wpr/8sj/x6b/yJrKwqLB4qva 57T/7tfe/+H//+36//3//8fxs53nr6//79D/3sGs/63/x5TfqaH/0Ziy1pq4/7vI/8r/2K3/1KL/ v5j/yJj/3qr/n6f/5tz/vbL/yOi895mY8JiU+pSY+Jiq/qug/6CY/5ig+6ig/6ig96CY96CY/6AA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKZW5k c3RyZWFtCmVuZG9iago4IDAgb2JqCjw8IAogICAvVHlwZSAvRm9udAogICAvU3VidHlwZSAvVHJ1 ZVR5cGUKICAgL0ZvbnREZXNjcmlwdG9yIDkgMCBSCiAgIC9CYXNlRm9udCAvR2VvcmdpYS1Cb2xk CiAgIC9GaXJzdENoYXIgMAogICAvTGFzdENoYXIgMjU1CiAgIC9XaWR0aHMgMTAgMCBSCiAgIC9F bmNvZGluZyAvV2luQW5zaUVuY29kaW5nCj4+CmVuZG9iago5IDAgb2JqCjw8IAogICAvVHlwZSAv Rm9udERlc2NyaXB0b3IKICAgL0ZvbnROYW1lIC9HZW9yZ2lhLUJvbGQKICAgL0FzY2VudCA3NTYK ICAgL0NhcEhlaWdodCA3NTYKICAgL0Rlc2NlbnQgLTIxNwogICAvRmxhZ3MgMjYyMTc2CiAgIC9G b250QkJveCBbLTE5MCAtMzAzIDEyOTUgOTg5XQogICAvSXRhbGljQW5nbGUgMAogICAvU3RlbVYg MTY1CiAgIC9YSGVpZ2h0IDQ5OAo+PgplbmRvYmoKMTAgMCBvYmoKWzEwMDAgMTAwMCAxMDAwIDEw MDAgMTAwMCAxMDAwIDEwMDAgMTAwMCAxMDAwIDEwMDAgMTAwMCAxMDAwIDEwMDAgMTAwMCAxMDAw IDEwMDAgMTAwMCAxMDAwIDEwMDAgMTAwMCAxMDAwIDEwMDAgMTAwMCAxMDAwIDEwMDAgMTAwMCAx MDAwIDEwMDAgMTAwMCAxMDAwIDEwMDAgMTAwMCAyNTQgMzc2IDUxMCA3MDMgNjQxIDg3OSA3OTkg MjY5IDQ0NyA0NDcgNDgyIDcwMyAzMjggMzc5IDMyOCA0NzIgNzAxIDQ5MCA2MjYgNjI1IDY0OSA1 OTkgNjQ4IDU1NCA2NzYgNjQ4IDM2NyAzNjcgNzAzIDcwMyA3MDMgNTQ4IDk2NyA3NTggNzU3IDcx NSA4MzQgNzIxIDY3MSA4MDcgOTEzIDQ0NiA1OTUgODE3IDY4NiAxMDIzIDgzOSA4MjAgNzAxIDgy MCA3OTcgNjQ5IDY4NCA4MzMgNzYyIDExMjYgODA5IDczMiA2ODkgNDQ3IDQ3MiA0NDcgNzAzIDcw MyA1MDAgNTk2IDY0NiA1MzEgNjYzIDU3MiAzOTMgNTc3IDY4MCAzNTQgMzQ2IDYzMiAzNDQgMTAx NiA2OTAgNjM2IDY1OCA2NDggNTIwIDUxMyAzOTcgNjc3IDU2NyA4NjMgNTg4IDU2MiA1MjUgNTAw IDM4OCA1MDAgNzAzIDQzOCA3MTUgNDM4IDI2OSA1NzkgNTE5IDk0MiA0ODIgNDgyIDUwMCAxMzA5 IDY0OSAzOTYgMTEwMSA0MzggNjg5IDQzOCA0MzggMjY5IDI2OSA1MTkgNTE5IDQzOCA3MDMgOTI4 IDUwMCA5NDcgNTEzIDM5NiA5MzggNDM4IDUyNSA3MzIgMjU0IDM3NiA2MDUgNjkwIDcwMyA3MzIg Mzg4IDU2MyA1MDAgOTQyIDU1MiA2MTAgNzAzIDM3OSA5NDIgNzAzIDQyMCA3MDMgNTUyIDU1MiA1 MDAgNjY4IDU0OSAzMzggNTAwIDU1MiA1NTIgNjEwIDEwNzEgMTA3MSAxMDcxIDU0OCA3NTggNzU4 IDc1OCA3NTggNzU4IDc1OCAxMDcwIDcxNSA3MjEgNzIxIDcyMSA3MjEgNDQ2IDQ0NiA0NDYgNDQ2 IDgzNCA4MzkgODIwIDgyMCA4MjAgODIwIDgyMCA3MDMgODIwIDgzMyA4MzMgODMzIDgzMyA3MzIg NzA4IDY1OCA1OTYgNTk2IDU5NiA1OTYgNTk2IDU5NiA4NTcgNTMxIDU3MiA1NzIgNTcyIDU3MiAz NTQgMzU0IDM1NCAzNTQgNjM4IDY5MCA2MzYgNjM2IDYzNiA2MzYgNjM2IDcwMyA2MzYgNjc3IDY3 NyA2NzcgNjc3IDU2MiA2NDUgNTYyIF0KZW5kb2JqCjExIDAgb2JqCjw8IAogICAvVHlwZSAvRm9u dAogICAvU3VidHlwZSAvVHJ1ZVR5cGUKICAgL0ZvbnREZXNjcmlwdG9yIDEyIDAgUgogICAvQmFz ZUZvbnQgL1RpbWVzTmV3Um9tYW5QUy1Cb2xkTVQKICAgL0ZpcnN0Q2hhciAwCiAgIC9MYXN0Q2hh ciAyNTUKICAgL1dpZHRocyAxMyAwIFIKICAgL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcKPj4K ZW5kb2JqCjEyIDAgb2JqCjw8IAogICAvVHlwZSAvRm9udERlc2NyaXB0b3IKICAgL0ZvbnROYW1l IC9UaW1lc05ld1JvbWFuUFMtQm9sZE1UCiAgIC9Bc2NlbnQgNjc3CiAgIC9DYXBIZWlnaHQgNjYy CiAgIC9EZXNjZW50IC0yMTYKICAgL0ZsYWdzIDI2MjE3NgogICAvRm9udEJCb3ggWy01NTggLTMw NyAyMDAwIDEwMjZdCiAgIC9JdGFsaWNBbmdsZSAwCiAgIC9TdGVtViAxNjUKICAgL1hIZWlnaHQg NDU3Cj4+CmVuZG9iagoxMyAwIG9iagpbNzc4IDc3OCA3NzggNzc4IDc3OCA3NzggNzc4IDc3OCA3 NzggNzc4IDc3OCA3NzggNzc4IDc3OCA3NzggNzc4IDc3OCA3NzggNzc4IDc3OCA3NzggNzc4IDc3 OCA3NzggNzc4IDc3OCA3NzggNzc4IDc3OCA3NzggNzc4IDc3OCAyNTAgMzMzIDU1NSA1MDAgNTAw IDEwMDAgODMzIDI3OCAzMzMgMzMzIDUwMCA1NzAgMjUwIDMzMyAyNTAgMjc4IDUwMCA1MDAgNTAw IDUwMCA1MDAgNTAwIDUwMCA1MDAgNTAwIDUwMCAzMzMgMzMzIDU3MCA1NzAgNTcwIDUwMCA5MzAg NzIyIDY2NyA3MjIgNzIyIDY2NyA2MTEgNzc4IDc3OCAzODkgNTAwIDc3OCA2NjcgOTQ0IDcyMiA3 NzggNjExIDc3OCA3MjIgNTU2IDY2NyA3MjIgNzIyIDEwMDAgNzIyIDcyMiA2NjcgMzMzIDI3OCAz MzMgNTgxIDUwMCAzMzMgNTAwIDU1NiA0NDQgNTU2IDQ0NCAzMzMgNTAwIDU1NiAyNzggMzMzIDU1 NiAyNzggODMzIDU1NiA1MDAgNTU2IDU1NiA0NDQgMzg5IDMzMyA1NTYgNTAwIDcyMiA1MDAgNTAw IDQ0NCAzOTQgMjIwIDM5NCA1MjAgMzUwIDUwMCAzNTAgMzMzIDUwMCA1MDAgMTAwMCA1MDAgNTAw IDMzMyAxMDAwIDU1NiAzMzMgMTAwMCAzNTAgNjY3IDM1MCAzNTAgMzMzIDMzMyA1MDAgNTAwIDM1 MCA1MDAgMTAwMCAzMzMgMTAwMCAzODkgMzMzIDcyMiAzNTAgNDQ0IDcyMiAyNTAgMzMzIDUwMCA1 MDAgNTAwIDUwMCAyMjAgNTAwIDMzMyA3NDcgMzAwIDUwMCA1NzAgMzMzIDc0NyA1MDAgNDAwIDU0 OSAzMDAgMzAwIDMzMyA1NzYgNTQwIDMzMyAzMzMgMzAwIDMzMCA1MDAgNzUwIDc1MCA3NTAgNTAw IDcyMiA3MjIgNzIyIDcyMiA3MjIgNzIyIDEwMDAgNzIyIDY2NyA2NjcgNjY3IDY2NyAzODkgMzg5 IDM4OSAzODkgNzIyIDcyMiA3NzggNzc4IDc3OCA3NzggNzc4IDU3MCA3NzggNzIyIDcyMiA3MjIg NzIyIDcyMiA2MTEgNTU2IDUwMCA1MDAgNTAwIDUwMCA1MDAgNTAwIDcyMiA0NDQgNDQ0IDQ0NCA0 NDQgNDQ0IDI3OCAyNzggMjc4IDI3OCA1MDAgNTU2IDUwMCA1MDAgNTAwIDUwMCA1MDAgNTQ5IDUw MCA1NTYgNTU2IDU1NiA1NTYgNTAwIDU1NiA1MDAgXQplbmRvYmoKMTQgMCBvYmoKPDwgCiAgIC9U eXBlIC9Gb250CiAgIC9TdWJ0eXBlIC9UcnVlVHlwZQogICAvRm9udERlc2NyaXB0b3IgMTUgMCBS CiAgIC9CYXNlRm9udCAvVGltZXNOZXdSb21hblBTTVQKICAgL0ZpcnN0Q2hhciAwCiAgIC9MYXN0 Q2hhciAyNTUKICAgL1dpZHRocyAxNiAwIFIKICAgL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcK Pj4KZW5kb2JqCjE1IDAgb2JqCjw8IAogICAvVHlwZSAvRm9udERlc2NyaXB0b3IKICAgL0ZvbnRO YW1lIC9UaW1lc05ld1JvbWFuUFNNVAogICAvQXNjZW50IDY5MwogICAvQ2FwSGVpZ2h0IDY2Mgog ICAvRGVzY2VudCAtMjE2CiAgIC9GbGFncyAzMgogICAvRm9udEJCb3ggWy01NjggLTMwNyAyMDAw IDEwMDddCiAgIC9JdGFsaWNBbmdsZSAwCiAgIC9TdGVtViA4NwogICAvWEhlaWdodCA0NDcKPj4K ZW5kb2JqCjE2IDAgb2JqCls3NzggNzc4IDc3OCA3NzggNzc4IDc3OCA3NzggNzc4IDc3OCA3Nzgg Nzc4IDc3OCA3NzggNzc4IDc3OCA3NzggNzc4IDc3OCA3NzggNzc4IDc3OCA3NzggNzc4IDc3OCA3 NzggNzc4IDc3OCA3NzggNzc4IDc3OCA3NzggNzc4IDI1MCAzMzMgNDA4IDUwMCA1MDAgODMzIDc3 OCAxODAgMzMzIDMzMyA1MDAgNTY0IDI1MCAzMzMgMjUwIDI3OCA1MDAgNTAwIDUwMCA1MDAgNTAw IDUwMCA1MDAgNTAwIDUwMCA1MDAgMjc4IDI3OCA1NjQgNTY0IDU2NCA0NDQgOTIxIDcyMiA2Njcg NjY3IDcyMiA2MTEgNTU2IDcyMiA3MjIgMzMzIDM4OSA3MjIgNjExIDg4OSA3MjIgNzIyIDU1NiA3 MjIgNjY3IDU1NiA2MTEgNzIyIDcyMiA5NDQgNzIyIDcyMiA2MTEgMzMzIDI3OCAzMzMgNDY5IDUw MCAzMzMgNDQ0IDUwMCA0NDQgNTAwIDQ0NCAzMzMgNTAwIDUwMCAyNzggMjc4IDUwMCAyNzggNzc4 IDUwMCA1MDAgNTAwIDUwMCAzMzMgMzg5IDI3OCA1MDAgNTAwIDcyMiA1MDAgNTAwIDQ0NCA0ODAg MjAwIDQ4MCA1NDEgMzUwIDUwMCAzNTAgMzMzIDUwMCA0NDQgMTAwMCA1MDAgNTAwIDMzMyAxMDAw IDU1NiAzMzMgODg5IDM1MCA2MTEgMzUwIDM1MCAzMzMgMzMzIDQ0NCA0NDQgMzUwIDUwMCAxMDAw IDMzMyA5ODAgMzg5IDMzMyA3MjIgMzUwIDQ0NCA3MjIgMjUwIDMzMyA1MDAgNTAwIDUwMCA1MDAg MjAwIDUwMCAzMzMgNzYwIDI3NiA1MDAgNTY0IDMzMyA3NjAgNTAwIDQwMCA1NDkgMzAwIDMwMCAz MzMgNTc2IDQ1MyAzMzMgMzMzIDMwMCAzMTAgNTAwIDc1MCA3NTAgNzUwIDQ0NCA3MjIgNzIyIDcy MiA3MjIgNzIyIDcyMiA4ODkgNjY3IDYxMSA2MTEgNjExIDYxMSAzMzMgMzMzIDMzMyAzMzMgNzIy IDcyMiA3MjIgNzIyIDcyMiA3MjIgNzIyIDU2NCA3MjIgNzIyIDcyMiA3MjIgNzIyIDcyMiA1NTYg NTAwIDQ0NCA0NDQgNDQ0IDQ0NCA0NDQgNDQ0IDY2NyA0NDQgNDQ0IDQ0NCA0NDQgNDQ0IDI3OCAy NzggMjc4IDI3OCA1MDAgNTAwIDUwMCA1MDAgNTAwIDUwMCA1MDAgNTQ5IDUwMCA1MDAgNTAwIDUw MCA1MDAgNTAwIDUwMCA1MDAgXQplbmRvYmoKMTcgMCBvYmoKPDwgCiAgIC9UeXBlIC9Gb250CiAg IC9TdWJ0eXBlIC9UcnVlVHlwZQogICAvRm9udERlc2NyaXB0b3IgMTggMCBSCiAgIC9CYXNlRm9u dCAvQXJpYWwtQm9sZE1UCiAgIC9GaXJzdENoYXIgMAogICAvTGFzdENoYXIgMjU1CiAgIC9XaWR0 aHMgMTkgMCBSCiAgIC9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nCj4+CmVuZG9iagoxOCAwIG9i ago8PCAKICAgL1R5cGUgL0ZvbnREZXNjcmlwdG9yCiAgIC9Gb250TmFtZSAvQXJpYWwtQm9sZE1U CiAgIC9Bc2NlbnQgNzI4CiAgIC9DYXBIZWlnaHQgNzE2CiAgIC9EZXNjZW50IC0yMTAKICAgL0Zs YWdzIDI2MjE3NgogICAvRm9udEJCb3ggWy02MjggLTM3NiAyMDAwIDEwMThdCiAgIC9JdGFsaWNB bmdsZSAwCiAgIC9TdGVtViAxNjUKICAgL1hIZWlnaHQgNTE5Cj4+CmVuZG9iagoxOSAwIG9iagpb NzUwIDc1MCA3NTAgNzUwIDc1MCA3NTAgNzUwIDc1MCA3NTAgNzUwIDc1MCA3NTAgNzUwIDc1MCA3 NTAgNzUwIDc1MCA3NTAgNzUwIDc1MCA3NTAgNzUwIDc1MCA3NTAgNzUwIDc1MCA3NTAgNzUwIDc1 MCA3NTAgNzUwIDc1MCAyNzggMzMzIDQ3NCA1NTYgNTU2IDg4OSA3MjIgMjM4IDMzMyAzMzMgMzg5 IDU4NCAyNzggMzMzIDI3OCAyNzggNTU2IDU1NiA1NTYgNTU2IDU1NiA1NTYgNTU2IDU1NiA1NTYg NTU2IDMzMyAzMzMgNTg0IDU4NCA1ODQgNjExIDk3NSA3MjIgNzIyIDcyMiA3MjIgNjY3IDYxMSA3 NzggNzIyIDI3OCA1NTYgNzIyIDYxMSA4MzMgNzIyIDc3OCA2NjcgNzc4IDcyMiA2NjcgNjExIDcy MiA2NjcgOTQ0IDY2NyA2NjcgNjExIDMzMyAyNzggMzMzIDU4NCA1NTYgMzMzIDU1NiA2MTEgNTU2 IDYxMSA1NTYgMzMzIDYxMSA2MTEgMjc4IDI3OCA1NTYgMjc4IDg4OSA2MTEgNjExIDYxMSA2MTEg Mzg5IDU1NiAzMzMgNjExIDU1NiA3NzggNTU2IDU1NiA1MDAgMzg5IDI4MCAzODkgNTg0IDM1MCA1 NTYgMzUwIDI3OCA1NTYgNTAwIDEwMDAgNTU2IDU1NiAzMzMgMTAwMCA2NjcgMzMzIDEwMDAgMzUw IDYxMSAzNTAgMzUwIDI3OCAyNzggNTAwIDUwMCAzNTAgNTU2IDEwMDAgMzMzIDEwMDAgNTU2IDMz MyA5NDQgMzUwIDUwMCA2NjcgMjc4IDMzMyA1NTYgNTU2IDU1NiA1NTYgMjgwIDU1NiAzMzMgNzM3 IDM3MCA1NTYgNTg0IDMzMyA3MzcgNTUyIDQwMCA1NDkgMzMzIDMzMyAzMzMgNTc2IDU1NiAzMzMg MzMzIDMzMyAzNjUgNTU2IDgzNCA4MzQgODM0IDYxMSA3MjIgNzIyIDcyMiA3MjIgNzIyIDcyMiAx MDAwIDcyMiA2NjcgNjY3IDY2NyA2NjcgMjc4IDI3OCAyNzggMjc4IDcyMiA3MjIgNzc4IDc3OCA3 NzggNzc4IDc3OCA1ODQgNzc4IDcyMiA3MjIgNzIyIDcyMiA2NjcgNjY3IDYxMSA1NTYgNTU2IDU1 NiA1NTYgNTU2IDU1NiA4ODkgNTU2IDU1NiA1NTYgNTU2IDU1NiAyNzggMjc4IDI3OCAyNzggNjEx IDYxMSA2MTEgNjExIDYxMSA2MTEgNjExIDU0OSA2MTEgNjExIDYxMSA2MTEgNjExIDU1NiA2MTEg NTU2IF0KZW5kb2JqCnhyZWYKMCAyMCAKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDA5Njk2IDAw MDAwIG4gCjAwMDAwMTAwMDEgMDAwMDAgbiAKMDAwMDAxMDA2OSAwMDAwMCBuIAowMDAwMDEwMzIx IDAwMDAwIG4gCjAwMDAwMTYxOTIgMDAwMDAgbiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDE2 NjMzIDAwMDAwIG4gCjAwMDAwMTc0NTYgMDAwMDAgbiAKMDAwMDAxNzY0OCAwMDAwMCBuIAowMDAw MDE3ODcxIDAwMDAwIG4gCjAwMDAwMTg5NTUgMDAwMDAgbiAKMDAwMDAxOTE1OSAwMDAwMCBuIAow MDAwMDE5Mzk0IDAwMDAwIG4gCjAwMDAwMjA0NDUgMDAwMDAgbiAKMDAwMDAyMDY0NCAwMDAwMCBu IAowMDAwMDIwODY5IDAwMDAwIG4gCjAwMDAwMjE5MTUgMDAwMDAgbiAKMDAwMDAyMjEwOSAwMDAw MCBuIAowMDAwMDIyMzM0IDAwMDAwIG4gCnRyYWlsZXIKPDwgCiAgIC9Sb290IDEgMCBSCiAgIC9J bmZvIDUgMCBSCiAgIC9TaXplIDIwCj4+CnN0YXJ0eHJlZgoyMzM4MwolJUVPRgo= --_253d505f-363b-4857-9c14-3a09b91662dd_-- From mertas@vluchtelingenwerk.nl Thu Sep 4 01:45:04 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: **** X-Spam-Status: No, score=4.0 required=5.0 tests=ADVANCE_FEE_3_NEW,HTML_MESSAGE, SUBJ_ALL_CAPS,T_HK_SPAMMY_FILENAME autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B8BD97F6A for ; Thu, 4 Sep 2014 01:45:04 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9567E8F8035 for ; Wed, 3 Sep 2014 23:45:01 -0700 (PDT) X-ASG-Debug-ID: 1409813098-04cbb05486a2d440001-NocioJ Received: from mailproxy1.vluchtelingenwerk.nl (mailproxy1.vluchtelingenwerk.nl [188.201.255.76]) by cuda.sgi.com with ESMTP id 88wDNzPDvpMUQjm1 for ; Wed, 03 Sep 2014 23:44:58 -0700 (PDT) X-Barracuda-Envelope-From: mertas@vluchtelingenwerk.nl X-Barracuda-Apparent-Source-IP: 188.201.255.76 Received: from mailstore1.vluchtelingenwerk.nl (mailstore1.vluchtelingenwerk.nl [172.16.0.16]) by mailstore1.vluchtelingenwerk.nl (Postfix) with ESMTP id ECF02EAC1B1; Thu, 4 Sep 2014 08:31:55 +0200 (CEST) Date: Thu, 4 Sep 2014 08:31:55 +0200 (CEST) From: "iPhone Company inc 2014 Award " Reply-To: "iphone2014win@qdwxs.com" Message-ID: <1507608386.1957781.1409812315471.JavaMail.root@vluchtelingenwerk.nl> Subject: FINAL NOTIFICATION OF YOUR WINNING PRIZE! MIME-Version: 1.0 X-ASG-Orig-Subj: FINAL NOTIFICATION OF YOUR WINNING PRIZE! Content-Type: multipart/mixed; boundary="----=_Part_1957777_1336190691.1409812315449" X-Mailer: Zimbra 7.2.3_GA_2872 (zclient/7.2.3_GA_2872) To: undisclosed-recipients:; X-Barracuda-Connect: mailproxy1.vluchtelingenwerk.nl[188.201.255.76] X-Barracuda-Start-Time: 1409813098 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 2.14 X-Barracuda-Spam-Status: No, SCORE=2.14 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MV0224, HTML_MESSAGE, SUBJ_ALL_CAPS, SUBJ_ALL_CAPS_2 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9159 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 0.50 BSF_SC0_MV0224 FULL: Custom rule MV0224 0.01 SUBJ_ALL_CAPS Subject is all capitals 1.62 SUBJ_ALL_CAPS_2 SUBJ_ALL_CAPS_2 ------=_Part_1957777_1336190691.1409812315449 Content-Type: multipart/alternative; boundary="----=_Part_1957778_1120446958.1409812315449" ------=_Part_1957778_1120446958.1409812315449 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Greetings from iPhone company. Congratulations for been part of our 2014 lucky winner.Kindly open the attached form and follow the instruction immediately . Regards iPhone Admin. Director. Rai Walle ------=_Part_1957778_1120446958.1409812315449 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 7bit
Greetings from iPhone company. Congratulations for been part of our 2014 lucky winner.Kindly open the attached form and follow the instruction immediately .


        Regards


iPhone Admin. Director.


        Rai Walle














------=_Part_1957778_1120446958.1409812315449-- ------=_Part_1957777_1336190691.1409812315449 Content-Type: application/pdf; name="iPHONE WINNING FORM.pdf" Content-Disposition: attachment; filename="iPHONE WINNING FORM.pdf" Content-Transfer-Encoding: base64 JVBERi0xLjUNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFu Zyhlbi1VUykgL1N0cnVjdFRyZWVSb290IDIxIDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4+ Pg0KZW5kb2JqDQoyIDAgb2JqDQo8PC9UeXBlL1BhZ2VzL0NvdW50IDIvS2lkc1sgMyAwIFIgMTQg MCBSXSA+Pg0KZW5kb2JqDQozIDAgb2JqDQo8PC9UeXBlL1BhZ2UvUGFyZW50IDIgMCBSL1Jlc291 cmNlczw8L0ZvbnQ8PC9GMSA1IDAgUi9GMiA3IDAgUj4+L1hPYmplY3Q8PC9JbWFnZTkgOSAwIFIv SW1hZ2UxMCAxMCAwIFIvSW1hZ2UxMSAxMSAwIFIvSW1hZ2UxMiAxMiAwIFIvSW1hZ2UxMyAxMyAw IFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dC9JbWFnZUIvSW1hZ2VDL0ltYWdlSV0gPj4vTWVkaWFCb3hb IDAgMCA2MTIgNzkyXSAvQ29udGVudHMgNCAwIFIvR3JvdXA8PC9UeXBlL0dyb3VwL1MvVHJhbnNw YXJlbmN5L0NTL0RldmljZVJHQj4+L1RhYnMvUy9TdHJ1Y3RQYXJlbnRzIDA+Pg0KZW5kb2JqDQo0 IDAgb2JqDQo8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDEzNjY+Pg0Kc3RyZWFtDQp4nI1Y bW/bNhD+bsD/gR/2wRpimqQoSiqKAk3SFemWNOtSFMOwD47faiC2MltpkD/V37i744sox1KSIqoo 3d1z99zxeAqbXLO3byeXZxfnTLx7x07Pz9jpzXAw+U0yKbnQ7GY5HEgm4J9kWSa5KlgqU24ku9kM B4Kt8PJxOPhnxJJ/2c2n4eAD6LMPl2eMRcZly7hiUrUs54oLpZkqBRelsyy4KeGSSs12q4MHX15G VBHiIUyecZ0RzAtG0h4jRvBCOiPvk3E6qutknI22ST56g0uWmNE3vFnjBR9vk7EaLZJ0tEvGenQS I8cAUiteHgD0eql7vNSGi1eFmvUYSSXX3pMb9P07RkJx7ZMS7Poow6quksze3aLoDlaOBlitEu2k gJSKIWtP8Kh6ACmiBqlDwqoaV6Q4WzB4UH9H4SkI16BmGjUyR17hyx8LMNCgI+X4S+D0GIXucXXv vatAR4/mQYIUn8jR41lKC81l2eaGPL3+XqGuS/ZxZS1LYLat/BPiw8AvMabbEPgdXtB7cut6h7Rs kBhHeZUUUWCO0eOoPp3S8Dx3qMQ3mp8t1j8CjOU5LO89sY5vUKnJW0z5A143iS34aomK9OIXkJAc lxncCYF3JwKotrck8/Uv0DlHxSXFsosccPHvGcIhMLqDTrgSgXdKwFLqYA4lNk7KkefqoNr2ZCJr UzLuElUpl23RO5sGW62BLnpqa7de7Kz7UkdUUsGtdp5VdJnbFPYnTiguUwf9t81D2C+PtmKMLYao 1ThuvrhNsLS9CS5XVKdvPEWnp5NEKpuSSZEhqeJ3vE4imnmHhyoXWMktD3vbjeluN7LIuS5fYyTv MQL/F+pZz7I5Oh5DmXJlDjTdjoa2BhVEO6WjZ6sce3ZL92eXbKq5MG3ZzrMgNSjUkp3Bjq8299Pt E5vuoC1CWA942a+T7LDBxtsoO1YjYRV0fEXa+qJ3YbPD9nZSJLH1zeMpAFa+HmeVF7t3e4NM7adw Vy8C0l3YMMx3swe7RcbdvdfnOCu4LDwr5O6eGmO1Wfg+0cSNpukRoc3BqUDHvCmNsdshQdo3ORMd GOFlvd4G3uLjCw8sn6W1J8l2skfc+9jnnBtg7tGfjsEPmA20a8Lo36t7oIn6y6Zi4RAJ5/LWu1+/ xK1OeaYdtzbR5HDI9BK7/Q4PYYS1vlZ7G4CMzw10uboHj9onGQZNW9IOACGoIPAAGdqvQw1ans3I t73ssJ/O8TkqzWpYnjBLnjsTHSRIIJDlc+X4bI9ltihdT9wv7haz2vvtpgN3WJF0tWGeUTKDms2g E2I5cjDZPdmfA1Vw3wfn/rCop4R429UwRMrzliYFvOhq3BIONaNaCr0tt+hpuVJDA32NkbLbSFmC O77uLjDS5sBqT3vPK6bpR/EoYo5OM1SkUJa+rr3WYzgqKhYD+PGomRCxrKI5mFlJeSzRTVuxO9PW zEG/iPqlS/W2mUGdYyEGaqNPHuR5A29mWBJY9QyyjngYZ8vCE3/2GdGuPvrBgb5v6BT9+gf48h5+ aUUJ+gyrK+aHQj/PSz8pBp/Iy7nfjM0oGfbyMj5+GvZQsnPuKOD7Rrad7/8Q9Z+5/w0HY/japB+p YJ4XkmeGGfgy1bLgGr46F8PBt1/ZdjhQKewOQ5Amh4PYsBy6IzMZTDs5mwHq5GIzXS1Kdl6xP4+h ygbVgUqhi35QmfEyt6CaG/jsVjgWIagqI1ApOlHVM1Sh4WuwD1XnMJxYVCkxSIo0S0v8MI9AZSdo eoTgDDD6UWl88qjCEaxVxrM0hlWdsPoYrMpfgC0wLAsLudQWFv/AAXIRbBrD/g/Fd5j0DQplbmRz dHJlYW0NCmVuZG9iag0KNSAwIG9iag0KPDwvVHlwZS9Gb250L1N1YnR5cGUvVHJ1ZVR5cGUvTmFt ZS9GMS9CYXNlRm9udC9BQkNERUUrQ2FsaWJyaS9FbmNvZGluZy9XaW5BbnNpRW5jb2RpbmcvRm9u dERlc2NyaXB0b3IgNiAwIFIvRmlyc3RDaGFyIDMyL0xhc3RDaGFyIDExNy9XaWR0aHMgNTcgMCBS Pj4NCmVuZG9iag0KNiAwIG9iag0KPDwvVHlwZS9Gb250RGVzY3JpcHRvci9Gb250TmFtZS9BQkNE RUUrQ2FsaWJyaS9GbGFncyAzMi9JdGFsaWNBbmdsZSAwL0FzY2VudCA3NTAvRGVzY2VudCAtMjUw L0NhcEhlaWdodCA3NTAvQXZnV2lkdGggNTIxL01heFdpZHRoIDE3NDMvRm9udFdlaWdodCA0MDAv WEhlaWdodCAyNTAvU3RlbVYgNTIvRm9udEJCb3hbIC01MDMgLTI1MCAxMjQwIDc1MF0gL0ZvbnRG aWxlMiA1OCAwIFI+Pg0KZW5kb2JqDQo3IDAgb2JqDQo8PC9UeXBlL0ZvbnQvU3VidHlwZS9UcnVl VHlwZS9OYW1lL0YyL0Jhc2VGb250L0FCQ0RFRStDYWxpYnJpLEJvbGQvRW5jb2RpbmcvV2luQW5z aUVuY29kaW5nL0ZvbnREZXNjcmlwdG9yIDggMCBSL0ZpcnN0Q2hhciAzMi9MYXN0Q2hhciAxNzQv V2lkdGhzIDU5IDAgUj4+DQplbmRvYmoNCjggMCBvYmoNCjw8L1R5cGUvRm9udERlc2NyaXB0b3Iv Rm9udE5hbWUvQUJDREVFK0NhbGlicmksQm9sZC9GbGFncyAzMi9JdGFsaWNBbmdsZSAwL0FzY2Vu dCA3NTAvRGVzY2VudCAtMjUwL0NhcEhlaWdodCA3NTAvQXZnV2lkdGggNTM2L01heFdpZHRoIDE3 NTkvRm9udFdlaWdodCA3MDAvWEhlaWdodCAyNTAvU3RlbVYgNTMvRm9udEJCb3hbIC01MTkgLTI1 MCAxMjQwIDc1MF0gL0ZvbnRGaWxlMiA2MCAwIFI+Pg0KZW5kb2JqDQo5IDAgb2JqDQo8PC9UeXBl L1hPYmplY3QvU3VidHlwZS9JbWFnZS9XaWR0aCA2NjMvSGVpZ2h0IDE4OC9Db2xvclNwYWNlL0Rl dmljZUdyYXkvQml0c1BlckNvbXBvbmVudCA4L0ZpbHRlci9EQ1REZWNvZGUvSW50ZXJwb2xhdGUg dHJ1ZS9MZW5ndGggMTA0OTI+Pg0Kc3RyZWFtDQr/2P/gABBKRklGAAEBAQB4AHgAAP/bAEMACAYG BwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicgIiwjHBwoNyksMDE0NDQfJzk9ODI8 LjM0Mv/AAAsIALwClwEBEQD/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAAC AQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZ GiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOU lZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T1 9vf4+fr/2gAIAQEAAD8A9/oprukUbSSOqIoyzMcAD3NcVrHxa8H6OzIdS+2yr1SyTzP/AB7hf1rj 7v8AaDs0ciz8PXEq9jNcrGfyCtVQ/tCTZ48NR/8Agaf/AIik/wCGhJv+hbj/APAw/wDxFH/DQk3/ AELcf/gYf/iKP+GhJv8AoW4//Aw//EUf8NCTf9C3H/4GH/4ij/hoSb/oW4//AAMP/wARR/w0JN/0 Lcf/AIGH/wCIo/4aEm/6FuP/AMDD/wDEUf8ADQk3/Qtx/wDgYf8A4ij/AIaEm/6FuP8A8DD/APEU f8NCTf8AQtx/+Bh/+Io/4aEm/wChbj/8DD/8RR/w0JN/0Lcf/gYf/iKP+GhJv+hbj/8AAw//ABFH /DQk3/Qtx/8AgYf/AIij/hoSb/oW4/8AwMP/AMRR/wANCTf9C3H/AOBh/wDiKP8AhoSb/oW4/wDw MP8A8RR/w0JN/wBC3H/4GH/4ij/hoSb/AKFuP/wMP/xFH/DQk3/Qtx/+Bh/+Io/4aEm/6FuP/wAD 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 jjoO3Xr09kooIyMGvOPFvwb0LxA73Wnn+yr1jkmJMxOfdOMH3BH0NeSaz8IfF+kMxSwW/hH/AC0s 335/4CcN+lchdaRqVixW80+7t2HUTQsh/UVTIwcGiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiilAJOAMmr9loWr6iQLLS725J6eTAz/AMhXZaL8GfFu qsrXNtFpsB533Tjdj/cXJz9cV6/4P+FGg+FXju5AdQ1FORcTqNqH1ROg+pyfeu8ooooooppRCclF /Kjy0/uL+VHlp/cX8qPLT+4v5UeWn9xfyo8tP7i/lR5af3F/Kjy0/uL+VHlp/cX8qPLT+4v5UeWn 9xfyo8tP7i/lR5af3F/Kjy0/uL+VHlp/cX8qPLT+4v5UeWn9xfyo8tP7i/lR5af3F/Kjy0/uL+VH lp/cX8qPLT+4v5UeWn9xfyo8tP7i/lR5af3F/Kjy0/uL+VHlp/cX8qPLT+4v5UeWn9xfyo8tP7i/ lR5af3F/Kjy0/uL+VHlp/cX8qPLT+4v5UeWn9xfyo8tP7i/lR5af3F/Kjy0/uL+VHlp/cX8qPLT+ 4v5UeWn9xfyo8tP7i/lR5af3F/Kjy0/uL+VHlp/cX8qPLT+4v5UeWn9xfyo8tP7i/lR5af3F/Kjy 0/uL+VHlp/cX8qPLT+4v5UeWn9xfyo8tP7i/lR5af3F/Kjy0/uL+VHlp/cX8qPLT+4v5UeWn9xfy o8tP7i/lR5af3F/Kjy0/uL+VHlp/cX8qPLT+4v5UeWn9xfyo8tP7i/lR5af3F/Kjy0/uL+VHlp/c X8qPLT+4v5UeWn9xfyo8tP7i/lQEUHIUA/SnUUUUV//ZDQplbmRzdHJlYW0NCmVuZG9iag0KMTAg MCBvYmoNCjw8L1R5cGUvWE9iamVjdC9TdWJ0eXBlL0ltYWdlL1dpZHRoIDY2MC9IZWlnaHQgMTk3 L0NvbG9yU3BhY2UvRGV2aWNlUkdCL0JpdHNQZXJDb21wb25lbnQgOC9GaWx0ZXIvRENURGVjb2Rl L0ludGVycG9sYXRlIHRydWUvTGVuZ3RoIDk2OTY+Pg0Kc3RyZWFtDQr/2P/gABBKRklGAAEBAQDc ANwAAP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicgIiwjHBwoNyks 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 Kwv7Vb1o/tVvWn7NiuV72xntXzJ8wJ+9nOap1oy6iZY2RuQazq2je2pIUUUUwCiiigAooooAKKKK ACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACnLI69GIptFADmdm6kn602iigAo oooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACii igAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKK ACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAo oooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACii igAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKK ACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA/9kNCmVuZHN0cmVh bQ0KZW5kb2JqDQoxMSAwIG9iag0KPDwvVHlwZS9YT2JqZWN0L1N1YnR5cGUvSW1hZ2UvV2lkdGgg MTQ0OS9IZWlnaHQgMzQ3L0NvbG9yU3BhY2UvRGV2aWNlUkdCL0JpdHNQZXJDb21wb25lbnQgOC9G aWx0ZXIvRENURGVjb2RlL0ludGVycG9sYXRlIHRydWUvTGVuZ3RoIDc2ODE1Pj4NCnN0cmVhbQ0K /9j/4AAQSkZJRgABAQEA3ADcAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0a HBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIy MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAFbBakDASIA AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3 ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3 uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDtfCHh Hwxc+CdBuLjw5pEs0unW7ySSWMTM7GNSSSVyST3rZ/4Qrwl/0K+i/wDgvi/+JqPwUf8Aig/Dv/YM tv8A0Utbuaskx/8AhCvCf/Qr6L/4ARf/ABNA8E+E/wDoV9F/8F8X/wATWxShqLAY/wDwhPhP/oV9 E/8AACL/AOJpf+EI8Jf9Cvov/gvi/wDia21OadQBhf8ACEeEv+hX0T/wAi/+Jo/4Qjwl/wBCvov/ AIARf/E1u0ooAwf+EI8Jf9Cvov8A4L4v/iaP+EI8Jf8AQr6J/wCAEX/xNb1FAGD/AMIR4S/6FfRP /BfF/wDE0v8AwhHhP/oV9E/8AIv/AImt2jNAGF/whHhP/oV9F/8ABfF/8TR/whHhL/oV9E/8F8X/ AMTW7S0AYP8AwhHhP/oV9E/8F8X/AMTS/wDCEeEv+hX0T/wXxf8AxNbtFAGF/wAIP4S/6FfRP/Bf F/8AE0f8IR4S/wChX0T/AMF8X/xNbuaM0AYX/CD+Ev8AoV9E/wDBfF/8TR/wg/hL/oV9E/8ABfF/ 8TW7mjPrSAwv+EH8Jf8AQr6J/wCC+L/4mj/hB/CX/Qr6J/4L4v8A4mt3NFMDC/4Qjwl/0K+if+C+ L/4mj/hCPCX/AEK+if8Agvi/+JrdzRSAwv8AhCPCX/Qr6J/4L4v/AImj/hCPCX/Qr6J/4L4v/ia3 eaM0AYX/AAg/hL/oV9E/8F8X/wATR/whHhL/AKFfRP8AwXxf/E1u0UAYX/CD+Ev+hW0T/wAF8X/x NH/CD+Ev+hX0T/wXxf8AxNb1FAGD/wAIP4S/6FbRP/BfF/8AE0f8IP4S/wChW0T/AMF8X/xNb1FA GD/wg/hL/oV9E/8ABfF/8TR/wg/hL/oV9E/8F8X/AMTW9RQBg/8ACD+Ev+hX0T/wXxf/ABNH/CD+ Ev8AoV9E/wDBfF/8TW9RQBg/8IP4S/6FfRP/AAXxf/E0f8IP4S/6FbRP/BfF/wDE1vUmaAML/hCP CX/Qr6J/4L4v/iaP+EI8Jf8AQr6J/wCC+L/4mt6igDB/4Qfwl/0K+if+C+L/AOJo/wCEH8Jf9Cvo n/gvi/8Aia3qKAMH/hB/CX/Qr6J/4L4v/iaP+EH8Jf8AQr6J/wCC+L/4mt6igDB/4Qfwl/0K+if+ C+L/AOJo/wCEH8Jf9Cvon/gvi/8Aia3qKAMH/hB/CX/Qr6J/4L4v/iaP+EH8Jf8AQr6J/wCC+L/4 mt6igDB/4Qfwl/0K+if+C+L/AOJo/wCEH8Jf9Cton/gvi/8Aia3qKAMH/hB/CX/Qr6J/4L4v/iaT /hB/Cf8A0K+if+C+L/4mt+igZz58D+E/+hX0X/wAi/8AiaafA/hT/oWNF/8AACL/AOJroqKYjnP+ EH8Kf9Cxov8A4ARf/E0f8IR4U/6FjRf/AAAi/wDia6LFGBQBzo8D+FP+hY0X/wAAIv8A4mnDwN4U /wChY0X/AMAIv/ia6HAooAwB4H8J/wDQr6L/AOC+L/4ml/4Qfwl/0K+if+C+L/4mt+koAwf+EH8J f9Cton/gvi/+Jo/4Qfwl/wBCvon/AIL4v/ia3qKQGD/wg/hL/oV9E/8ABfF/8TR/wg/hL/oV9F/8 F8X/AMTW9RQBg/8ACD+Ev+hW0T/wXxf/ABNH/CD+Ev8AoV9E/wDBfF/8TW9RQBhf8IP4S/6FbRP/ AAXxf/E0h8D+Ej/zK+if+C+L/wCJreooA5xvh/4PY5PhjSfwtEH9KT/hX/hMfd8PaUv/AG4wn+aG ukopgc3/AMIH4ZX7vh7RD/v6ZCf5KKP+EH8OD/mWfDzf9w2Nf6GukooA5v8A4Qvw2OvhDQCP9mzi /qgo/wCEO8LDr4N0n6iwg/wrpKKAOb/4RHwf38KaSP8AuFJ/RKP+ET8Fd/DmgqfRrCIfzWukooA5 9PBng6T7nhrQm+lhCf8A2Wnf8IP4S/6FbRP/AAXxf/E1tvBDJ9+JG/3lBpn2SAfdjCf7ny/yo0Ax /wDhB/CX/QraJ/4L4v8A4mj/AIQfwl/0K+if+C+L/wCJrY+zKPuyTKf+uhP880eTJ2uZPxC/4UAY /wDwhHhL/oVtE/8ABfF/8TR/whHhL/oVtE/8F8X/AMTWxsuR0miP1jP/AMVRm5H8ELe+8j+hoAx/ +EH8Jf8AQr6J/wCC+L/4mgeB/CX/AEK2if8Agvi/+JrY82ZfvW7E/wCwwP8APFH2nH3oZV/4Du/l mgDHPgfwl/0K2if+C+L/AOJo/wCEH8Jf9Cton/gvi/8Aia2PtUX8RdB6ujL/ADFKt1bscLPET6Bx QBjf8IP4S/6FfRP/AAXxf/E01vBHhPH/ACK+if8Agvi/+JroMgjINNbpQB86+NdE0m08WajDb6ZZ QxJINqRwKqjgdABxXLvYWIb/AI9Lcf8AbMf4V2nj9ivjTU/+ug/9BFcm7Mx6iqVrAyn9kst3NnB/ 36Wk+w2hOfskOP8ArkP8KnYgGm7yOAxFMRAbG0HS1gP/AGzH+FJ9is8/Nawge0a1NuJAyc/jQ0nG 0AfUUWC5CbG0zxbQge8YppsrX/n1g/79j/Cp/TmjHy8fyosFyEWNr/z6wf8AfsVYgsbIyAG0tvxi FCMSwXkD0xVmKMb8lsfhTsFyHUdPsUvnVbSBQAMBY1A6fSqhs7MdLWE/9sx/hWnqiE6jIcDoOp9h VErjrt/OkkFyH7HadPskOf8ArmKPsVoMZtYf+/YqcAZyf0FNO8no2PpRYLkJs7Pn/RYf++B/hR9k tMAfZYP++B/hUygknj86Vgc4HWiwXK/2S0/59Yf+/YoNpaZ/49Yf+/YqYq4/hP5U8wSEbth/AUWC 5WNnaY5tYv8Av2KPsdp0+yw/98CrcVrKxOY2X6inGykAzkZ9KLILlH7HaAf8e0H/AHwP8KQ2lrn/ AI9oP+/Yq59kYHBkUe5cCnm2jCDMq5/3qLILmebW1A/49ov+/Ypfsdtwfs0OP+uYq75Vuow0w/Wl H2QKBuyfUA0WQXKQsLZjxbRH6ItX9L0yze9jElpCwJwQ0akfypwe2XlQwHsKtWDIbuMR7gxbgkU9 BamU+n229h9kgHJxiMUw6fbDI+zQ5H+wKvXE0aSsNhyD61Cbpe0fX3paDKos7U4BtYh7+WKd9gtd p220LH/cH+FTm5B42Jj8aBdkfwKPoKNAKn9nRHkWkX/fIp39lL/z6wf98Cpzdy54YY9Aoo+1Sn/l oR7jijQCEaXHkZtISPaMU9tJiLDZZxgf9cxQ1xL/AM9X9stSo0sg+8Tj1ajQBg0lM82keM90Wpzp dmCN0Fsv1VaZ85Q9M1C27oaNAJv7PshkeVa5/wB1aBp9gTzHb57gIP8ACq/zZ4zj6VJuIxxzQBML DTl6wwH/ALZj/Ck+xaaB/wAe8f8A37FRiQEEk4PpSHcB2xQBL9l04H/j0jPt5a0fZ9O5/wBCi/74 X/CowCORimk9s8/SiwXL9tZ2MqTFbG2+WMnmJT/SqLJaISDp9oD7xitHSwxiuRz/AKluazWRgxzk n3pWC40rbf8APlaD6QimeXCf+XW2/wC/C/4VIMdDx+NNwAM0WGRGCE9beD8Il/wpv2e3H/LtD/3w KlLe/FKPpSAh+zW+ObeIe+wUfZbb/nhF/wB8Cptpx3o6D/69AEAtbct/qIv++BUn2S2LDFvF/wB+ xTxyenH1p7sMjBosBE1nbY/1EI/4AKb9ntiMfZof++BUjncevNATnr+QosBH9jtz/wAu8P8A3wKY 1pb/APPCH/vgVZbIHAP5UgB9GosBALS2x/qIv++BS/Y7cj/UR/8AfAqbaeu0/nRhvb86LAVzZwY/ 494/++BR9lgx/wAe8f8A3yKn2t6jNKEOeSPyppAWdFsrSbUIkktLd1JOQ0YPY+1Vp7O0EzgW0I+Y gYQetaeijbqUHTqe3tVO6JNxKvT5zz+NFtQKv2K3Vv8AUQ4P+wKUWdt1MEP/AH7FO2KvVmP40ERq eSc/WnZCG/YrbH/HtF/37FNaytx/y7Rf98CpRIRxyPxpdwIyRn2pDIUtLcHDW0P4oKkFpa7f+PaD /vgU8fMOE/MU0yFTjZ+NFgGG1s1628P/AHwKQ29oTgWsX/fAqdkITdkjiollZRkEfjQIYLW13EfZ 4v8Av2KeLa1xzaw/9+x/hSF2diSRmnqzEYyKAGNbWpUAWsP12CmC0tw3NvDj/dFTD73/ANantFng H8QKAIPstsDxbQfig/wppt7Yf8u0P/fA/wAKmaLaR87GngMvBoArfZLfaf3EP/fsU37Hbd4ov++B U7YB96BHz8wH4UWAgEFt2t4f++BUsVrbH71vD+Ea/wCFPaMYG0AfhT4wR15/CgLlvUdOsxbWbR2d uu6PkiMDJ/Ks37Bb/wDPvD/3wK3L45sbI4/gNZ4B5oshlT7BAP8AlhD/AN8Cg2dsV/49oh7+WKt7 TiiQfJRZAVFs7Yf8sIj/ANsxTxZ2va1hP/bMVJjinL1Io0Ag+xWnObaL/vgUosbPH/HtF/3yKnA5 ORR0zS0AgaxtdvFtCP8AgAphsbYL/qIv++BVgDI6UFc9qNBalT7JbK4/cxH/AIAKd9ktj0toT/wA U+SP5l2j86kijIzn9KNB6kBsrYrkW8Wf9wU37DB/z7xf98irqr1+XNLs/wBg0aBqfSXgr/kRPDv/ AGDLb/0UtblYnglf+KD8O/8AYMtv/RS1u7aQDacBTgtOAxTAAMUuaSlpALRSUUALRmkpaAF7UmaM 0UALRmm0tAC5opKM0ALRmko/CgQuaKQUUDFopKWgANFFFAC0ZpKKAFyKKSigB1ANNzRmgB1Jmikz QAtFFJmgBaKM0lAC0UlGaAFzRmkooAWikpaAFozTaXNAC9aKbS0ALRSUUALRSZooAWikooAWikoo AWikzRQAtFJRQAtFJRQAtFJmigBaOaSigBaKSigBe1FJRQAUtJRQAtFJRQAtFJRQAtFJ2pc0AFFG aM0AFFFFACmkoLAdTiomurdPvzxr9XAoAmpKrHUbIf8AL3B/38H+NNOq2Q/5bhv90Fv5UAXKRlDD DAEehFUTrFkP+Wjn/tk/+FMOtW/8MczfRQP5kUAXDaWx58iLPrtFNa0i7GQeyysP5GqR1yIdLac/ 98//ABVRtrZP3bX/AL6fH8gaAPGfHMMi+L9SVU3qJByxyfujv1rlzESeYV98E16hrnhW51vWrq+N 4kCzsGCKN23gDrxmqSfDsfx6pIfpH/8AXppqw2efz2CxPGNrPvTdweB7dKrNZ5cnbIP+Aj/GvUh8 P7HgyXU749MD/GktvAejywrI4n3N1xJ/9anzIVjy37ASR+8Vf97ij7AM4Eyf99V66ngbQ0I/cO31 c1YTwhoaHIsVP1Zv8aOYLHjn9nnH+tjPsDmgWSr95m/BDXtSeGtGTpp1vn3XP86sJpGmxj5LC2H/ AGyX/ClzhY8PWCIEYDbh6LViODc42xSn/gNe1nTbIncLWEH1VAD+lOWziUfKZF+kjf40cwWR47c6 ddT3LFbGaQnHKIcdKQ+HNTmA26PdH/gJH9K9mEDdriT8Qv8AhSGOcdJlI/2o/wDAijmYHkEXhLWs jGlOB/tH/wCvUw8H61IxVLKIFThtzDj9a9Y/0kDpE34lf8aqRtN59zmEH5h91/8AZHqBS5mB55D4 E1lly5tYvxz/AEqlN4W1RCQkkLEHHHH9K9VEzhfmt5R+R/ka595k86QEOPmPVTRzMdjz6TQtZRlU xklum1xUD6JrCj5rWdvpzXoTzRfaYDvXgnOT7GrgZWHysD9DRzMLI8ql06/Qgm0mB90NU3huUYlo WX6qa9iAFLtUjkCjmYWPGdrkHKN/3zQQduMHNextbQOPmiRvqoqGTSrF/vWkJ+sYo52Fjx8oSB1p h445r1w+H9Lcc2UX4DFQP4T0h+fsmPox/wAafOKx5XFkNWnpg/4mEH++K7l/BmlNnasqn2eoz4Us rLE8bSl0IIyw/wAKfOgsef3YzO/HO49veq7fK2Aua9BuPBMM7FkunUE5wUBqlL4Bkz+7vF/FKOZB Y4joD/jSgFhx/OuubwJer924gb8xVeXwRqYJ2mNvo+P50uZBY5jHNKRnAH8q3m8Iauv/AC7ZHqJB UEnhrVk/5c5Pyz/KndBYyAgyOP0qaNguQcCrZ0a/T79nMuPVDUEtlOnWGT/vk0XQWIjIgjPzcmqw AbIGKuC2ITJQ/QrTTGVA4waNAKwOF208noQM+2KWQYY/40ixknmmAnBB+U5+lJk4x/Wn+UAcFRSb BnhefpSEMJfA4H50vB9M/WpAoB+Y/pSELuzk0wNDSWJNwOOIGrNcuxzk/lWppH35h6xN/KqAbJ5o AgCsfX/vmkJbGD296sD2phTgHFAFfaDzz+dPCZ9Pzp5BJ4Xj2pp3AkAceuaQxqEZ5H86UsoPK5/C m4GcZ/WhkA6UWAXeOgUflRuJIxikWInBGKcV249fpQA4Ngc8UoJ5OeKUqD6flSgAA0CGkgtTgOeK CCMUnzE0AJgkmkOaeqnbyKcYnI+VSc+gpjIiPf8AM0qrx2zUptZSRiNvypVtpASNp4oAt6O2NRg9 d39Kz7okXswJ/jboPer+nxvFewucEBugYE/lUd1Dm5kbcoy5yNw45pAUCC3c/lSFNxHLVb8hSfvq PzpfJQE/vF/I/wCFAFcOoXAwcUpkxgk1MIYgPvf+O0uyE45b8h/jQBWLu33T+dL5RcbjtzVn9yD/ ABY/Ck/d5OEf/vr/AOtQIhOSuDTTFngcfQVY/d4GI+fc0pdRj92ox7n/ABoHYrICjFRz9RSMhLE4 5+tWPMHmcInT0pfNIzgKB/uigCuoOOaf1PGakMzAY4/BRQZn4+Y/hQKyI9hY4P5UqxPk4ViR7U8y yZyXbP1pm9ieSfxNA9AFvIRkRtj120rQuRyuPrxTctig7h9KA0H+Qw/uD/gY/wAaPJOf9ZGP+BCo d55FOHJpAmac/wA1hbBmACZGexqltUH/AFq/hmrVyP8AiU2x9WNZ2c8ZoQE2UxgsfyoPl/3mI/3R /jUXbqaQjNMCbMWRwx/EU4tCD8qv07sP8KgGO3WnD3paAS71HRCfq1N3DkeUv5n/ABqMk54poz3J oAm8wAcIg/X+dHmt6IP+Aio8gj/61DkBcg0WAdJM6kHI/BRTkmkOfnYVX8w5XPSpEYM3FOwEvmuM /vG/OmeY3/PRvzo4zyKPloA+l/BP/IheHP8AsF23/opa3awfBP8AyIXh3/sGW3/opa3c1IC0tNpa AClzSUUALnNFJRmgQ6im0Z7UxjqKbS0ALRmkzRQAtFJRmkIWikzRQA6k7UUUAKDRmkzRQAuaM0lF AxaUU2igBaKTNFAC0UUZoAM0UUmaAFzRSUuaAFopuaWgBaKTNJQA6jNNpaACl/Km0tAC0UlFAC0U maM0ALRSZpCwHJIH1osA7NGaga7t0+9PGv1cUw6jZD/l7g/CQUCRaoyKpHVLMf8ALcH/AHQT/KmH WLIf8tJD/wBsn/woGaGaM1mnWbf+FJW+iY/nimf23D/z7z/kv/xVAGrmjNZC66roGjt3wwyNxApD rMna2X8ZP/rUAbGaKxTrE56QRr9XJ/pTTqt32EI/4AT/AFoA3KM1gHU70/xxD/dQ/wBSaab+8P8A y8sPoq/4UAdDmjNc2bu6P3rqQ/gB/IUwzzH/AJbzfhIw/rQB0+aM1yFw8uwfv5j8y9ZGPce9SeWr feUN9eaAsdSzqvLMB9TURvbVfvXMIPu4rmxBGOkafgop4AAwPyoA3jqdkP8Al7hP0cGmnVrMf8tS fojH+QrCIFJQBtnWLMdGkP0ib+oph1qHtDM34AfzNY9LmgDVOuR9rWf8dv8AjUUmveWjP9l4Hq// ANas6obv/j1k+lAGw2tS/wANsn4yn/4mmHWLk9EhH4E/1FUPWigC4dWvTwDAPpGf/iqYdRvT1mA/ 3UH9c1WzSZyOtAFj7deE/wDH0/8A3yv+FNa5nI+a4lJ9mI/lUINLkUAOMszf8vE//f5v8aYRu+9l v945/nS5FGRSAYYYuvlp/wB8io4EVZJtoA+fsPYVNuFQwsoln/3x/IUATilpm78qN4oAfRn2pnmL jrTGnRfvOo+ppgS0VALuEnAlQn2NKbhB1YCkBNS8VTk1C3iGWlH4Gqx12yBwZcfUimBqE8Gq1kf9 Ej/H+ZrPk8QWS8CRT9GFRW+u2cUIRpORnoCe/tQBvZFGaw28RWi9pf8Av23+FQv4otB0DfjgfzNI LnQ5FGRXMP4ttx/AP+/if/FVE3i+Lsg/77H9M01q7IXMjrMikzXIv4rcDlFH13f/ABNKviG7mGY4 h0zkA/1xV+yn2Fzx7nXbsUm4dK5SXU9S+yNOGRMFQAyHnJx/eqsdVv31OaxWTc8ZA3bAAcj6mkqc m7WBzilc7QsKpRyqLq6yQPmXv/s1y1zPfKD5js2PR1H/ALJWfcX1zEDwendx/RRWiw1R9CHWh3O8 NzCoOZox9WFc88qGeTDA5Y8g1yFxrlzHIFEUZyM5Lv8A0YVnxapdz3U4LKu0jG1n9PdqU6Eoq7Lj NPY7mRv9Ih47n+RqY+W33o1P1FcWNXv4zhbl/wA/8c07/hIdQX/loW+pX/4mseUrmR2IWLsu3/d4 /lS7V7PIP+Bk/wA64+HxRfyXSwbUJbuUHH61fTXL7yt7RQNliMBT2P1o5Qujo/mHSZ/xA/woLy9P MU/Vf/r1z48QTj71mn4Fv8KX/hImHW0I+jH+oosw5kdAJJQOiN+JH+NKJ5B1jB/3WH9cVgL4ji/i tpB/wJf8aePEVmfvLMv4A/yNFmFzdFwe8Tj8j/I1FdXCNbsMMOR1QjvWcuuWLf8ALSUfWJqWTVLG RNv2pV6feUj+lKw7mqLmHH+tQfU4p4dW5Vgfoazhqdk3S8g/77FPWe0l6SW7/wDAgaLBc0OOvFOz WcXt1I5UZ/un/CpEAcZjd8eocn+dAXLmBSnbxVP95/z1k/ED/ClLTD+Nce6f/XoAtsFJ6CmmNCPu iq3nSjqEP4kU1rqVeluX/wB1x/XFGgBdwRFoQYkOXHVfY0Ppli/37SA/VBUM14WeLfbzJh/QHsfQ mpvt0XcSL9Ym/wAKAIDoGkuCWsofwGKqyeFtJc8WoH0c/wCNaQv7XHM8Y9icU9Z43+5IjfQ0AYje DdKfOEkU+z1C/gXT2HyTTr+IP9K6VWGDTgwpjOPk8BQNyt234pn+tV38BuPuXSH6pXcEijgii7Ec Va+D7q1lZvOiYFSvfv8AhWcfBl/t3RvC4yRwxH869EPSooP9W3+8f50czCx503hLVY/+WAI9mH+N RP4b1JQA0D/QKT/KvUO1MOM80czCyPLG0S7jb5oJh/2yb/CoHsWQfPHKPrHXrOAe1IVHTFHMwseR GGJeqv8A98ik2xA/cbH1xXrElvC/3o0P1FRnTrJ/vWsJ+sYp8wWPKx5Q42N/31/9ag+Xx+6X8WNe nvommOObOL8FxVQeG9KlkkBtV4I6MfT60cwHnG5f+eSfr/jSl8DhE/KvQZPCWmE/LG6/Rqgfwbp5 HyyTD/gQ/wAKOZBY4USN/s/98ik8xyeGx9AK7RvBEB+5dSD6qDUL+Bmz8t4PxT/69O6CxyPmy8/v G/M0hlcdWP511Engm7C4S5iP1BFVpPB+oDo0LEf7R/wpXQWOfySckk03cBmtx/CuqgjEKEeocVXf w5qiHi1LD1Ug07oVitphzqFv6FxTLo/6XN/10b+dXdP0q/gv4XmtZlRXGSVPAqC6tbj7VKxhkALk /dPrRoGpUXOc5/Sl9en5U8xOOqkfWo2+UkH+dVoIMjODRxnjOabkenNLxnr+QpDHcnrTc4FIWz/+ qk3cYwaBDgaR+P8A9VJ82OAR9aRy464/OhgNyQ/HpTgR1NRBju5x0qVfcL+VJDEwvWnADI4pC3HR aM8g7gPwpiFcdMUwDnOaez5P3/yFNAJOQSaBkgA2U0getAzjqaaAc8/zoEOJ28/0pP4uc0HGRxxS ADOcUAaVyCdEtcAZ3t1rLGRnO3Nac+f7Et8DpIePzrNBOemDSQxMj2/OnEjGc/lQMH60clcdqYCA +ufyoJGep/KlApMjPA5pAJkc/epQw9D+dB9aSmA7Hfb+tI+NvQfnTSCBxk0uD3FADDjI6U4Hng/p Sso4znGaYyKuCP1oAkXOTz+lOw3r+lRjB55z9af+NAH0x4J/5ELw7/2DLb/0UtbtYXgn/kQvDv8A 2DLb/wBFLW7UgFLSd6KAFopKKAFopKKYC0tJSZpAOzRmkopgLk0ZpKKAFozSUZoAXNGajdsKT7Vw cup3kjHN3Nj0DkUAegZpC4XkkD6mvOXuZX+9NI31Y1WZszJkk9etOwj0pru3T708S/VwKjbVLFet 5B/38Fef7gKN9FkB3ja3py9bpPwyaibxFpq/8vBP0Rv8K4cyoOCy/nTDKn94fnRYDtT4o04NtDSM cdk/xpreKbMfdinP4D/GuIEiifoT8vYE1MJP9hz/AMANGgHWN4qi/gtnP1YCo28WN/DZj8Zf/rVz G5z0jf8AKjMn/PJvzH+NFkFzoW8VXPa3iH1JNVm8V35lCBLdRjOQp/xrGIl/55j8WqHbKbgfKn3f 7x9fpQBvt4j1E9JUH0QVC+v6kR/x9EfRF/wrL2y+qj8zTXjlx/rF/wC+T/jTEMfxPrIv7iNb99ib cDavcfSrC+K9ZT/l7B+sa/4VzrJJ/aF186nlcnb/ALP1qTbJ/eX8v/r0ijov+Ez1dBy8LfWMf0qa DxzqZRS8Nqcj+63+NcqwkweFP402FpBGuFXGP73/ANagR2q+OrofftIW+jEf41Mvjxh9/Tx+E3/2 NcRvf+4fwNHmOP8Alm36UAd4vjuA/fspB9HBqZfHOnn71vcj8FP9a888490b8qTzh3Df98mjQD0p fGuknqZ1+sf+BqWPxhosn/L0R9Y2/wAK8uMykfxfiDTIJk2t84+8e9AHra+JtHfpfJ+KsP5inPrN jLGwt72FpCPlAcZz9K8nE8efvr+dauisG1CLB70WA7Np526zy/g5H8qgV5WnYNcTkBRwZW9/epDj HWok/wBfIfYf1qRjyinqM/Xmk+zx9diZ+gp24UbhSAUKB0A/Kik8wUnmL60ALil4qPzVHVh+dMa4 jUElwAOvNAEx6U0nANVhewEHEi4qGTUrZflMoz60AXLb/j2i/wBwVPWVFqVnFCitdxAgAEbxQ2s2 agkTBvZeaYGpnmjNZI1q3IziX8Iyf6VG2v2idfMH1Qj+dFgNnIJoLCsE+I7Qn5ck/wC8o/rSvrwU Z+ztj3Zf8afKxXRuZzRkVzF34ne3jldoPLSJVZmY5GGPHSs9fGm7hTGx+jf/ABNNQk9kDkjsLlh5 a/76/wDoQqfdXG3et30Rh86HaJgHjx3HrUj65qawrJ5ShWOAdv8A9lT9nLsLmR1+8DrRvHauOGra rKpYFAAQPujv+dQXeqapbSKjyAk91IH/ALLT9jPsHMrHb7xTTIPUVwus6hqel3iW5uC+5A+Q2Ov4 UvnX7feu2P4t/Q1ccNNq5lPEQhuzuDIAeo/OmSXcUX33AzXDkXRPNy5/4E3+NNMUh+9Ox+oB/nVr B1GZPHUkdq2q2g/5bD8jVa61e2aFkEnJ6VyQts9Xz/wFf8KDar6t+BxVrAzI+v0zsTq9jjJu4hnt uph1zTh/y9IfpzXJeQv95/8Avs09baIocrk+5zVfUJdxf2hHsdO2v2I/jc/SNj/Som8S2C9fN/FM VzQtoRaTny1yCOSPeqnlRjog/KvOxUvq8uXc0ji+ZXsdU3iuzH3VY/VlH8zUZ8WQDpCT/wBtF/pX NbQO36UuABXJ9b8h/WX2OjPieSSGSSG1BEYGcvjr+FUpvEt1BdvbuyGRMblGSOffbVWL/jxufov8 xVO+H/E+u+Oy/wAhWsqzVPnSLdV8nMaUniS7kHG5fdR/9cVCfEl3ApPPzHqYh1/76qliq93/AKtf rWCxU27GuDl7asoS2ZoN4pvm6MfwVR/jULeI78/8tJP++1/+JrKpCfyq/byPqP7NoJbGkmvahNGW 82Qder/4AVVfW75/vMDj1d//AIqq9t/x7n6mq/8AEcUlWndmTwdFLY3FkncAmTH0Zv6mnrG7fecH 6oD/ADFNjHyj6VMvQ/SuCeIq33G8NSS+Ei8n/a/JFH9Kq35eC3DJLIpz1DEVc3cVnaq3+ij/AHhR Rq1JTV2c1SEEtEY8l3cs5BupyPeVv8avaWPOeTzCXwv8RzWUTljWrov+sl/3R/OvRrtqDOSqlyM0 fs8QbhF/KoxEvZR+VWiOaixXnKTPNaISgz0pXHyLx3p7DmkkHyr9a9TLHesjCqrRLFx/q1+taWnn 5D/un+VZlx9xa0dOORj2r6WXwnMty/eD/iVD/eT/ANCFUIh/xVV2f9pf5VoXwxpf/Ak/9CFUoh/x U12f9pf5VwQf71nTUf7pFnUB8rVh6gOv+7W/fr8prC1FST07V3QZxnNXv/Hyv+7UWnR77q6+o/lV i8hla5XbGx+XsKNLtpVu7rcGTkdRjPFc2La5TtpLQmkhw34VAYh5ZNXbpWj2nOcnHNQMP3LV55qV bRf+JmnFbECkwcf32/nWRaf8hJfpWol0beAER78u386TK6E3lNjpSeW3pUY1Ud7f8mp39qxfxQuK QtQCHB4pCmeo/SlTU7Zs5SQc/wB2nf2haHqWH1FAtSIwoeTGv5UwwptzsH4CrQvLM/8ALTH1FL59 qR/rVoGUxByfvf8AfRqCe3ULkZz781ph7cscTJ+dV7sJsG1lP0NIabM+zt/NiLMfm3EZAA7/AEqw sMiOAk8oHs5/pU2lxK1oTnnzG/nVs2/zZoFdlQNeJ927mH/A2/xqQXepL0vpcf73+Iqz9nppt6B3 ZF/aepqf+Ppj9QP/AImlOtaknWSNvrGP8RStAcVC9uaA5mS/2/ecFo4W9Mpj/wBmp/8Awk06/ft4 sf7zf/XrPMB4J6emKiaH5DTsPmNb/hK1BCtbLluAA5/qtTHWrdt3nad0bBJKn+dc95YM8PH8QrUV c+b/AL5/kKVh8xdGr6fx/ozoP9ggfyNSpqlgekl2v4uf8azVi+UZFBhUjlB+VFhc5rDVLXtqMy/7 6f4rUi6tEfu6lbn/AH1/+uK51oUzwg/AVG8YA4yPoTRYfOdU2q7V+W4tZT7Pj/GoYNRugGxaoy5J ykwJ/IgVzPlAjq34mk8j3H5D/Ciwc52C6pEq7riRYMdVlwpx7c1Vk8TWP2jZCPNj/vpMv8jiuWeJ thwx6dqoRhpLkROkbfKTyDn+dKw+dHoCa3ZyMFUy7j0ygx+YJqcX9uTgyqvsxwf1riYGuLYYhfyx 6LUhuboksxVyR1ZVP/stFg50dt5qtyCD7igODXFC9mTjy4v+/a/0Apw1OdfUeykj/wBmFFh8yO13 jFRwn97Lz3H8q486/NF3YfiT/MmmjxV5bEl8E9d2f/iKLBzHbswPSkyCBXGDxgmcGSH/AD9SKsxe KhJ92EPgZO2Qf/XosO51e7ml3CuZHieFTiSGRT6A5qUeJbQj7s4+qUWYXR0GRnrTWAPNYyeI7A/e kZP95D/hU66xYy4K3kP4uB/OkFy+Rmo4fuEf7RqJbuOQ/u5o2/3XBp0bMAcjuaAJsCjAPWmb2H8J /KkMntQAPGj8FVP1FQNY2z/ft4m+qCpTJR5gxQMqNpFg5+a0h/BQKhfw9pjn/j3UH2JH9av+bQHo AxpvDGn7GZUdTjjDVAfCdkQDulH/AAIf4Vvu2Y2+lO/hoEee65pkemXSRxuzKy7vm7c1lAfMOa6T xerG+g2gn93/AFrnRFJxiNufarQmIeJDgnpSZPrTha3BfiGQ8elONpcgnMLD6incWpX2ilIIFTG2 mxyoH1YUv2ZgPvIPq4ouMhC+9KBjvUvkHP8ArI8/71PW0kY/KQfoCf6UrgRKgK5z+lNIUVcW0kUY LBfqpH9KPsSEfNcwr6/NRcCkF5pfumrn2W1X718n0CMf6UjR2A/5eJWP+zEP6mgCaTnRIs9pTWdt 561rsbVdJUMsrx+ZxyFOf1rPMtmPu2sh/wB6X/ACgaK4HJOaCPerKXVuo/48oyfd2/xpwvgoylvC PqgP8xRYLlPaR71IltJLysbEeoFWjqkwHyxwr7quP5VG2oTSn5sH35/xo1AvweH3kVS91DEW6BiS f0GP1q4PDdkvEutWyn0HP9awWvJjgeYwA7ULeTjOJAPX5R/hSaYtC5d6VFbOAl5HKp7pkfzxTYra zBBnllYZ5CKM/wBaqm9uCOZWH0pv2qcj/Xyf99GnZhdGnPDo6qphXUJCeqkAY/HFVZLeMsPLs58f 7TZ/pVV55flzK/5mmNK27lifxosFy4InVhizX/gWf8adtl/584fy/wDr1n8MfWl2e1MV0fR/grUL P/hB/D8f2uDeum2wK+YMg+UvFdCLmA8CaP8A76FfOGk+YNHscZx9njx/3yKvB5QOC2frT5dCXM+h BIh6OD+NOyK+e1ublfuySD6MakXUr5Pu3Nwv0cijlDnPoDPvRmvBU13Vk+7qF0P+2rf41OninW06 aldfi5o5Q5z3SjNeIr4z15Omoyn6gH+YqZfHOv8A/P6Tj/pmv+FHKHOe0UV44nxA15etxG31iX/C pk+I2tjqbdvrH/8AXo5WPmR67RmvKF+JerD70Fq3/AW/xqdfidf/AMVjbH6Fh/WlysOZHqFFeap8 UJ/49NiP0kI/pVhfifH/ABaY3vib/wCtT5WHMj0KiuCT4n2X8Wnzj6ODU6/EzSz961ul+gU/1pcr HzI7OXiNvoa838kEk735PTNbQ+IOkXAMax3QZhgZQdfzrJUjaKLW3C5H5CDux/4EajMSCZOD0P8A EasE81CebhPoaYiURR90U/UU7y4/+ea/980A0uaQCjA6AD6UE0maQmgCMf8AHx/wH+tTdqgB/fn/ AHamzTAdRTM0ZoAcar5xcH/d/rUx6VCObhvTaKQEuaGwFo6UjE4oAwsZ1C8P+2o/8dFS4qNOby8P /TUD/wAdFTbeKBsif7p+lNhX90v0p8gwh+lJFxEv0oELijFOOKTg+lIY3ApjAVISB3phBbOAT9KA GEcVHb8qf94/zqx5ErDiJz/wE0tvZXOwj7PL949UPrRdDGFQR0p0FybCaKdUTJYqnXJIHsKsf2fe Hpbv+Iqrco0bWqOu1hK+R6VpTipySMqs3CDkjTGv3/8Acz+H/wCqo/7Xv/MLjcCeo2j/AOKqHNGa 7/qkDynj6hZOrak3QgfgB/jTTqGosOZCM+jD/wCJqMHipAPkFeNmknh0uQ68PXnU3GG5v2/5bsPx /wDrCo2mvc8z5+pb+hqfFRSDmvEWOrPqdLbIS9w3WX9W/qaVEkcndIT/AMBB/nSk4p8HLGnLFVbb kpyY37Nk8sP++F/wqOeLy2UK7dOxxV3HNV7v/WL9Kiniajlqzuwkeaeo+5gCXwRHkCeWDjzD1x9a ijhVmg3bmyw6sT3q1cc35PpGP5VFGObb3Yfzr0lJt7nS4pdCtfW8Iv5wI1wG4GOlc5exoLp8KoGf Sunvv+P+f/ermr7/AI+5BjvXblbbryuRj0lh4s1tGjGIDgct6V2eqkLEBjvXKaOuIrU/7VdHrEnC j3r1qqvNHjxehzWv/wDIM1Ef9Mov/Qq5iz/1q10uu/8AIN1D/rnD/OuatciYUYfZlz6Hba9/q9G9 7cf0p84/4lkJ/wCm39KZroJi0Tj/AJdx/MVPMhOlRcf8t/8A2Wi6silG4yAf6PIf9pf51T1jm4T6 1oQxn7LLwc7k/nVLVIZZJlKRswDdhmlzLmL5fdZD4y/5DMH/AFwSrA6UzxZbTXOrQvBGZEEKAsvI BqUgL95kH1YVvSkuXVnmYuLbVkMPWmmlJizzPCP+2g/xppeH/nvF+DZ/lW6nHucXs59hw6UhpRJA B/rh+Csf6UwzQf8APRj9I2/wp88Q9lIdTuiGovOhyP8AWn6J/iaeZ4wv+qnP4L/jS50P2bEOfss3 4fzqkatmdPIkHky44zkgVV86PPFux+suP6V85mmtW510o2W43NFKZx2tR+Muf6Uec3aCIfUk/wBa 8vlXc25fMtxf8eFz9F/nVS//AOQ7d8f3f5CrUbs1jc7lRfu/cB9fc1XvriRdaukVYcDbyUyx4FdU kvYrU3t+7GAe1V7zPlj61Z8+4PSRB9Ik/wAKgubq6RBifv8A880/wrmgo33N8u0xEbFLacdKDG54 CsfoKk+23f8Az9Sj/dOP5VDJeXh4+23P/f5v8a3tG59nJ1LbL7ya1tpzAQIZOp/hNRrp16WJFrNj /cNNgklktyZJpWPPLOTVUKGb5uee9L3dTnftGuh0qW0yqNy7eO5xT9gVSDJEOO8ij+tU44IwBiNf yqYxqI2+UdPSvPcqd9jOfPy7hiPHNxb/APf5f8aoajFFJAFN7brznlj/AEFTZXHSsvViPIH+9W+H 5OdaHmzk2tWVvsloGJbVLYfRJD/7LWnpSWUbybLzzjjokLDH5gVzXetrQB+8m/3R/OvQxFlTbsc8 22tzcaS2zyZz9Ix/8VUfm23OEuT9VUf+zUrimAV5aqLsc/KKZbcH/UTH6uB/Q02SeIBf9EY88Zm/ +xoxzTJh8qfWvTyyXNWSMK6tEmnucAZtU/GQ/wCFXrGWZz8iQpx6Mf61mTnkVqaXzIB7GvpZQVji U3cvXYlGnHzGU/MmAq4x8w96rK0za/dojKihhghBk8Duavaj/wAeAHTLp/6EKpQ/8h+9/wB4fyrh pJOozeq7U0WLpLhVP+lSH8F/wrFvpbmNvluphx2bH8q6C75Q1z2on95+FdsIRfQ41Ulcw729vVmV Re3O0j/ns3+NM0gPcXd150srkEY3SN6fWmX3+vX6U7RB/pd2fcd/asMVFKOh2UpNl/UE8i33o8gO f75P86z2uJtnEjH6gH+YrR1Nc22MnrWasYNvnnt3rz7G1yK3mnfUokYpt7kRgH9KvySbLZPlVvnb 7wPr7GqNoANSTFW7gA26Z/vt/Oky0yMyjvGn4Ej+tIZkz/qvyk/+tUW1fSjAHOBSAkWWLJwjj/gY P9KXzYe4l/AA/wBagTGT9adkUATGSE/xSD6p/wDXpCYCCPM5942/wqIUpPH9aAHqsJBxKh/4CR/S jCjP72If8DAqMYGeaRgGByKACBSqth0OWJ+WQf41MVn3AoW/B6p2nETDtvP86kYAuBtHqeKQFsG8 XkNJ+dSJcXgPLv8AjVMKvYD8qt2q7j1P50xWLkUl05+9+dWDHOV5dfypYbdGHO7/AL6NT/ZkA4Zh /wACoEZtx5sSD7p5qEqSjZParN+DFGCHJ5xyAf6VRedghxg8dxTCxF0uYuSfmHWtAXCweaWVmBc9 PpWS1zL9oiAii5Yc4PH61duX2JIcZw/TOO1Iqxaj1K3K8xyCn/b7QjlXH1FZSuNv+r/8f/8ArUvm Duh/Bv8A61BPKXWvrEsRvxz/AHTTTc2JHEwH1zWYzw7zkS5+g/xprG3YfekH1Qf40BymsstqQMTr +dP/AHBHEyf99CsTbbkf6wfihoKQdpU/Ij+lAcpsyRqUJDqePWsu1QvqajI+439Ki8uLr50Y+rYq Noi1wrLNGcA/dkFAWN77O3bFIbdvSsgJcD7skn4NSlr1ekk1AWZqGBt3SmPA2OlZv2m/V/8AWvj3 WlN/eD/lqD9VoCwXduTwRisKe3YStz8vatO41C6yAdh/Cs5riWSXDqoB7ikGpXa2w6E9zW/piBYp CB/BWRMRtQgrwfWtfTpl8mQE/wAHYZ/lVWDUbdxb5i2Ow/lUHkKO36VNc6jFFMUaFzgDmoxqtr3S Qf8AAaQNMaIsdGYfSlO8D/WP/wB9H/GlOq2XpJn020n9oWjdAw+tGgrMY2/+8T9RTlllQ/K2D7AD +lL58DHhk/Fsf0pxeHj95CP+2n/1qB6ijUL1M7Z3+m40kGvaoJVXzuD7n/GpUu40OVFqwx90jdUU OoymYqsdqu48EQAlfpQM1hrEiW4a51hYWPVfLDfnmnR64RETbalFMR/AYcZrMn865QpIysp7CECm xR3EChYmdB6KqilYrnNQeJL8/wDLupP+5/8AXp3/AAkl6oy1sn/fBH/s1ZW278zf51xntlhimm3n LlzJJuIwSZKBcxq/8JVcHgwRf+PVKPFu0fPCPwz/AIVgNaS56f8Aj5py2Lt1/wDQjTDnLGqaymoy B0JQqMYDbQf1rOeRwQHVuf8AbJ/rThDIs5jXYoHquc/rVn+yr+aQtbiOQLwcqB/OldroUncfZm1i iFzJPAkoPyrIrOfr1FSTXOm3abjdRvMP+mJA/nVWTSNXzg2y4/2USqp0vU4ThbWUD2j/APrUPUoY 04DHEMfXrg0guJCeFQfSNf8ACh7O9P8ArI5xjttI/pUBhlVgXEox0JJouFiwbicHHnMvsGxUbSu5 +aVm+rZphBPILE+pNJlxk84phYlDBRgkUm4bf/rUwEHOSc/Wk3DHJ/WgQ8Hn/wCtTi3I6/lUO5eO g/Gl+XPUUAaBlB0org/6329Ko78dAcfSrGR/ZEnHSUc49qolsHPagZKpXknP5igHj/64qIOOaTd9 aYidmBXtn600Mc9vzqMvxikDemaAJyxzzgU0HnOR+tM59KTdtz/jQIeXweq0Bs46fgKYOeTikLHG BigCZm45J60jEe/6VXycUqkg5pDsTA4PU07d7momYnHPFN/OmB2NhE0Oj6a27KvaRMB6fKKsKxzz TLZv+JHpA/6cov8A0EU5MVUdjF7jt57ClAJ71H35p4NMQ4KBSY9uaKQntQAvHbmjGewpyRMVyKcY XBPQ4HY0AR4XuBTQqk/dp6xtIwVR8xPFaKaFetGkn7sBx8uXAzRdIaVzNCLzkUhVR2q7Jp88U6xS AAnoc8Vefw+gTIv4i2M4x/WlzIOVmHsU0m1B3p0qGKRkJHHGRUYzmqEO2D8KNg96Bnvml5FAE9kB 9pj6j5hXaKRiuNsgGuoxyDuHNdYqNt5k/IVMi4k+ai/5eF/3T/Sl2H/no35D/CoxHm45dvunv7ip KLIIpdwpnkr6v/30aPJT/a/76NAD9wFBYYqPyY8/cB+vNHkx/wDPNP8AvmgBquvnNkgcDrT/AD4+ m9fzpkaIJnwijgdBU/agCPz4+zA/jR56+jH6KTT6KAGecP7r/wDfJpiyfvThH+6O1TVGp/et9BQA pkb/AJ5t+Y/xpjvIQcRn8SKlxTH6GgDEiMn2m7O0Z83sf9kVZBb+4fzFQQt/pF2f+mx/9BFT7vek MbIWEbfu26e3+NMRgIkyrfdHallf5G+lNVyI1+lACPIB0Df98mr2kxxyxyMygnf3HsKz2fNaejn9 zJ/v/wBBSYzVjijHRF/KrAVfSoUNTKaVgJFA9KlUDPSolNSKaLASdq4zV8nUYxyf30ldmTxXE6sz /wBoIFkkUNJJkKxGefatsP8AGrGGIt7N3HhW/un8qXy5D/Cfyqt5eeryH6uTSGCM9VB+teveR4Vo F0I46g/jUodAoBkQfVhVBbaH/nmv5VejhjC8Io/Cvm88a05j1MFFNOweZEOs0f8A32KillhyP38f /fQqx5SjsKq3CgMK+dhOnfb8Tu5SMyQ5/wBcv4An+lPglhUt85b6I3+FQkD61YshnzPwrSc4KOw1 Al89OyyH/gNVriaMyDKTDjptH+NXiMCqN1/rR9KmjUjzbHZhINyJXuAblj5Mu7Z0OPT60kcpJtws BOD8uXA/pQT+/Y/7H9KdEMyWw/2hXr05p9DacGiC7mY3cu62G7PP73j/ANBrAu7iIXLhrMFs9TKf 8K6C9/4/Zv8Aermb7/j8k9N1d2V+9XkjHHq1CLOjsWl+zWzIkSKegwTj9avanJcqw3yRt/wD/wCv VS2O3TrI1PqsmXH1r1+S8jxnJpGfrUzw6dfyoELBIeHUMOvoawINSumlA3Qr/u28f/xNbmu/8gq/ z02w/wA65q3/ANeMe1TQimmbNu6O11YzRQaQy3Ev72HLc+46en4VPJEw01X86bd523PmN02/WotZ GbXQv+uH9RVxx/xK1/6+B/6CazaVjohG6IktlNlM7NIzAryXJxz9aytShRWXA/i9a6BVxptx9U/9 CrC1Hkr/AL9EbXLcfdZD4wtoo9VtwkaqDAh4FWxBGoGEUcelReM+dWt/a3SrWOB9K7KCXKeNjrpo i8tc8KKNozTyKSujQ4AC8VCep4qwB8pquRyaaEGcYqR+FH0qH0qV+EH0pMQx+IJPoKqDpVuX/UyD 2FVADXzebr96jso7BRS4owc9K8dG6LCHGn3P0X+dVr4/8Ty7P+7/ACFWlB+wXP8AwH+dQXkMra3d ssbFSVwQPYV2TX7lHRb90R1Wu/8AVj61f+zTH/lk/wD3zVe5tJ2QYjbOe9c9OLudGW6YmLZmioZD 81XvscoHOxfq6j+tVpbVi5zNbj6zp/jW0Yu59nOtC24tqB9l/OoYxmT8auW8KLb7Tc2+eekoP8qZ HDCr5N5B+G4/yFTyvUwlVhZamqn3RT5BiFz/ALNIj24H+uz9I2/wpZJYfJfl8Y6hDXAqcuYwq1Fy so5+WsrVj+4H+9Wtvt9uMzn6Rj/Gs7UHsjEPM+1Yz2Rf/iq78PRtNHjuoYQ5rc8Pj55j/sj+dZ4f TB/Bdt9So/xrX0ea1DSfZ7aU8DO+Yf0WuzFx/dMhSuabDNRipWm/6dR+Mv8A9amCY44t4h9WY14s YK247DCOabP0T61KZ5M/6i3/ABVv/iqZPczKF/d2/J/55n+pr1MrSVdWdzmxK9x3I5eorU0nmf8A A1lyXM45zGP+2S/1FaGlyXE820zlRg/cRR/IV9PKUuXY82KV9zY1P/jxH++n/oQqpCv/ABPr0gfx D+VS3yGOybdIz5dOWP8AtCq6h5NZvFaaUIGGFWQgDj2rgpX9o7HTWS9mrmhcIWU4BNYN/azySjZD I3HZTWnNbqFPzyn6yN/jXP6isazY3cY7tXdFyOGPLcp3elX7yqVtZSAOpWmaXbS215dedGVyRjP0 qhdiEzLymMVLovkLd3e8JjK4yAe1YYrm5dTspWNa/RngAUE89hWesbiBgVI57irV+0KwAxpg7hyq GstriQfdeUfTcK883H2wI1JCR2NWJ/8Aj2X/AH2/nVGCedtQiBlmZP7pJ5/Orc0zpAoVGB3t2U96 TLjsV6QmnefN/cH4otIZ5AOUh/Hj+VSFhkfQn3p4JpqXBxzFbDn1b/GnecCP9XGD7E/40XHYAaCe DTd7k/c/INS4DD5kl/Af/WougsIhzu+tPHQ0ixcYC3Ix7LQ6LGuWNxz/ALK/40XQWILU/I/++afu w5+lMtofMRmTeVLn7xx/Kpmszwd2Pxf/AAougsOB9TV20PGc1S+yHvs/Hd/UVPbwqh5a3/Ff/r0J 3E1obcUqKOXUfU1IbmHH+tT/AL6FU4WRf+WsS/RP/r1Z3Iw/4+ufYD/CmTYoajNG0IxID83Y1R3q Ubhjx2U1o3kPmRgCZ259B/hVQwkI2S/Si4W0M8uPtMXDZ3f3TVu7kJST5HxvyfyqsYiLmLO7G4fx Gr0kETeaGz97j5j6UN2RaKKyfL/qm/Mf40F3xwh/E1ZSC32g7PzpTDbjP7taz9oh8plO7bzwv/fV MLkjB2D/AIFV1lhDHCCkJix90UufyHylMMcDlfwo3N6j/vk1dV4gB8i/lTvMQfwr+VHO+wchQO4j 7zfgtQhcTIfmzz2FahmXBGB09Kpq4S6Q/WmpXWwmrDfLJ6qx/KjySOiN+Zq4Z+aT7TxU877FcqK6 pP8AdAk/77NL9llznY2fck1MLogmg3Rpc8g5UVpY7pPuj81H9aqvJcxHc6RY941/wqxc3ZyOf1rP mnMjbSaUZSbBpJDLjUJG2gJH/wB+xWppLSypJu2quw/dGKyJo8Ipx3ra0cfuJP8AcNdJlcLi3Vps lUOQOWc56VGLKIjnA+kp/wAKi1G4Md0VB/hH8qp/a29a5ZOd9DdKNjROnxZyG/8AImf6UhsYR3Y/ TFZ/2tv71NN23rSvMPdNIWlmPvLL+S/4077Lpo+8JR+H+ArJN03rSfaGPem1Jhoa5t9LH3d2fcH/ AAqrFHbeeM3MRUE8bsGqXnMe9Rj5WU981cIuxLaN/bAMbZYz/wBtKDuA+Rwfo9Y3mHuaXcDRyC5k ajtdbflLj3BzU+mNcPclZ3Yrt/iGKxQR6CtPR9j3e1wCNp4NaQVjOTTN14V2jGDUewAipXhtgmdg B9jWdcFVGIw2f941RmirJxfv6ZrpNHPM4z3X+VcaJLg3LKZCPwFdZoZIEoY5OFyfXrQ9jWJt5oPW m5oJqSwIyOlNKqeoFKTRmgdyNoIm6xqfqKwPFMSRaOzRoqkOvQV0RrB8V/8AICl/3l/nSBHB+cQa es1Vt3OacCKq4FkyUeYc5qDfSh/pTEacchbSZuekgqjnFTQvmwnH+0tVC/8AnNAyXd60u761CG4o 3daLgSbjSBzUeTSDOaLiJWahX45pnJ7Gl2tgfKfyouOw8nJ6UbqaEkPRW/KneTKf+Wb/AJUXCwF8 jqaTOO9L9mn/AOeT/lTjbTdCmPqaLgM3H1o3n1p32WXvtH1cf40fZZP70f8A32KVxHo+jacLnw/p jyy8/ZIsbRjA2CrR0VM5EzVy+k3t0mkWSrFCVEEYBK/7Iq8NTuR/y7w/gD/jT17kM2f7FHaY/in/ ANeg6Mw6TA/VayBrFwB/x7r+DMP60o1ucdYW/CVqevcVjTOkTDpJH+v+FMGkz7gWZMdyD0qkNdkH WKX/AL+n/CnDX2HWOYf8DB/pTuwsaP2PyxtG9gO4Wni03sSSwyPUVnDxD6if8lP9KcPES9zP/wB8 LSA0otNiUhtjvj/a/wABVzyjxmE8dMisQeIo/wC/J+MY/wAaePEUX/PUfjEf8aANUoobPlqD7077 3XH5msoeIoe8yf8Aftqcuu25OfNiz/usKLDuaDQROctFGT7rSrbxDpFH/wB8CqI1qBujwn/gRH9K sRX/AJq5jSNh7Sf/AFqBFkRqOiKPoopsu5UODj6Uz7S3/PH/AMfoeVWjJKkHHTNAxtuzmZNzE896 2x0rBteZ1+orcHSgY7NRj/X/APAaeQaYn+vP0FAFgGjNJSZFADiaTNJQcUAMT/Wt+FS54qJMb3+t SZoAU8UmaTcPWgsB1oAD0qNP9a/0FOMsfdl/Oo0li8x/nXt3pgTVG/Q0vnR/3gfpUbzLtPDH6KaQ GLE3766/67N/IVKZMd6oCcCe54bmZv4TSm4Hr+lIZYmkwjfSmrL8i89qpS3C7Dlx09aZ5y7R846e tIC804HcCrenapZ28UizX9tCd5OHcA9B6msCWQMD8w/OsiJEk12FXwVIOc/jQxo9EHiDSVHOrwf8 BdTS/wDCTaOP+YqT/urn+S1wdzbbbr9y6BfQOBWtd28UmwBlyAM8+1RcDpv+Ep0cD/j8uH+kL/0W geK9KPKi+fv8scn/ANaufEECWaozDknt9KfaxW8SuVdTx2o5gNweLNOb5UttQY/59WqhdyrPPbSK rKHLsA3Uc96htktg5YFefcCn3DxrLbbt+fn2hVz3+tdGHfvowxCvTaJqMU3zk7RTH8F/xoE2ekMn 4kV6vtDxfZsmTtVtT8oqisrdoPzf/wCtUwmmwMQp+L//AFq+Zzz3mtbHs5fC0WWc+9Vbk/OPpThL P/zzj/Mmq1xLMHGVi6dwf8a+fp01zfEjv5fIax4qxYniT6iqRml/uQ/98t/8VVizaZw+GRMH+Ff8 TW04R5dw5TRY5qjdf64fSpsTf89z/wB8r/hVWczLKB556d0X/Cs6UYJ7nXhU1LRE3V84/hqWHPnW 3H8QqqTLkfvn6ewp8Su8sIM0uC3IDmvRoOPc1qqXYW7BN7NgfxGucu7eZ7uQrDIfm7Ka3LhGFxIo lm2g8DzD/jXOXkkgupFEsmA3A3mvVyr+NLlOPHt+xjc6gRyCyslCNkdRjpS36SSOCqk81nSxRC3s sopLD5j6028SISDCKPwr3IxlueHJxLesxNLp1/GuNx8kYJA/nXPwWciT5Z4QPeZP8a29f+bS78f7 UNc5bKBc9scVhRvyuzOxJOSR2uqTwS2+kKs0eYosMC3uOnr+FW/tMB08JuJ/fBshDj7pqlq0sHka NiRMiDn5hxyKvrPAdNX97HnzwfvD+7WTbsdMVoPa7h/s2ddsvJX5vLbA5+lYd3NE4X5n+/8A88zW /JPF/ZFyASeU6KT/ABVztzKp8sAP9/8AuH/ClG5bjox/iiaKbVImmWaFhCg2lASR69asG4PGLeX8 dv8AjVXxdKr60hCvxEg5Qj+dXd7cYgk+vH+NdlBXW542O0toRec5/wCXdvxYUebJ/wA+4z7yf/Wp 5kf/AJ4P+a/40xpHH/LMD/eat+XzPP5vIUSTYP7mMf8AAz/hUJeYn/Vxj6kmni4Kg5MA+sv/ANaq 5uOT88I/7aZ/pRyruHM+xJunx0hH/AT/AI06Q3GB88fTsn/16g80kcSR/gpNPeSTaPn7f88G/wAa HFBzyFlM6o2ZR0/uCq6vOR/rsfSNf8KdcO+Dl35XtER/Oqy+Z2M35L/WvBzT3Zqx00pSZY3Td53/ AAAH8hSZl/57y/g5FRYk7ib/AMcpuxifuyfi+P5V5Kk+5td9zRiz9gucu7cp95if4veql+S2u3gL ttBGF3HA4FPSNzZTHZxuTrM3r6VUvI2OtXY2L94dXJ7CumbfskdDb9mSGKPuoP1qtdRRCIEIoy3p UvkH+5CP+A5qC5gIhU4i+92j/wDr1jTu29TfLn/tMSvmJRyVFVZXj8zhlx7GrQRscMPwWq0qnzPv t+lXF6n2lRO2xatpEFrjOevTmo4XXzejdf7pqW2jJtvvsOvpTYIgZOSx59azb3MJJ2Rsxyrj7j/9 8GnyyH7O+In+77f40kcC4HL/APfZ/wAafLbxi3k+U/d7kmuCm06iRz178jMzzGx/qm/Mf41maozG EfIRz6itLyo8f6tfyrM1REEIwig59K+gpUrSR857RXMoH2H4mtnQpdrS/Mg4H3mrGAGOlb3h8fNN /uj+dVjlaizWm7yNIysekifghP8AWmB3/vH/AL9NVxhTQK+bUjr5StlifvSZ9o8fzqG43kJzN19F q/tOaiuVOE4PWvWyl3xCOTFq1NspSCTaMib81rR0eN2uMBGPyn/lqV/lUEkTkcI34CtPRYpFucmN gMHqK+snblZ48btk+oQSC0JKD7y/8t3PceoqKK2J1a7BihzkcHLdvpV3VHCWhDHBLrgHv8wpIYnG q3chUhCRhj0PFedSt7RnVXT9noQS2nB+S2H/AGx/+vWFqEJW4/5ZDjtHj+tdRJt5y6j6sKw763Mk 5KvFjHeVR/Wu+Lj3OCCnfY5u4RvNX5u3YU7SFY3t3h2H3c4xzx9KuTWLGQE3FqB73Cf41FpyLbX9 1umhbOPuSBu3tWGKlHk0OukpX1LV9F+4GZHPPc1mGIY/i/76Nal66SRAKy5z/eFUxExjbjJPQAiv NR0lO3jX+0IxyR9TVuWJBADsXPmN1+tRQQSrfo7RsFHfFTyhmthtUt+8boPelIuI2ExYw0UZP+4K kLxKDiNB+AqoCy9Vb8RSNKcHg/lWDjqaJk6yjb0H5UGb0qoshK9/ypC7dgaFALlvzzTWnOOtVN7e lBZ8dqrkQuYteed3Wmu+9cGqoZi3UflUi5OfmHT0pqCQnILSTYjgf3zUzzkkDNUoc5l+Y/fNOOd/ 3j0ocQTLwnNWrU7jnqaywBjqfzrQslG3v+dNKzFJ3NuDGOamYIRyFP4VWhUYqYqMdKsyM3U1iSEE Io+b0rNdhtO0gfStHVAPs44H3hVNUBQ8DpQUnoZzPI08YWeQAsMgOa0bqQxJIwYqd46fQVSYf6RF /vCrd8f3cv8A10H8qGUiD7U2Pvn/AL5H+FBuWx1z/wAAH+FQg8UhPGamw7kTXhyf3cf4rTTeDHMM X5N/jVZj8xprH5TRYLlr7VHgfuV/Amj7TCTzCfwk/wDrVUB+WlzRZBctGeDOdjj/AIGP8Kjea3Mq ZEykZxwD/WoeCRkU2cDfHxjk07ILlrfAf+Wkg+qD/Gj9z/z2P4oaqED0owvpSsO5ZxED/wAfC/ir f4UpVe08f6j+lUyBuGKDiiwrj54C+MSw/jIB/Oq62cvng7oiPaVT/Wo7gkDiqqMRKDSSVwuas1pK 0ahU3EHsQa09Lhkihk3oVyhxkVzU4ZgpPStnRYlXcwHOw1oSitq0MrXm5InZdq8hfas4pIvVGH1F X9XldL3CuwGxeh9qpC8uB0nl/wC+zUWRdyPJo5qYXtz/AM93P1OaX7bcd3z9VBosguQDNKKm+1y9 xGfrEv8AhThdt3ihP/AAKLCuQinHgL9amF0O8EJ/A/40C7B+9aw4z2J/xpiI6UE1N9ohI5tgPo5p N8B/5ZSD6Sf/AFqdhEfNaeigm+wOu01QzD6SD8Qa0tIZRfKY1ZmweDgU0Jm+8Z2mqrw5NW3kmC82 5/BhVSScpy0Tj8qRBkTps1BhWgurQaa586J3DgY2kf1IrNnuYXvGffj2IOanmhhvCjFSwAGOKG9D SJpjxPYBQz292gPft+jVIniXTWBO66UDvsY/41mT2cM9rGpQ4U8ZFC2kP2GWAAgEYzg+tZ8xoa6+ ItMY8Xkq/WNv8KeNd01umpKP97A/pWFZ2MMSugOWIOODUNjp8McpMj5z0BNHMFzpl1ixYfLqdsfq 6/41m+IbyCfR5VF1BJyOEIyefrWNHYR/bG3spTcerCsbXIo4dRdYwoUAYx9KL3GiEtECeGP40geP P3G/76/+tVZc4FOzzVAWg8Z/5Z/+PU4SR5/1Q/EmqqswBGeD1pSxxTA04XT7LMdi4GMrk4NVzOna KMfgabC5+xzfUVXD0CLXnjjEaD/gNH2g9Aq/98iqwJNKGx9aBlj7Q+ccD/gIoFxJn72PwqDPNAeg RYNxKP8Alq34Gm+fKf8Alq//AH1UW6k3YFAEpmkxzI3/AH1RuJGSx/OoicilUkYIx+VAyxGufmHz c4xmnugJyq4IHKgGkS4dmDM3TsBjipVkJbKkKe26sZSkmUlcqk46DH1pM+4q+0RwGyrEnODjApPs a/8APeL/AL5P+FNVkLlZ2+iWJfQNObb961iOT/uir39nAddv4kV5/aJfDT7UiO4KGFCpAJGMDpTg 5ORJL5bg4KyZBH51sZs7xrGIDmSIfVxURtLUDm5tx/20FcnHp80rBUmgbIyCJOD7VIulXJTcXjwP vfNytHzFr2OmMOnj719aj/gdMKaUOuoQfhk/0rnm0i7GQuGb+Ec/NVWTT7+LloSQDzt6j88UrruP XsdMX0UHBv0/BDTTLoY63rH6RGuUkjaI5mcQg9DKjYP4rkUgilkj3x3Fow9PNAP5HFPQNex1JudC H/LadvpHTTd6CO10x+gFcnLK9sP3gicnoY51b+WaiGoKGJ2HGOFbnn8MUaC1OvOoaGo/49rpvqy1 F/behq2P7PnP1krmFu2nQ4uoIMdFZTk/iAf51V81mbc7sxB6g5o0DU7Ua3pY5j0rj/alNTJ4lhj/ ANVp8Sj3c1zttqWjxRqZBLvH3w/Ofpipf7Y0QZXEpXqv7oFh9eelK6Kszf8A+EqPa2hH4E00+Krg niKAf8ArnptW0SQ7jBMSP4VTaD+T1B/alimVhN2qHoCFIX885/Onp2CzO00nXLu9v4oCsIVs8hMd q6xFlx99B/wE/wCNef8AhTVXvNahjYKVAbDlcN0+uK9EUjFMQ3bL/fT/AL5/+vTFR/OYmTsOi1IX UdSB9TUQniEjZlQdOrCgCXY3/PVvyH+FJ5Z/56v+n+FH2iHH+tT/AL6FJ9oi7Pn6DNADhH6u5/Gl 8pfVv++jTPtCej/98N/hQZ1x92T/AL4P+FAxI403v97r/eNSiKP+4D9earxT5L4jkPPp/jUvnN/z wk/Nf8aAH+VF/wA80/75FHlxjpGo/CmGV/8Ani34lf8AGmG5I6iNf96TFAFjAHQCo1PztUJu/wDa t/8Av7/9ao0uTufDQ9ez5/pQBdJNRuTtNQ+e56OPwiY1HJNJtPz/APkBv8aQHPB/31x/12f+dKWz VRJGMkxy3Mr9E96Us/8A00/IUgJJm/dtz2pm75RUEpfYc+ZjH+zTcMR0f8WH9KAJJMEdKy7faNfi 44CnOB7GrkitjOP/ACIaoWuTrSDbk7DxuPoe9J7DRZu/Ja8JLbT6bataq0LqgbzAB3Cg54+tUrkx fayGgIb2k/8ArVZ1IIgQmFCM8Y4qOwFhJIk0XYN7LlucAEdPeo9JlhRpCrNnb0cgUsYxo+5YoguW 4Kn/ABpNHy7S7ESM7Oqg88+5oQFiGaH7QWJP3v8AnoP8K1biaNrm1IP8LngZ71lwo3nck53dQorV niP2u2G9z8jfzrpw/wASMMQvcZN5yn+F/wDv23+FKJlzwkh/4AaBAvq//fZ/xpwtwf8Anp/32f8A GvSueTyocspxxE5/L/GpRK+B+5f81/xpq2q7T+7zx3yaetqmP9Qv/fNfM53dtHu5bH3GIZnA/wBX j6sKo3VwfNGfKHHeT/61aQtR2gH/AHzVS4tZPN+WE4x1Arw6UHzbHe0jPNx6GH/v5/8AWqzYTnbJ h4+vYFqGgkA5AH1IFWLFRGsm+SJSW7yD/Gtpwly7CsiQzSY+/wDlA3+NVLiRzJ949P8Ankw/nWiZ Ie88P/fYqrO0TSE+fFjH96sqdOd9jow7SluVyZCBhpfwUD+dOgMnmx48773+xUxeHaMzr+AJ/pRD JAJVPnZwegjf/CuukpJmlRxaK86yGd+JTz3YD+Vc1dhvtcnB+8erV1kkluZGPmt/37b/AArn7gWJ upC11ICWPAhPH617WU6VZNnn5g06UUi1cKwjsxt/hH/LVj/+qmXCEyrlE69yTVi4ltD5AJuflAxi Nef/AB6mtLatKMLc591X/wCKr37qx4TTuP1qDbp14dsORJEPljx29c1iW0f+k/wdf7tdDrLhbK88 1C0fnRghDg5xxWRby2vnnFtNuz3lH/xNcdN+6z0aavM6nVIn+y6OfMP+p4AUDHIrQjhc6Wp8+T/X +i/3fpVLUpZfs+mrJbxlfKzHiQ5A9+OauxPcnS42CQhDMeDknOOtZt6HUlZE00J/sa5Jmk6p3Hr9 K5ySIM8Y3Ofn/vGuguGuxpE7Fodm5AV2Hnn61hrJM00a7YBlhzsPH60RKWz0GeLYVXXAuX/1adXJ 7e5q/wDZY+Mpn6kmqfiOW4j1t45DFKwCje0Yz0q/tuCP+Pg/gi/4V10G7bHj5gl7utiE2sP/ADxj /wC+RSfZogeIUH0UU8i4z/x8v+Cr/hSbZjx9ok/Sum8ux5Vo9xVTAOFx9BSwWFxdyFYYmY+wrV0r RJLoebPNMIuwDkFq3RpFoowEYj3cn+tc1TF8jslqdlLB865m9DGt/C7kA3MyoPReTV7+wtNRMO+7 A/ikx/Krn9lWY/5YL+NZGt/YbWAwRQx+c46hR8orlVarUlZM6ZUKNKN2jn723cysI0O3HFUVtpR9 5cfUilu7eISD5F+76UkMEePuL+VY5hS5rcxwxnBPQUxY6yRj6yD/ABppWPPNxAP+2q/40x40DHCj 8qjKgdhXh+6nsdN4lrzIo7KUGQOpZMmM7sc1XuPJfVruU3EabmHyHO4cdwBVqFR9hm/34/8A0Ks+ 8A/t2+/3x/IV1Sa9itDobXsiwfs2ObtPwR//AImorj7KYlBusc9fKf8Awph5qO7H7hP96lRSs2ka 5c08VBIbiyA/4+ZD9IT/AFNV5P7P38z3BPoIR/8AFU2q0v8ArKUZK+x9rUpyt8RqQvZLBhRdMPXY o/8AZqWB7MONsVyT7lRVe3GbepLdfnH1rCU0r6GMqbtubEc0Y+7bP+Mo/wAKdLP+4f8A0UY28/vv /saZGOBT5x/o0v8AumuSlUvVSt1OPExtTbuZf2mPHFmo+shP9Ko315GseWsYGGehZ/6GpiTis/UP 9X+NfVQp6nykat5EI1GMdNOsx9Q5/wDZq1tGvXleQJb2sWBn5Iz6+5Nc7jitvw+P3kv+7/Wsswjy 0JNHbh3eaRume4HRox/2yX/Cmi4uu0yj6RJ/hQ3emgda+WVaXc9T2aHfabrP/Hy34Ko/pUNzc3ah MXUwyecNinkc1Fd/cT616mVTcsQlI5MZHlpNojkuLn/n8uP+/rf41d0kPNc4lllcY/ikJ/rWe55r S0Yf6Tn2r62cIqL0PCjKXMX72CNbN8KPvp1/3hTEt4n1y8LorHI6j2qa+P8Aokg/2k/9CFNgOdZv D7j+VefRX7w6a7/dj2tYQDiNfyrA1GNBcEbR09K6Ujg1zmo/8fLV6UIo86Mncxp1AkHHal0fA1C8 z1+X+VLcf6wfSm6QP+Jjef8AAf5VhjP4Z10H7xe1Yj7Oh9JBWY4LISelaOq/8en/AAIVT4MBNeUd hTghX+0ojjkHNXbhiLYYYj963Sq8A/4mEdT3f/HsP+urUMuJWE8gH+tk/wC+jQ11MFJ81+B/eNQZ NNkPympsMsLdSleXJ47gUv2mT1X8UX/Cq4PyjNLk0AT/AGhu6xn/AIAKQzjvFEf+An/GoM5oJwDQ BKJ0yR5EX4bv8aesq84hH4MaqD7/AOFTx9/pQIbDLC28+QwO45xJ/wDWpQ8Dv/q5AVP98HP6VBCf ml/36chwT9aALIMJ/wCegH4VfsymBsDn6gf41litOw+7QJmtC744iY/iKnMjbeYmFMgOBU5f5aZB k6iQ8GDlORywNVsqEOXHSrOrHNqP94VnFSyfhQV0IpAvnRnzogAw6uBVi8UukoBGd46nHas6RB50 eRn5hV+/XdG/s4P6UFIqiGXA4GfYigwSkf6tvyqKmnoaQFd7a4DH9zJ/3yahaKQDmN/yoaVwxwzD 6Gk+0zgZE0g+jGgYbWA5Uj8KQ59KeLy5x/r5P++jSm9uP+ezH680ARjORS3P3o/rT/ts56sp+qL/ AIU2S7mDpu8tgT3jX/CgTI80Z4qX7T6wxH/gNH2hD1t4v1/xoArkncKdnmpfOi3DNsn4M3+NBlgP /LD8nNAFK4BOMGq0Y/fqDWhO9pgboJPwkH+FV0ey85SI5gf98H+lAMfMg8lT71q6N/q3HfYazpri zEYVjMOewBrQ0maElliEpyp5dQP61QkZusf8fi/9c1rPrX1SOBrhDJMUbYOAmf61R8i3PS6H4o1S UytThVj7PF2u4vyb/CgWw7XEJ/E/4UCK9LirH2U9pYf+/gpRZv1Dxf8Afxf8aAIRQ33Rj1qf7JN2 VT9GFDWdxgYiYnPamIiFKDin/Zpx1if/AL5pphkHWNvyoAN1aGjuVv0Psazwjeh/KtDR1P8AaEef f+VMlnTPK2ys+cGTgmtNo8pVV4+aRKOfkgEd4VxWpCMMAB/CKqXy41D8KfPdG1KHazZUfdFJ7GkT QDEwjKAc+tAYlGXy8Ad81SlvjbWqyS7mDMAAFHFPiv8ANpJcH/VBem3msbGhchYB8eWeR1qCPaJR 8rH6AVFZ6h55LRBdo65U/wCNR2uoxzTbYdrEdQQRRYBdsS3jEg/e6YrnPEYB1R9oIG1f5V0H2oC9 bEe5tx7/AP1qwPEpzqW4rglF4zVR3GtzKAwOtL3pF6UHg8VYDhzS9qaAaXnBoAswf8eswz6VAO9S QH9xMD1wKksVheQrMOCOOTSbsrhYhBoJq+LWJMqTkk4Bx0ps2nSCTEPzJjOSRUKtErlKW7npSdKn a0mjXcduMZ+8KclnMzAFNuRkFjgY+tVzx7isQBsjoantIvOfBXI9K1LW0j+y5RVMoPLEHn264pY4 ltm+YKSRkcdKwliFqkVylT+zTITscDHYj+XrVyGwigjLOFkk7K1MZij7lO4dcGnrIAQ2Bgdcd65p 1Km1x8qKbW0TqSow5Of/ANVWbazdFJfOMYxjOae5JbenyA9cdKZ+8kkZftCnvyetV7SdrDsRy7o3 2MhHYEios/7a1LIspgyWLAH8Kq7T6fqK1jZrUQltd6olnAEdxGEUL8owOO1TpLrU4Oya4PqQxrod Hs7FtLtXe5mYGCMmM9N20Z5xWgttpjMyeZIuR3P/ANauu6M7M4kaZqbSbhFLuz1CnP8AKpns9aL/ ADm7LLxyW4rr2stNjAImd2HOzdk/+g1K+mabKrul2oZx0Yf/AFqLhZnC/YbxTiYzhSeevP50r6XM 0ZkXzNoPVsf412MOkWjFsXWGz27VYTToSJbX7WhJwQ5IApJ3CxwP9my9cNTl0uQkdfxru/7DCpmP VQP9kY/+KqSPQ5V3f8TRCW+6S4GP/HqoTODk0h4pNpZScA5B/wARSjSu+R/Ou5udCuLiUn+0I9uB gF8jgfWpYvD94tuyi4gcnG09f6UaCOQsfDc182yDBkOAqkdfxzWg/gTWolJaCID/AK6D/Guz0DSr m2vo3laFlDDlF/8ArV0t8P3ZxSk7bDSueGano1xYSoJ1RS3TBzTDYrA+JgW4BzGB3+tdV4stJriW 38pC23Oar2mh309lvWzRpAwHzNg4x9aIu4NWOfWC0wuJCSexXBH6VfjsLT7MZH8wYIGRWp/wj+oC TJ02LHs//wBlVttHuBYBRYqZN4JUMenr1qkJsseFtOtzOZohllHBkGevtmuvFr7Qf9+v/r1heHLa a2WQSW/lMccE10QMv91fxb/61NiGC2I6GMfSMUqQsHbErD6Af4U/Mn91P++v/rU1TIWbhR+NIB/l P/z3k/Jf8KPJ9ZHP44o/eH+NfyP+NH7z++v/AHz/APXpjDyF/vP/AN9mkMCer/8Afbf40fvO7r+C 0Yf/AJ6H8AKAI4rePL/Ln5u5Jqb7PD/zyT8VFRwoSH/et94+n+FSbDj/AFj/AKf4UCDyIe0Sf98i nBEUcKo+gpuwf32/OjylPdv++jSAef0piY3P9aDGuOrf99mmJGmWyCee5NA7EvAqOQjaad5cX/PN fyqKSKLH+rT/AL5oA5CJgfNPrK//AKEacWqvGiHe21eZH7f7Rp5RD/Av5UhiTH9230oLVHMieWfl A+lBjXHf8zQISQ5Gaz7In+3vfyzVx0GOrf8AfRqjYKv9ttk4Hlnkmk9hli4kmF4RtVuRyYwf6Vd1 RZwylAW56eWDj9KoypKbw7LhdmRwJh/jVnVolaUBJFUg85YCosBbRLj+yl4Ib5uAuP0qTTVm2yGQ uvy/TvVYIg0VA0iZ+bDdR19qXSGUJMGljYBf4QfX6UrDNW2GOsjk56lqnuJZVu7dEkKqYyTgDn5q zrS4/ebUeIrux0bP8q0Ln/kIQf8AXE/zrpw0bz1McQ/c0Jw0p/5by/gxo/ef895v+/h/xpKdmvT5 F2PN5pdx2wlSTJIeO7n/ABoWJWxnJ+pNLn5D9KchGBXy+dycZpI+gyyPNTdxPs8R/wCWa/iKz7qG JbgARr93sK1KzLw/6Tj/AGa8OlKTluei6aKxRB/CPyq9piqYpOB9/wDpVFjV7SjmGT/frerfkZPI Xtq46VUnA8w8VczVSY/vDXNTbub0o2YKBsHFLAP3woT7tOi4mWt6crSLmtGMlH71q5a6P+mS/wC+ f511cozIfrXKT83cp/2z/Ovosj1qSZ5OafwomhctnyvYUkR3TrTZ24T2FLbAmVfrX0z+E+bW5p69 /wAg+7/6+Y//AEEViWvFy31ra13mwusd7pP/AEEVkWyn7S3HevPpv3Ge1h1efyOx1b/j10o/9Mav Qf8AIFh/67t/KqeqKTY6acdIv61et1P9iQDHPnN/IVk9jqduUdecaFcH/bT+dc/b/Ndwj/bH866a a2kudImhiALs6YBYDp9aqWnhyZJkkmurZApBxvyamMkhKcUndmD4o58Qy/8AAR+lbGOKuan4atb+ /kun1SOMsQduAen41O+nWyjC6hCfqf8A69b0q0UtWeVj4Orbk6GOw5NT2Nv9ou44z0Y81JNaqnK3 EDj/AGXqKIyQyB45FVh0IYV0urBx0Z5SozjLWJ2aKsaBVGFAwBUc11DbrumlVB7muYN3fSDBuHwf 7v8A9amR6ckrb7ieXJ/uxMxrh9lBaykel7ao1aEC5qHiMFTHZg5/56MP5CsGZ3kIZ2LMRkknrW/F p+lp96K8kPvGRVnytNwANNnb6xn+prWNejTVoowqYatV+NnF3nEy/wC5/Wki6V2Utnp0xy2kzMQM A9P61Wk0e0Yfu9Puoz7SD+prDEVY1VoS8DUVrM5B/vGon6V0U3h24JZkilI7D5c/zrEuo0t5PLmg ukcdmRR/WvElQknct0pxWpJAf9BlH/TSP/0Ks+9/5Dl9/wBdP6VcWQ/YnMMZx5seQ5568dKrTyxf 2rd+ZBI0u/5iJABnHbiuhwvTSNZr9yMXrTLzPlID61ZWaLPFo34zf/Y1FdXEQVd1lkZP/Lf/AOxr SnTtTkaZWrYqL3M/tVWX/WCtH7TB2sU/GUmoHvIQ+BYQfUs/+NcsYrufc1KkrfCyW2H7gVPbr84p YbkmMbbW2X2w5/8AZqninkJ4itx9EP8AU1zVOXXUzcpW+EuRinzg/ZJj/sGmxyTn+KMfSMU+d7gW srCUcL/zzX/CubDxj7eNn1PPxUpezldGBjjpWffKdnTvWqb26x/rVB9ok/wqldajeqPluT17Iv8A hX2sYy7Hx8HHm3MkIdvQ1t6BG/mS/Kfu+nvVI6nqHl5+1yj6HFaOjXV3cNJ5t3cMABj963+NcmYp /V5c2x6WE1qKxrmJyDhG/KmrBKf+WbflSMJCpJmmP/bRv8ajCEg5Zz9WJr5H92luz20pFj7LMf8A lk//AHzUVzZ3DImIX6+lRmFCeRn61BdW8QRD5Y6+leplLj9YXLucmPi1Rdx5sp88pj6kVoaXH5E+ 6R41Hu4rDEMefuL+Va+kQpv+4K+tqc/Kz56HLcuX1xELZwHDZdBleQOe+OlEckSatdO00Y3EfLu5 HHpSXKgWswAA+dOn1pI1A1y8BH93+VcFJP2h0VrezLZubfH+tH4A1h3xgkuC32lF9irf4VvlRjpX O6io+0txXfFSfU4ION9jPmjtC4Jvox7eXJ/8TUWnCFNQuvKmEucZARhjj3FNuMeYv0pukNjU7z6L /IVji4tQ1Z1UWubRF+/w8AB+XkcsDVIBVh2eYmfrV3Uzm1H+8KyGUnJzXmo67kkIVb6NvOhPsHGT +FS3KNJb4GM+a3UgVSgQf2lEcVau/wDj1/7bNSZaKv2aX+6PwYUkltOUOImJ9hUdI3Q4pASi2mAH 7p/++TSGGUdY3/Ko0Y7Bzz9af5rr0c/gaADY4/hb8qawO05p/wBplH/LZ/8Avo0pu5v+e7/99UAQ pnk+tTRZJP0pBdy95c/WnrcyHgOv/fI/woAqxffl/wB80vSTHrzSxXb7pAxiOH/55qP6U97r5l/d xn/gFABmtOw+6KzvPX/njGfwP+NaFlIWX5URfoD/AI0CZtQjipiODVeFZDjDqP8AgP8A9epys237 yn8KCDM1Uf6KOf4hVVFzGenSrWp7hb5cArkfdOP6VU81Vj6Hp60DKMnE0f8AvCrV8cLJ6bx/Kqk0 0IdCVlzuGAAP8auXoVo5d5KjKnIGe1BaM5TkUjdDUirEQMSNj3T/AOvSGNDn98PxU0AZTfeP1ph6 Vaa2j3H/AEuL8Vb/AAphtRjAuoPzP+FICAdBmlNT/ZTjieA/8DoNo/Z4T9JV/wAaYyDvTp/+Wf1/ pUv2SbsEP0kX/GnPayuyfJnB5wRQIremKKvC0kA/1LflUU1vN0EEn/fBpAVD94U6nGGYEfun/FTS FGHVSPwoAr3HQcVVHMgq3OrbeKrKCZhx3oAfLH+7Bx3rY0Qcn/dNUJlxB0/irQ0XO85/umqtYSKO sf8AHxH/ANcxWd2rT1gfvouP+WYrNxUlMKdQFPpQBQISlApcGjHvTJuGKaUAwcc5qTA9aRh8vXuK BihiOhP4U8SOP42/OmAD1pcj1oESieXj96//AH0avaZIXvo1kdipPqazD161d0v/AI/4ue9MTOrM UIUnc4/4GaoXDBPus+f96rxQhD1qq8YJpEpmDNPObnk/iRk0uo+aYIT5mGxnOdtTXyBbxcDtUOqq vkw7nCjHXGaHsax3CdGOmoYpctuG7D+x96dCJF02UmZt+08b81FKIX0wKHAwRyVOKWFYRYyBXDPt PQH/AArJlkuliY7i8hHse9Raclx9qP8ABz1CAf0rFjyL+EcjLCtiyjRbk+ZIuM/36GgZYd5hqTqu Ad3XaKyfEYb7apY5OwZ4rVuFf7e2JQEJGP3mO31rK8QYW6jwQw8sd896EC3MhelLketKJePuL+VL 5rei/wDfNWMQUZz2o81854/75FHnP6j8hQBcsApZw2MY7k8VqS+Qx3CFG256Z5/Gse3kdkkyf4am gM4cBpflb0OQawqxu73KTLAlHGRgnjAqQq2QeVUDnFRsMsCRhemQMZqxDLsXCjJBzySKm6sUS28E ShnmCuCMhc80x5bUkhoCox0UnFI0twHVpEkWNucgU8u+1nYhlboMbifrXFJ63Yyc3BkQpbhmiA5B 5IFQcCTgnJ6dMZqOOeYS7FQRj0wP61KXmc7QCDjgKOv4ClFWYXGSsVGwgHJzTN4CBWOAKawcMRJu BHYCoiq87myO2K3ikBYMqiL5Fww7k9ah8xigBVQue1MRTjsR9an8qLAKsMkdPQ1doxFcgErKCA+B 6ZqXdD61DKCONnHrioML7/lWikhHWaRxpdku1QTCh3Ef7Iq9KTGw3x8dtprN0lAuj28qk/LCnQnj 5RUhvJw58rcynkkNz+vNHM7mqS6l4zxlC2AHxwTnANPhiZNo+XczZJ9fpVT7VhVZ4CVH3uePxFPe 9kCABvlY4UAVD5pFWSNB44SeF6fQD6U7Nuyf6gZ+vSqcaTrbecXZSOhOatR20zQj5xyc4zQozWqJ lKOzZXZVtpA3VM45OfwxTHdVRmCjO7gZ7UtwHWTACqQPugdakttKvbmQM1s6hh8p6Y96E5lWiBmg kZQE4AwwwKnRY3zsDn0Bz0q8fDt1BgP5YDEZfIrQm03TreJA91JJIvLKMLj8ADQ1LoJyiQeH0VdT iBDBsE4JPpXRX5wh+lZGhRxi+ZtkoPO0unb61q3/ANxvpW0G2tTKVr6HIapGXZD6UeYYooh5rJk9 jird2mcZqvcQlrdGVJCy5IIHyj6ntUyvbQqNm9RDPKh2rfvuxn/WHFBnuOv9oyZ7DfVIsskoVoW3 YBz1q79if7NmNVY7gCG+XHtz3rNVpLQt0o7o0dMluJJf3l08qgdGOa11HFYmkQ3Ec7ebEY1A4BBG fzrcHArqpNtXZzzik7IU1HH95/rTzUUfVvrWpBNSGgUYoEGaM8UUlADYT8rf7xqaoIPuH6n+dTCg AozSGigAJqOI/f8A96nmmRDIb/eNIZITxUcn3afiopPummBxNucxE+rMf1NSHNRWp/0dfx/nUhNS BHK3ymgnimzEbfxFBPFADJM7TVHTgDrMhOcCM1dc8GqWmNjV5iBnEfek9hj5BCb4newO4cbat6wY WnG/zFOeyg5/WqbvEb87om3bh0f/AOtVzV5FEw3RBueOansImLRLoygBypB5wM9fTNM0YxKLjZvb K85AHenySEaNGViQptOQc+p96i0iXKTlIETAA4J9fc0DLNi8TXeArg+Z03D1+lbFy0a38ReTB8n7 u0k9fYVh6dKrXnMUYbzOxPr9a2bo/wDEzT/ritdWGTc0Y1vhJ/Oh/vMf+AH/AApfPj9JD/wCmA0u RXpcr7nFp2JfOTYfkl/75H+NOW4TH+qmP4L/AI03/lkaFOK+Wzp2qJNXPosshek2tB/njH+pl/HH +NULmaP7Qd0UmdvqKvdqzLs/6Uf90V5FGS5tkehKn5iNNH/zwkP/AG0H+FXNOl/ct5UHG453Sd/y rMJ5rR0o/wCjN/vmtq0/c2I9n5l4yyf88kH/AAI/4VBJJJvOYo8/U1Pmo3GWNckarT2X3GippMYk kuOEhH4H/GnJLN5gwsIPrtP+NKFwKEHzg1SrNf8ADDlTQx3n3dY/++P/AK9c3Neyi5ceXBwx58oV 07DJrjp2/wBKk543n+dfRZDL2kpXPIzRcsFY0Zb64AHzRj/tin+FT2l1cO65kXr2iQfyFZEsucc1 paf9+P6ivpJxionz/NK6NTWJZIrSZo22sbwDIA6bRVC2urppyPtMmAegbFXdZObOQf8AT7/7KKr6 TaSXd8sMa5d3wK8+FuQ9nDWcnfsdU+lz3SWS27Tbmjy58xsD3PNdBaaDbQQKk2ZpByXYmtC0t1tb aOEHOxQpPrU1c8pXCc76IqDS7P8A594z+FOGn2g6W8f/AHyKs0tQZXKwsbYdIIx/wEU8W0I6RJ+V TUUAR+VGP4APwpfLX+6KdRTATYvpRtHpS0tIY0KPSjA9KWimITHtRilqveXUdnbPPL91R+ftSBtL Vhc3UFpCZZ5FRB3NcbruvRahH5MVspQHiR/vD6elVL++m1CcyzNx/CvZRWdIPmArCcnLRHBVxDei LEH/AB5N/wBdY/51Qucf2ze/9dP6VfiGLM/9do/51Qm51a9P/TT+lVCN4oVXSgh6jniq170X6mrS VUveQv1NdEoWoyNslf8AtkSnVdz+9qc81CQTL0ryUfoU7WNG3/1Qq3AOaq26nYODV6BG/umuGtfU xm1YuRU+5H+gzn/YpIkbjg1NcxsbCcAEnb0/GssHF/WYep5WNkvZSscyRxWfdjp9a1jazkf6l8/7 tVZtPunIxbSn/gJr9CXKup8TGMubYzXTEPStXQB80uf7oqKTTLvycCB856Yq7o1nNbmTzk2ZAxki vOzSzw8ktz1sv/ips0iP3bGo1HFWCFETAyRg5/viogIx1mhH/bQf418a6U7bH0SlHuMxzUN2P3af WrGYs/6+H/v4KhujCyL/AKRCMH++K9PKIOGITaOTMWnQaRUAzWrpYwazcwj/AJeI/wACTWhYzwRr /rN3+6pP9K+uqTjynzMItMs3PNrP/vp/6FQp/wCJ7d/8B/lUcsqPZ3BQk/MmcgjHze9PZ4E1q6Jk YvhcoqHjj16VxU2lVOiqm6Rodq53Uh/pLVvfaI8cRyn/AIDWLfSWzTsX89T6CMH+tdsZo4I03cw7 n/WL9Kj0pc6peH2X+VXJzYllJa6zjoIl/wDiqg08wf2ndfZxKSQuRIoHb2JrHFzTgdNGLUi1qSg2 3OfvDvWf5Y2NyfzrSvyTB+8UqNw5GD/Ws/dEEPznn/ZrzDssVrcY1GPFTXuDbc/89m6VHE1uL+M+ dljwF2Hmp7lA0By4X963JzQyomZtHv8AnTSo9Ks+Sp6Tx/r/AIUhg9JYv++qQyuirtHFLsX0FSpb sBjzIz9HFO+zv2KH/gY/xoAh2r6ChlHHAqb7PL6D8GFDWs5HEZP0oAhQDB471LEBuPHahbWcdYX/ AO+akjhlVsmJxx/doApxjEkv+/8A0FKwG/8ACnJDKssuY35bjj2odWGDtP5UCHDpWnp54rMAPoa0 tPPH40AbkLcAVMzHFQQipmHy0EGZqhzaH6is8JlOfStLVRi1P1FUkH7v8KB9DNmUb04/iFXbwZjl Huv8qqTj5k/3hVu8+7L/AMB/lQWjNT7oFOpqjkrUoiYikBlTfLK31qI1euIFExzmo/JT0oArL0oq wIUPb9aQ247GgBYlG3PeoXCpPG2OM9al8g4+/TJQDLEp6ZpgPebjCj8aj3t2J/OrQjTsopdo9B+V AFTzpQwxI/5mn/aJwP8AXSf99Gp2RSRlRSNbofb6UCuVJby4HSeQfiarjULkSDMxI9wKfdx+XxnN UwP3gpDLc2o3Oz5SuM90B/pWjpE08sy73XHcBFGfyFZskf7jPuK0tFH70cdqoSItTnMckYCRtlf4 lB71Q+1etvD/AN8n/GresACWI/7J/nWZSGWftCd7aH/x7/Gjz4T1tk/Bm/xqvR3oAsebAetv+Tml Elt/zxk/7+D/AAqvx6UtAifdbEf6uQf8DH+FML2xBXbMOfamDpSMMKTQBOBb4+9L/wB8j/GjbCek j/ig/wAaizSg4oAlCRf89D+K1c08It7EyvuIYcAHms/NWbJyLyIj++P50xPY6/zTtP7mT8qrSSgc lGH1FWPNOw1RuCz5GaCEZl/LE90rB1AA5BOKh1J4XtYmOXUDHynFJdwCO6XPen3iL9liGF5Pek9j WO5BK0Z0kgxuqjBBDc/ypbR0NhIFR/unkmp7i2nt9OkWVI22joM461DYtJJbyKsSAYPAB/xrMsxj n7bC5XA3D+da1q0KXh++3PZf/r1DbaW8twokieMjkA5H86sRI0GoMnkMrbjjceo9elFwY+58r7cz MTjIyMe1ZviDb5sTKCAU6Ee9ad2MX5PkuTx346fSs/xDkmBmXadp4zmkhrcw1p3SmA4FOzVgLmgC kzzVm0gWeTbk7+wxwaUmkrsZe0iAFpHeIMqrkhuBj+tWpWhmAEapEo6YGP5CiNXdSmwIo6le1I6C EfLIHrglPmnctIhFwrIIyeR0OaVSyOMfdHPHSmbAzHe+1T1O3NLIrI3zfNx1q7pAWZZXILKVEYHT mq0YVyS5bj+7T4pgFAWI5H8WaleKJ7dgTGGJzlidw/pWDsmBCzkDDFlLdM1NLdec6hsbVGME1HFa SXBRV+YHoRkD+VTPYW0aPmRy/YdMH60m4LcepWe6wpBkP0A7fWkbY0asBvGO55FRtb7e39afJbMq r91t3oRWtkthakYnCHG08dBxTmky24jrTpIo0KjYVyOQeaaYEIGHHvzV3iwHm5jC7Np/E5qLzY/+ ea/maGK4IYd+SBUOR7/lVKK6iOg02/j/ALKt4JIGCeSgYxhfm4HXI5qeMRB826ysT2dgv9MV23hX TvCq+H9MlnaFrlrWJpPNfADFBnv6+1dZDceH7dNsNxp8a46Iy5/TA/SujlIcrHl9lo+rXg3wWNwV J4LMoU/mBV86f5SGC8UxXETcqQCfw7V1F1c2ej3QvNJvI5InP762V+DnuAP5VnadHaarrV1fahK1 vblspESRu/KjlXQfM7CW2lwSLFBc3bvIf9XbW6FnHf5un8+K1Lbw1dNdGVbWOCDGNk0pJb3O08fT NbVveaBbSB4fJRgOGWI5/PFJN4s06IkRrNIfURk/4D9aqyIbk9kVn8JfaQBJKgQYOEjPGP8AgWP0 pDoscLBDfG429I8k5/I/ypt14pt3iOJURuwl3ZH0VVIqjb+KrdZDGI5MHkyNKQCf++c0WQXma0Wh qyqWt7aM5zjBb8/Wkk0WD7UspmBkUYCJEv8ALms+41yKZQI72zj553iWT+aYog1oI206vAqescDf 1Wk1EPfNpNKmjR72RcchSzHlvTgcVnahxG3HarMOqNft5f8AaPnxxj5Ywm3HuflFVNSOImx6UrIt GFcDJFX7CxuJbeOSFV3I2eQTn2PtVWZelbWj3unwWQW6ljV88BvSlFJsJtpaE95pM14schu7eGSM 5KhcH+fIrH1LR5J2kldCZBgLJFGxDfrxXSJq+lRsGiuoY2ByCgxipH17SpFy11EsnfHRvf2qnCLI U5LY5GztJrV1aRZ+U43rgE+1X/Mb/nm35j/GtDUL21ukQW8ySEHJ2npVEVcY8qsPmctWN3v/AM82 /Mf40yJnIJ2H7x6kVKeKZD90/wC8aYh37zso/FqUeb/dT/vr/wCtTqWgNBn73+6n/fR/wpGEmOi/ nT6GpiIYRJsPzL1Pan7ZP76/98n/ABpsH+rH41MaAI9sn99f++f/AK9G1/74/wC+f/r0+l7UARlW /wCen6U2JDhv3rdT6f4VITxTYvu/iaQB5Z/56P8Ap/hUMyfIf3j/AKf4VYzUFw2IXPoDQBw9qhNr Gd7DIqQo3/PRv0/wpLQYsof9wVKRSGVZUOP9Y3Uen+FKVb++fyFOlB4+ooagZXlDgff/AEqppkbS ancYcqQnUVcmztNVNIGdRusttGzrnFJ7AAWU6iEJz84BO3mrWqxyx3ACszAk9ecUyP7R/aCgTEpv GMyjpn61Y1RZTcDyp1Azz+9A/rU9gHSwTDS4mUybymSoJ55PanaVbTSQTmQSKeMdRTrmMnS4g0qe Zt6mQevrSaXFttZ/MkRs45DbvWgCWxtpftKho5fv8kg+tal2f+Jpj0hSsjS4yt2v7xCu/s1ad7cy Lq7xqIwBGnJXJ6V14X49DGtblLG6gMag+0TcfOv/AH7X/ClE8+f9aMf9c1/wr025djj93uXT/qjS Lmo/Mm8onzj/AN8r/hSLJN/z2b8AP8K+VzhJ1VzOx9LliapaFjmsu5ybtuvQVd3y4/18n/fVZ811 crcsouZgAB/y0NeXRhDm0Z3vn7DCG7Ka0tLR/sh+U/fPUVlNd3Wf+Pu4/wC/rf41f055JbXdJNK7 bjyZCa1rqHJuK0+xqbHP8J/Kn+S5P3D+VU/LBPVj9WNTCBCOV/OuB+zXcmUpIm+zyf3D+VIsDg5K kVCbaI/wL+VIttFn/Vr+VLmpeZnzyZMY8d1H1NchLp1yZnO1ACxPMijv9a6owRgfcX8q4GUjzn4/ iP8AOvo8gkm5ch5uYXlFXNI2E2Rl4B9Z0/xrVsLcrJFma3JyOBMp/ka5YEbhXSaWo3wcc5Fe9XqS Ss2eO4RutDS1RBJasDJGn+mE5dgo6D1rX8HpBbXctxI3mbVwvlAtgn6Vh6yM2i573jH9K6rwIV8i 8XHOVP8AOuJP3WehBWTaOk/tSDtFcH/tkaX+04+1vdH/ALZVawPSlwPSsyCp/aIPS0uT/wAAH+NH 9oOellcH64/xq3ijFAyp9vm7WE34sv8AjR9tuT0sH/GQVbxRgUAU/td2elj+co/wo+0XxP8Ax6Rj 6y//AFquYo70gKfn6h2toB9ZD/hSebqR/wCWNsP+BNV2igClv1M/w2o/76NGdSP8VuP+AH/GrtGK YFHGpH/lvAPpEf8AGsLxHJfxwQpLJDIjPnBjI5A9jXVmszW7A31iQgzIh3qPX2pGdVNwdjhvMnI+ 5B/3wf8AGq7zTeYBthz/ALh/xrQ2YyCOnaqLD/SVFDieW5snUsbQb9ufPj+6uO9Z80sv9qXir5aq JDg7Bk/WtMri2Qes6fzrNkH/ABMr0/8ATU1VGN3Y6K0mqCYLLcHP7wD6Rr/hVS5ublW/1w6nrGn+ FW4+hqhdnLfia6a9PloyZrk0nLFRUtiL7Xc/89vyRR/SmfbLvd/x8P8AhimmmjrXg87P0B0KfY0Y Z7hlBNzN+DmrUZlb71xOf+2rf41Sg+4KvxdBXDWqS7mFSlBdCzFGW6ySH6uakubdBp87c5C9cn1p Ie1T3Y/4lVx/uf1FZ4OpJ4mCb6nl42KVKVjmCileefxqnKilulXT92qrcvX6Mox7HxSk77kdxCn2 XcFGc1b0OJC0mVHQdqiuR/oGfcVY0L70n0ry81SWGlY9bLHesrm2IU+zOdo/Ko0jXH3RVhf+PV6i j6V8ZJuyPpUldjCoz0qK6UeUnHepj96o7n/Ur9TXoZM/9pRz5mv9mZUCg1q2CgJWaBxWpY/6uvsq i90+Sg9QkH+iz+m5f50oA/t28+i/ypjn/RLj/eX+dP8A+Y5de4X+VcUP4x0VX+6NRR8orn9SA+0t XRL9z8K57UR/pLV2Q3OBbmLdjDr9Kh0tgNWu/wDdX+VWLsfOvFVtM/5C93/ur/Ks8Z/DOmh8Zo6m 2bMj3H86yUjPkeuK2byIS2zLnGOazEH7g15R3IqwqP7QhzVq94tz/wBdjUEIP9oxVoixN7G6Bwm2 UnJGaTKTMTqKQnAzW0fD8nadfxWmN4en2nE0efxpBdGLGcpn1qTNaa+HrkKAJYyfqf8AClOgXQ/j i/M/4UBdGXn3oJwDWl/YV2O8f/fVNbQ70A/Kh/4FQFzNjJyfrU8RLHqasLol8Mny1x/vCnDTrm3+ eWPavruFAXM+KWRZJV3vw/Hzewp7TzCRcSuPX5qfb2FxPJO8URZQ+Mj6CpH0u8GD9nfrQO4wXEuf 9a//AH0a0LFmk+8xP41T/s+7HWCT/vmtCwtpowd8bL9RQJs1IYlxzn8zUxhQA4Lf99UyMECnMeKC bmfqS7LUsCSeOG5rP84iPoOnpV/UQTasOvSqKJ8nTtQFyhPM4AISMnPcVdn4V8qGOF4OfSqk64Vf rVyfrJ/ur/WgtMrRlMbvJQE9cE/40/ev/PMfgTUaDj/61O5pAV7h4hJ80RP/AAP/AOtUO6D/AJ5P /wB/P/rUXX+s/CoaAJQYD/BIP+Bj/Cl/cekn5ioh6UtMCTEJHWT/AL5H+NV3NsZE+eYEN/zzH+NS 1WmGHj/3xQBeCw/89G/75/8Ar0m2PtJ+a1GKXFIVx5RM581fxB/wqGTa3C3EYH0b/ChxwcZ6VSNM dwmtwx4uIfxJ/wAKgFofNB8+D/vsUT4wMmq3SQUgNSWDMBXzYs57yCrWkr5MoDPHz0w4P8jWPMjM mTWjo8S+ehxVEoXVLeSVojGoOAc8j1rP+w3P/PIn6Vd1nrF/wL+dZVSWyx9juR1gk/KkNrOOsEn/ AHyahyR3oDsP4j+dMRKYJR1if/vk0nlyD+BvypolkHR2/A04XE3aWQf8CNAhMEfwmhgQh4p4uZ/+ e0n/AH0aRri4AJ8+T/vqgBoJxS4qQXE2P9YTTxcS46j8VFAEIGas2I/0yH/fH86QTvjon/fA/wAK mtpCbiMHaPmHIUUyWdZsGw1XdBmphENp/fyfmP8ACqkx2ZIlc/lSJSM3VVxPER6VW1IObOLaGJ/2 aW9uJWmUFQ2OhP8A9aoL8PJp6+YyqM8HsKOhpFDUhlaxZmMxOPu5OfyqWzttyMyvOuPXK1XhjiOm yhZE3bTzS6VGgLbpE3dsNWZoLYS3s8u2SecAf7RqVpbpr4x/aHOGIBPJFVNOjxc4llXb/wBdAf61 OyuNUkBmxHv4/edvzpASXN5fRXIhW5fBx1A/wqjrwnxC00pdsEcgD+VX71X+0J5ch24HIeqWvJiC D593XnOaEMwVzS7qQA4pdpPb9K0ABV3T3IuAA6oD1JHP0qntb0P5VdsXeKUD7Mj7uMuP8eKyq/Cx o3DNBHEFXcvGC3c1AxjZ/l5XGCcdaVmZnyYwMdBuGaikjUANH3PID815kVZmlwYxoTuUKMYwo6/n TYnBJZMgDu3WkVZWYhVZvTFTrbSY3eUMYycN1rRpJXbAsQk20ZdJFOepjBz+NVJ5EP3MZNK8jSD7 pX/ZFQeVI75VN2OoohFXuwJBfGOLytufdTUTyyzADAPp60oi3t864welKzbVKxhlGeeeDV8sL6LU RGDtB3AkegpFlURlBuyTnmmSEM3QAnpjikEQIz5oz7VVr7iHHfPyCeB/EaiZWXAD7j6HtSsr7c+b kjpg4rQiYiFT5yh36jbilKXJsBSERK7hznqBR5Y/uipmVMABCsgPJ9aTaPQf5/GrVS4WOl0y6C6T ZAKOLZB94ddo561Kb4kDER6Y59fWsvT4Jv7NtD5b4MKEHaf7oq/HE46g8e1dNn3EDzvMVDxED6Y/ GpHuHj+RImKgYyI8Yp8iMIlYrgFxg1adGxJx1Ix70WAzY53jcuEfP+0ORSm8dmBIkB+nA/Srcas7 zkAn5qssjnzOvJA6UWYFBNQcMDuk5HHNWI9SeRSVMmAM5GePrUzI2H44LAdKqzKWvlyuBnp2pWYh 39sqOBNNkj5cOabHqj+fuM8jIRwCT1/OrEkalX/dpneADioFhRnnPlrhenHSizBM3tH1LKTy5YiO LccMVyfSrWpX7rbzhCysiK2S5bk9sGs21iSKC7VVC5VFwB6mnau+I74j/noiD8hTGPgu5JVTzN7v s3EjAHX04qtf6gYlCqDHJ5YKhlU55981TZmF/bIrEARrkA9al1eNGnaU/fjjUL+JpIZEupXIdS8k ezbkgxL+X3aa2pyGfIddnoqr1/75rOG6aRQ7McAgZPSnLCAWHOFqkI6/QpWlEhZt3A/hA/pW2K5z w0wWGUnJ5HQZroBKB2b/AL5NaIze489KZD9wfU/zoMgx0b/vk02GQeWPlf8A75NMCxmjNR+Z/sP+ VG8/882oESGmk8Um9sf6tv0/xppZ8f6tvzH+NACwf6lfpUnNQwu3lLiN+nqP8afvf/nk35j/ABoA fS1Huk/55/rRulP8C/8AfX/1qAHGmRfc/E0Ey4+6v/fR/wAKbF5nljhf++v/AK1ICXFVr3i1lPT5 D/Kp/wB7jon5/wD1qp6h5gsZySo/dt/KgDmLWPFnCP8AYX+VSGOnWyMttEPl4QfyqTD+i/nSGVJI jx9aRoSe1WZA+VG1Tz60/D/3V/P/AOtQMy5baQggKfwqLTNLvo7qaVrKdkkX5SqZzWzhx/Cv5/8A 1q6qxGLSAY/5Zj+VJgjhIvD+pfbRN9im2Bw2MAHGfrVq98OaneTB0spVA9Sv/wAVXoKdKnWpsM8/ l8O6pNYR262MgZQBuLp6/wC9Umn+F9UtYZY2tGbfjnegx/49XoAqQU7Aee2vhXU7Ofz3h+RSWOXX j9arX7f8Tyf2VR+lei3rbbKY9hGf5VwE9i0+pz3Afar4wCjZ4H0rqwklGfvGNZNx0Id1KG5qf7Dz zMv4g0os0B5nT8x/jXpOtT7nEqU+xJn9yfwoU08RxBNpnT/vpf8A4qlCQAf69f8AvtP/AIqvmM1p yq1bwPpcuqxp0bS3GZ4rLnP+mSfQVrn7MM/vx/30n/xVVGgsDO7m75PbK8f+PV59LDVE9TveJpmc fpWnpn/HkP8AeP8AOo/I07qbz9RVy0+xRQKkcxdcnnPX9Kuth5OFiHiIf0iYHmraDKj6VW821/vZ /Fv/AImrAuEAGI8j6t/8TXBPCT7r7zmxFdaWHEcUgFIblf8Anl/6F/8AE0ouB2iP5H/CoWEl1kvv Ob24MPkrzWXPmt9TXpL3GEJMXGP7p/xrlGm8OgnMUrH/AHW/+Kr28nXsHLVP0M6j9otjAU/PXWaU o32/1FURdeHAeLSYn/dP/wAXW5aTWpaMQW7JkgKSnT/x+vSxNbmtrY5/Y+RBqxzaR/8AX29bXg68 FvqSxscLMCn49qyrmeG3gjNxF54Nw4AC/wAXr1FLb6nCrgxWpVgcg4HB/Oqpu7aNaa0aseq0tc3Z trV9bJMl2FDc4JGR/wCO1Y+xa4et9j6MP/iaWxg1Y3aKw/7P1k9dRcfRh/8AE0f2Zqx66lJ/31/9 akFjcwaMVh/2RqR66lL/AN9Gj+xL09dRl/76b/Gi4WNzBpO9Yn9g3J638h/4E3/xVH/CPSHreyn/ AIE3/wAVRcLG5SceorF/4RzPW6kP/Am/xoHhqPvPJ+Z/xouFjZ3KP4l/Ok8xP76/99Csj/hGYO80 n6UDwxa95H/If4UXCxrmWIdZE/76FNM8HeaP/vsVmf8ACM2fct/3yv8AhSjw1Zeh/Jf8KLhYi1Gx sLktIlzDHKep3jB+tclcWUkN8MmNlH8SuCK7QeHLEfwn8h/hTZdC06GNpJFIVRknNPm6GE8NCTuz j5mRIYgXTJnTjI9ap/ZXku7qQNFteQlSZF5H51oX4iYholKxmdNoJzgZrJkeb7VcgTSqokOAHIAr ehGTn7plWjBUrPYnSycA5lgH/bZf8aqS6XNI3EkGOf8Alqv+NKsk2Dm5n/7+H/GqMtxchzi6uOp/ 5at/jW+KVRUnzWsaZXGCrx9nv5k50W4/56Q/990o0O4znzIj+J/wrP8AtFx3uZz9ZG/xpBLMTzNK f+Bmvn70+x9vy4r+ZfcbcOkyovLr+Ct/hVuOwKjl/wAo3/wrEhDMPmZj9SauRwo3Vc/WuOrOhfVM 56kMR1kvuNeOAIcF2/79N/hUsyRyWcsG5wzjGfLPFZ8VtEeqL+VWbi2hGlXB8tchPSows6Ht4qMd b9zzcXGoqb5nczjo6gc3P/jn/wBeof7HhBJN2PyH/wAVWZ5aAfdX8qYkakt8o/KvulCr/N+B8vzU r/Ca0ul2j2vlNehec7vk/wDiqk0+wsrRnxeiTcOzRjH/AI/WNKg/sljgfeFP0RR5kmR/D/WuDHxl GhJzd0ehgWnVSirM6gPZiJkM2Qe/mJ/8VTFaxX/ltn/tqn+NQxqv2eTgdPSoYwM9BXzDq07J8h7v s53fvFtmsc5L/wDkUf4UyWTTyihicA9fN/8AsahkUbulMmUfZxx/FXXl1SM66jGNmY46nKNByk7o lEumAdz/ANtG/wDiKsw3dqi4jjyPcv8A/EVlKorTtlAj6dq+mnSlb4mfORqR/lIp51e3l8lQEyu4 /Nkc+4FTm4hj1KcFVafjdhWPbj2qu/8Ax53H1X+Yp7Y/ty5/4D/KuaMH7W1zWc0qV7GiLyUL8sS4 /wCuZ/xrMuL23MpMsQ3d/wB03/xVbgH7sfSubvv+Ph/rXRGjd/Ezk9sv5URz3unBgHt8nHH7o/8A xdZDXdu+pTm0QRuAN2Yz6f79TXYAlX6VlxA/2rd49F/lUYmjywvdm1GtzStY0jdyMjZ2kDr8h/xq t9piC4+THptb/GmSuyoRj2pnlfISa8867ki3Fv8AaYwu3zSflHzf4VoWk9zG022ONhvP8R/oKxoE H9pQ+taE1y9tFIyYyZiOaWxXQ1PttyP+Xdfzb/4mg3txj/j3H5n/AArDGsXHotL/AG3PjlFoJ+Rt /b5R/wAu/wCtH9oyY5t2/wC+h/jWGmtzlQTGv508a3L3j/WgfyNn+0jnmF/++l/xpTqYxzC4/wCB L/jWMNccf8sv/HqH1zchVocg9s0C+RsDU4+mx/wI/wAaiubyOeLYBIOf7uf5VgwXyxTyMsf3ug9K kV4/LYFMse/pQOyNXTZks0lVhI299w2xtxwB6VdOpQsPuzf9+m/wrnLC/htGuEaLdlweg9KtvrFr gZg6n+4KAsjYGow8Z8wf8AP+FB1C2/vn8VNZI1a0/wCeI/74FH9qWh/5Z4/4DQKyNX7fa/8APdR9 eKQ31pj/AI+E/wC+hWX/AGnaf3SPzqN9TtwpwW/M0BZGo13bN0nQ/RhVRniJYiRef9sVntexupKz SD05NQi5kZgBKx+tAJItyx5QbcMc9jV+2dGvWyVwUH9awp5ptgxJg/Qf4VpRpAjbpVTAjXJ2j3oK sjaVYDnKp+QpTDbnqkf5CsYzaeCBujGT6L/hTt+n9nT/AMd/woIL01rbM3+pjP8AwEVF9itiOYE/ KqM01jGBiZQf94VF9ptT0uB/33/9egLI0RYWhH+pWmnT7Tn90Pzqis0TDi5P/fxv/iqrXd49uoeO TzB0/wBY+f8A0Kga9TVOm2n/ADz/APHjWLLbR/b44znZ5wGM9s0smozL5QQli4ycu3H60z+0JRcr GygHeFLBie/XmgdvM2v7LtT2b/vqkOlW57v+dQ75f+flvzH+FBaX/n5b8x/8TQTbzHtpNv8A3n/O q0miQE5Ejj8qlMs4/wCXj9R/8TTTNP3lX8x/hQO3mUptEiI/1r/pVOTRkQ7hK3HtWjPfSRDLEN9B VCXV41XLxOR3wn/2VAWfcryxgW7Vd0tMSrVFtXsHUq0T4/3P/s6t2V9BJIogQhicDKf/AGVO4KLR Ndacb5VIkClSeo96q/8ACPy9pk/I1pJLJGD90/Meg9/rTvtUg6IKQ3cym8Pz/wDPWP8AX/CmHQbk D78Z/E/4Vsm6k/uL+Z/wpv2qT+4v5n/CiwtTH/sO6Az+7P8AwKmnRrocbU/76ra+1t/cH6/4VHLq CRAGTC/Un/CgNTI/si8H/LMf99CoJ7aSIFHTD46ZraOqwhQSy7SeDuFVLmWC4k3+cqk/7S/40BZl ddMvP+eH6injT7rHMB/Otdb5Qo+U/wDfQ/xpft6/3D+Y/wAaA1Mc2NyP+WLflTI0dLhQy4IYZBra +3p/db9KoTMslwZB0z0INAWZ0IB2dO1V3jJ61CmrR7cPG/TsCf6U3+0Yck4f/vg0E8rKmoxbXjwK iuLKW7tEgiALMeMmpry5inKbc8eqmrGnzxtc26KcsCcig0iiimi36WbwfZclhjIdf8aSy0i+tN26 zds+jL/jXYClrOxpY4e00i9tZy72cpHtt/xofTrxr5pvsc2wnOMDP867cjNLjFFgOIvLO6lmRks5 woXBBQ/0qvqtpcTQxLDaXGVznMRFd/8AhUUgyKLBY8kzICQSwNOTzHYDeRnuTUsy4uJB/tH+dW7e xdwjxON5bgEY/U0pTUVdlWG2tjK8v7wnYuCxVuasvGIZD8zeuDkVemaTylV5ArqORncPzFVXcHnc GB6+1cLrSk9SuUbComkYswAxnuc0hWRfmAAPbHapVQeYdr5XHIU05JFiBYKFYH5WJyaht30AFtJV VZDKuSM9808TfZ0wH3Z6gcVXW4NxId7AgcgGm/PI2I0zgEmhRbfvDJ/tAClgcZ6qe9ItyS3Em1u+ B0qmwKMd6tk9ApqF3VnPH51fs0xF24fzGwGXcO/rVViwUBnGPrULyYBA6UKqsOW+bsMVpGCiguSs IgFYZPr2oMqlCqrjPc81WJwcfyo3enArTluK5NHuX5goP1FSojOd5MY+pqCN9pJ+Yn8qcxLduPUc 1MlqBPJKm/Pmbvb0qPcnt+dNUxhtsjNs+mDRm2/vN+QqOVID0rRIj/wj+mkFubWLv/sitCJG3MNz 1zulkN4d09vlB8qNeB/sir9o+PLXg7upIzXaSa5iJH3jSeV6t+eKz/tMYklViPkxjAJ7e1MF9H5a H+IkZGDx+tFgNFYQG4KDPX5RSuoXr5Z/4CKoi6iMxX58AZz82f50xr6NYWkw+QePmb1+tAGjGiyb siLj2oaygeQOyxZXpms+2vYZ5gsbOwOcncwx+tSTSHypCrOpWQKMSNz096AJpowrbVEVUfLaAkxo nzdc85oaZkgVy7sx7lz61Krl0BJzj1pDCO4ukBKpCd3XK5qC6a4ukKSJGATkleMmraD5KYQM0gIF tLiTF15a/u8L8vU0t5aPdgtHFcB2AHKnHFb2lACHp3rbjxtpgcJbaSqR4lguml9UT/EVKmmz/anc 2915bLgfu/m6fSu3jUGQ1MyYFK4HNaVai1idBHKmT/y0XBNaQ6VLdcSAe1QitVsZsU9KIc+WKRj8 ppIj+7X6UwuTUUmaM0CF+lNc/KaM02QkIfpQAQnESfQVJk1FFny1+lSZoAUk9aM0nNGaAA9DTYx8 goPQ0ifcH0pAPzxVHVm26XdH/pk38quZ4rM1xtuj3Z/6ZN/KgaMqHAhQf7Ip2RUSvhAM9qDIKQxZ D8yf71SZqq8g3p9aUzgUAWc11NmMW0Q/2F/lXESX0candnHtWpZ+KtOaIKkd45jADbQcA/nSYHYq amU1yieKbEsAtteknoBjn/x6pV8T2pbC2N8x9Mr/APF1PMh2Z1a08GuUbxRbIcNpl5n/AGin/wAX SjxTbldw0mcr6kx//FU7oLM6HUv+Qdc/9c2/lXmF8qnW7vKjOR29hXVyeIIruFol0t03jbvJTj34 NclfNjWbv/fruwSTmc2J0gKETso/Knqoz0FRgjFOQ/MK9VpHArl/A8ocDrUihdvSoif3Q+tPU8V8 dm9/b6H2WVx/2dEmBjpWWebmbj+KtItxWaDm4mP+3XnUb6noWVxpxk1q6d/x4x8dj/OspjjNaunn /QovpRiL8pEkrlwVoqw2L9KzR1q7ngCvPmmzysxdkibINKpFRA05TWTgzzFMLg4gf/dP8q82aPJr 0a5P+jSf7h/lXBtGeeK9TLE43PVwMVNO5URcPXb6emHg/CuRSEls4712tomJYvqK7cRNucUa1KSS ZR1LDQ23vcyVBBw/HrVi8BeO0wM5mkNQwowc/Keterhn+8Zy0laB29hfPZWttIvK7cMPUV1VvPHc QrLGcqw4rjFGdMgH+zW1ps5gs4SGHQ5BPvW1SN9TnqRT1N6ioIruGUcSKD3Ban+fCP8AltH/AN9i stTnJOKKi+02463EP/fYpDd2ve5h/wC/gpWETUVAb20H/L1B/wB/BTTf2Q63cH/fwUDLNFVf7RsR /wAvkH/fwUn9p2H/AD+Q/wDfYoAt0VT/ALV0/wD5+4v++qT+1tP/AOfuP9aALuaKpf2tp/8Az9p+ R/wqGfxBpUC5e8jB7AgjP500m9hN23NB5FjQu7AKBkknpXEa3rzX94ttAStsp5P98/4VLqGvR324 faI0iwcKG/nXNh4RdhvtMJHs1bqny2bMudybS2L8/MEX/XdP51lyn/SLn/roa0ZpEe3i2MGHnpyP rWdIYftNwDOgPmHIwTj9K2oNKoZVYN07EKHg1Uflz+NXUMAB/wBJT/vlv8KrFbZmb/S4+/8AA/8A 8TW2MknRkkaZZFwxEWyj3p6rk1L5drn/AI/o/wDv2/8A8TUira/8/in6RP8A4V8s4ux977aFv+AS QDir8QqpE1sOk5P0jb/CrkUkA6O5/wC2Zrgq05NnJUqxLcQq1c/8ge6P+x/UVVjniHQSn/gFT3Nw h0m5UxTBCvL7RxyO2anBUpLEwfn3PLxs06bRyZPGKIlyrHFSbrL/AJ6T/wDfof8AxVSQmz8tsG5I /wCua/8AxVfovtFY+Q9m7lecf8SVj/til0T/AFkn+7/WpZns/wCxyG+1CPePnEa5/LdSaVLZq7+S Llzt53Io/wDZq83Mpc2Hkkepl65a0Wbkf/HvL9KgTrUsc6fZ5QIJiMc8iohPHu/1Euf94V8m6b5U fQc/vPQdJ94U2UZtx/vUrzpkZt3/AO+x/hTZJx5I/wBGbGf+ev8A9auzK48uJTMcfK+GasRKOlaM HER+lUFnXjFqf+/v/wBjV2Od/KOLZQMd5f8A61fWznpsfKxhruRn/jzuf+A/zpzn/ie3X0X+VM83 fZXP7oJgD+Ldnn6USzFdauFWAFvlyzSdePTFcsX++vY3mv3O5vD/AFWfaubvP9c/1rcEl15eQsWM e9YVzO4lbMEROfU11Qk77HHyeZl3Y/er9KoWabtYu/8AdX+VadzdYkXNpATj1b/GqdjIsur3IEMc bBFJKFuePc1ni5N09jWgkp7jrmLapNRY/ck1evcRxbmUMM4qibiPyz+7z/wKvLO4rwc6jFx61cng 8+KVc4xMTnHtVJbhBfRbbc7ieG8zp+GKvvMsKSswJHm4wD7UmWil/Z3/AE0/SmtpzY4kH5VY+3w/ 883/AO+h/hSNfw7T8j/99CkBWXTnCAb1pf7Pk/vrVkX8BA+V/wA6X7db+j0agVf7Pk/vLTTYS+q1 c+22/wDt/lSNe2wGSz/98/8A16NQKP2KRCzErjPrUoxjHep2uLeRMb35/wBn/wCvUY8gH/WSf98f /XpgZ6xlribHqP5USRNx9asxLbmWUiZs5GQU6cfWnyJCxC+dyeR8hoAreU/pSiFyeB+tWtkf/PYf 98mnxohPEqn8D/hSAp/ZpT0T9aa9tNj7hrZjhBxhgfwNTfZcr/8AWoA58QShMlDUlvE3mjKmtaaD bEeccdSKjiRUGdy0xGbdLwPrV+7BMLgf881/nVW6VSM+bEOe7gVclxIpKleY1wc8daBoxCrGUcHg UpU+h/KrghYyE7o8Yxw4p5hb1T/vsf40AYV8G3Lwfyqlg+hroLiKfeNoUjHTeP8AGovJuP8AniP+ +hSAw+aOa2vJue0H9aYba6J/1LfgtAGdACSafOWEbc+lXPst0D/qZf8Avk02WzudufIkzkfwmgDO 82QdHYfjR58w6Sv/AN9GtMQSgc2h/GOkMTf8+n/jhoAzDcz5/wBc/wD30aX7VP8A89pP++jV14Gb /lhj/gNM+zjvF+lAzOnup+P37fnVN7mckgyMR9a1p7dOMx/pVVrZC33KAuirblnY7jmt7R2Iuowf WqkNokcbNjnFXdKXF2h/2qYr3H6/dTW0cRhcrl2B4rDGsXo/5bZ/AVv67EskS7hwJD/KsA20X939 aRWg7+2r7/nqPyo/ty9/vL+VM+zR+h/Ok+zx+h/OgLImGuXn95T+FNk1m5lQo4Qg8HioTbx+/wCd N8hPegLIel27hYyq7QcirTztJlmAyB2qmsaocjNTqNyHjtQJkw1+5Qbdi8e9OHiKfH+rH51mmFSe 9J5A9TQPlRqf8JDN/wA8x/31VabVHmcsUx9DVTyPenCDPGf0oCyJPtxPG39aaLjLZ2kfjVtdGdgC JOv+zSpospOA/wClArolVT5UcuThveuh0dVSSJh1L/0rNuLM22nwKTlgeat2twLS2WdkLhGyV9aY k7nXg0uRXMp4ngcHGnTcDJxt/wAaVfFNo5wtjcZ9tv8AjUGh0pPvRmub/wCEpss4NtdA+gx/8VSn xRYKcPDdqfQj/wCyoA6PNMc96wf+En04AZW6H1U/401/E+mhck3AHqVNAzjbsbbyZfRz/OpLK5SG XMkYYHjJ6j3qvdTxy3csiE7WckZHvUQcUnFSVmO5tTMszBuAvZttRnYQFUbT/eNV7MPIMKwC9CSe BUrRtyCRge9cUoKL5R3Ii3lMcu2fanKVmc4JYn1NQSAZ75+tOhz5ox29ScVfLdXC5KLcHcS5X0oi tQZB85Yc5C5zSO5kk+bC/wC4KTzChBDYx3pWlYCYu6qfLgLJ6kVC2CcFdrfoaWS4eVQolb6E1GcK flbPqTRGLQD0iO4hlyPaldEGUBdcc8rUKs2eOfwqXAJO58Dvk1TTuBFIm5Qqtge561A1tLHkiMkY 6gcU9lHJXPHehp3YehAwMCqSYhIY5GwSuQOuamk24BVQufQ1Bucr98/nS7mIAb5gKOXW4C5JOMHj 1o5/urUsLKFPyDPrk1Jvi/uik5tOwHU2FwV0KxRQeIkPJ/2RViyc3UoQsxwOmah02J20exxGceQh 4I/uircKmA5SBg3qCK6RFuKBFSbOeDxz7USyRwxW+UJyQePpUAnkAYeTJhuvzClN2yhS0MmE6fMP 8KANCEI87sBgFAcVE0atYA45Lf1qst8yszeTLluvI/wpGvv3QTyJcD/aH+FAFuztUgvpCpzuUnB7 USkCBiB1mNUl1Da5cxTZPGcj/CmSXgdAqxygbtxz/wDqoAsSgfZo/fFTRyKsYAz9AKofakKqGSXj 2/8ArVpWRjliB8rA96TGL521R8p/Komuh6H6Yq1PEnTAxiqnlrk8UtQJrXxALb921tIQD94VcXxl aJgNG6n3B/wrIkjXPSq7xgv0o1A6AeOrCJyT3/3v8Kf/AMLA09uNw/8AHv8A4muWe1Rv4agNovYU 7Ad/a6vDqkXnxkbQdvU/1Aqx5sf99fzrH8PRiPTAMDJcmtjj0rRbGbGtPFtP7xPzpY5o/LX516et EhPlt9Kcn3F+lMQvnR/30/Ojz4x/Gv507k0dKAG+dH/fFRyzp5bYPb0qXNRzH9030pAOSVQq8np6 Gneav+1/3yaAeKXNMBPNHYN/3yaDKPR/++DS0ZpAMaYBTw3/AHyaRZRtHyt/3yadIfkJ9qE+6PpQ A0y+iOfwrL1+QnR7obHGUxnFaxrI8QnGj3HqQB+ooGjE804xsammb/Zb8qQsfWmE96kYkk3zrw35 U1ph6N/3yaa5zIvpQTQMrXMo2Hhv++TS+HJEVLwvnBYdB9abcn5DTfD77YLo+Xv+Yd8etRPYaNC2 mhF/GfMzhs4C1dOpWUMvzsyse22sq0eF75QI3DZP8Y/wqK8aFbrbJFISB2kH+FZqKKudBc3trHtk lZvLYDBC+31qaC8s5bMtHvKBuTtH+NY+oyx/Y4g0LFMLjD89PpUtjMg0l/LhIXccgvnsPajSxJqW 2oWMziOFmLnplcVj3d1CNVu1NojMJCCxc803R5Ldr5NkLBz335qpdNnVrz/rqa9PAxXMc+Ib5S8L pMf8ekP4s3+NOW6BYYtYPzb/AOKqmucCpF4YfWvTcYrqckVJ9DU+0uEH7i369MN/8VTluXx/qYB/ wFv/AIqqTzxqg3SKPqab/aFog+a5iH/AhXymZOTrNRR9dl9OPsFzGgbmTH3IP++D/jVJLty8mIrc YY8+X1/WoH1mwX/l4U/Tms9dYs0aQmQncxIwprjpqpbY6+WnfVms13IAfkg/79itCznma2jbKLkd BGuP5Vyr63ajOBIfoKmi8VQwQpGts7bRjJOKdSFaUdEZyVO51glnyP3o/wC/a/4VY3z5/wBef++F /wAK4pvGL/wWi/i//wBao38Z3pyVhhX8Cf61gsPiDzsZRdS3szu90/8Az3b/AL5X/ClHmkczP+Q/ wrz1/F+qN914l+if41XfxPqzj/j7K/7qgf0qlhK76nEsFU6s9Hm8xYHYTPwpNcy17djpO34AVy8m ualKMNezEf71VmvLhus8h+rGuqhQqQveR6OEhGimpq52cN5eMMm5kx9a3YL+CGWMy3wABGd03H86 8qaZ2PzMT9TSbua0lRcpJ82xtNwktFY9Eu9WtVjtVjv1Ta8hcJLjqeM4qoNetUb59RlI9pGNcKWo DV1wm4u6MI0oqNj0t/F2hLbou+4eQDkgHn8zQPHeiRwqq2NzIwHJOBn9a80zzRk1TrSJ9lDsd5c+ O7SQgwaayY7mT/61PX4kyJHtGj2bn+8+c/piuAzS5qXUbB0oPodtL8SNRb/V6fp0f0hJ/maqS+Pt bk+69tH/ALlsn9RXKZozS5mNUoLob0vi/W5fvXzL/uKq/wAhVKXXdTlzvv7hv+2hrMLUmaLsLRWy L0er38Z3JeTqfUSGrsPi7XoMbNTuP+BNu/nWJmii7JcU90dXD8RfEkP/AC+K4/24UP8AStCH4ra5 H9+Gzk+sRH8jXCZpCRT5mT7OD6HocvxZ1OVNv2O3j/2o85/XNUh43SV99xbyyOTyxfNcRmjcfpWk K04bGc8NSnuj0SPxtphQhoJ0zx90H+tRR+I9La4VzMUX/aQ1wG80m+qeIm3dkRwdOOx6r/wkOkyw RKt7HuEqMd2V4B96rC9tJbi4ZLmFg0hIw45FeZbqN5HeqhiXGXNYieDjKPLc9PQqynBB+lQADdJ9 DXnAkZTlSR9KmW/u0+7cygezmtK2L9pBwtuGGwao1VUvex2+Pm96sIOK4ZNXvV/5eXP15/nVuLxB er1lU/VRXiyw0nsz6P8AtCHVHcwAY6VciHSuFj8T3iDG2E/VT/jVqLxhcp96CFvpkVx1cDWexnLF 05HexirN2P8AiQXh9FH8xXCx+OduN9ln6Sf/AFquv4/sZdLuLVrWdXlUAEEEDmlgsHWp4mM5rRHn 4uSnTaiQE5q3armCT6GsEa5ZE8uw+q1p2et6aIHVrpVJBxlT/hX3nt6bWjPlvq1ZPWJNdDHhzPrL TdE++/8Au1FdahZyaCsUdzE0nmZ2hhnFLok0YdxvXlfX3rzsxknhZ2Z6WApyjXi2jpof+PWf6VAe GH0qe3wbG5II+6P51C4yR/u18o4vkR71/fYkh5Whx/o+feiTotKw/wBG/wCBV05V/vaMsw/3VkaD irycQt9KpIOlXhxAa+zkfIRKx/48rk+w/nRKf+J3P9F5/CkbAsbrP90fzpJv+Q3N/ur/ACrkj/HZ vL+AdAv+pH0rnbsfvn+prol/49wfaueuv9c/1rqp7s4zJvRiRPpVPTyf7busf881q7f/AOsj+lUd P/5Dtz/1yWs8X/CNcN/EL+oj/Rj9RWcqDym4rR1If6KeT94fzqiq/un5NeSj0SooH2+H61bu/wDU Tf8AXb+lVVGL6EZ/iqze8wT4OD5w/lQyomceajk+7il2nP3v0pJFOM571Ix4xiik28daXaf7xpgK FoYZxRt/2jSMMY5NADk+6KkTnFQog2Dk/nUiKN3f86AIozieb6j+VP6yE+lQqo+0zcccU9VXeQR3 oAn4xU9vy2KrbV/ujP0qxaou7hR+VAGxbgVb4C1Wt0HHA/KrewY6CkQUb0j7M/0rJU7gBuGPrW1e qBbPx/Cay4QMD6Ux30My4C7CMgmtGTCwj/rkKp3n3DVx+Yl/65CgpMz0kUA8jr60pdcfepqdD9ad 2pXAz7pwZeD2qDcPWprv/XH6VXoAUN15o3Y7031pcigB273psuQm4MevrRxRLjyTQBIJXwPnb86P PkHSRv8Avo1FxjpRxQBL9om7Syf99Gl+0zD/AJbyf99GoDS/hQBJJd3AXImk/wC+jVdr+6B/18n/ AH0aJPu1XYmgC219dFDtkbgetS2FxcyzKHmbBYdqjRMxH/dqTTuLhf8AeFOwrl7V5niiyhAPmdwD 296xvts/dkP1Rf8ACtbXP9Qef+Wn9K58saRZZ+3Td/L/AO/S/wCFIb2T+5Cf+2S/4VV3Gk3H1oCx aN45PMcP/fpf8Kb9rb/njD/37FV8k96Mk96AJ/tWf+WEP/fFPW6J6QQgY/un/GquCe9Sx/WgBfPU 9baL/wAe/wAacJY/+fWP82/xqJenWng5oFckDRn/AJdkH4n/ABqVPKLD9wP++jUIzUik5piOqt7U NAhDAZXpimPF5XO5f++ans8m1i/3RTJoyxOaDMyb66YqEKFlB6jioWkZ9PlVl2oPQ5q3qMAW2Dd8 1Bgf2bKcZoLiVbJozayqN/3T8232+tM0wxCU4Lv/AMB/+vUmnMGikCxfLg559qh0yQCbEcR6c5b/ AOtWZoNt/LXUGO5m+Y8baffhDqWd2MhflIPpTI3VNUcLEd289W4/lUmovGuoIxjYttU8Nx/KgY3U FQNCd20EHgg0X/ltpyBOzDtipNVZCluzxsDzjDUy+O7S1ITaMgdaQGH5bf5NL5b4/wDr0zuaXIqx lmCWaA5jIB9a0FkSaNdz5kPUBRiscHNats9pD5RiO+Xq24ED6YrnrRVr21BEcimNmyMgfpUDZwDz +VW3khkkYyA47BeKqSFVJ2ocdjms4XGRs7dyQaaWYjGeKCR361LGIyMljn0rbRIRGJGBHOPwpwIY jNKwTOeaYxXqMAChWYyaNgW25CZ705twOMhvp3qsJUU9z9KcJ13AgEfjUuL6CuSNuBPyjH1pyMMg Fck8YxSlgRkPyO4pBMyqyljzipuxjHYBiBTN5ycipgqs3C59OakkJw3HJ6kUcwFYOy9MgH1o59RQ cnhsc989KTy1/vU9wPQdJP8AxJbH/r3j/wDQRVknmsXTdYtItKtI2Ztywop+U/3RVg63Z/32/wC+ TXSQaNRy/cxVL+2rLp5h/wC+DUcusWZGBISc/wB0/wCFFwNIHigkHNZ/9s2P/PU/98mk/teyH/Lb j/dNAy/jikxVH+17I/8ALb/x0/4U4arZ/wDPX9DQBcIAFaFm6qgywH41irqNoxAEuT9DWzaMrwgr yPpSYyeaVcE7hiqnmpn7wqzJ901XwPSpAjeRM/eH51CWUv1GancDNREAt0oGISp7/rTTj1FS4owK YjoNGGLBcepPFaQNUNLAWyT8avZrRbEPcSQ/uz9KeDwBUUxHlmpARgUxD85opuRRkUDFzUc3+rNP yKjmI2H60hEwPFGabkYpeKAFzRn86TIpMj1FACSn92fpSr90fSmSkeWcntTgy4HI/OgB9Y3iI/8A EplHqVH/AI8K1jIg/iX86xPEcqHTCAwyZE7/AO0KBoxjTCaUuv8AeH50xnHZh+dQMYT+8H0oNIXH mdR0pCw9f1oGVblu3Y1HZ3DWMbpFghzk7hmn3JBGc8gU3ToFvbR5pH2FWwACKympHo0KmHUPfWo+ O+eKXzEjj3eu2h7x5H3ukZb1KiltbJpptj8LySQRSS2brMUQqy+pcD+tTZmvtsJ2JJdTmmUI6xbR 0HlihNVuI4jEnlhTzgRr/hUl9pi2+0RyKzdwzgYqSLSkax895VD5IAEi4pWYe2wv8pnNfXqHdBJF Gw6FYlB/MCs6a7v97O8jbmOSwA5/Kt+y0v7ROiSsoVjjKyKT/OqLwr580fO1HKj3rpoUqs3aBnUx OFXQx2vbo9biX/vs1G00jfekY/U1ttpsEnJH5ULo9uSPvY+tbPDVupksXR6GCWPrSZ9a6U6DagA5 bn3pRoFoe7Z+tefVqKnLlkejSpSqQUo7HM5pM1050C1A6t+dQRaLbyKSSwwcVmq8GafVpnP5JNGS K3zo1soJ+bj3rQg8NWckSO27LDPWpnioRV2Q6Ekcfk0Zrth4Xsc/xfmalXwnp5JyG/76P+NZ/X6R y16io25zhKK77/hEdO9G/wC+j/jXKeIbOPSbvyVgIUjKvk8irpYuFR8qMY4unLYzKK1dL0+C+UMX bG0k/gM1c/sm1A+6T+JrVVot2O2lTlVV4nPUZrtNO8PWFzHueAnnH3zV5/CGmmRVWMrkf3m/xoda Cko31ZE4uG6PPKWuym8N2cfkbV/1qF8ZPH602Pw5aMwyn6n/ABrphBzbS6GammrnH0V6fD4F014V dkB3DP3m/wAalfwFpgH3B0/vN/jV+xkR7aJ5XzRmvTG8E6crAeUD/wACb/GmXfgjT4rZpVQAj/ab /Gj2Mg9qjzXOKN1dXJ4dtx0AH4ms3U9NttPi3tyTwACetTOnKCuynJWMTNGcVb062N9cCIQ59SD0 rpx4Qh2jLDOPU1mnd2sTGSkcbSZrtR4QhPO5f++jS/8ACHwY6j/vo1S1LcbHE0ma7b/hEIOPm/8A HjSt4NgCsd3T/aNVysyc0upw+cGkzXVN4ahWUp7/AN6pR4VhZQcn8WroWEqNXOWWNpRdmzkM0ma6 e78KmGCSVZkwilsbuTiuWZsfwkVjOm4OzNI4iEldCk0mTTC/+yaTf/smp5WV7aJJk0uai3n+6aN5 /umlZh7aJLmlDVDvP900u8/3TTsHtokwcjvTvMNV95/u0B2/umiwe1iWd5NJuqvvb+6aN7f3TTsx e1iWA1KHqvvb+6fyo3P/AHTRqHtYljfx1pRIR3qtvfH3f0pd0n9w0w9rEupdzx/cmdfoxFTprOoJ 928nH/AzWZmT+4acElI/1bUnBPdB7ZLqbK+JNVTH+ls2P7wBq0njHVETYWicZ/ij/wAK5srN/wA8 2pMTf882/KiFOMJc0VZilXUo8rd0danji9X71rbH8D/jVmHx1eyMI/scLA9lBz/OuIzL/wA82/Kr unM3nnKlTjvXTCc5SSbOWoqSi2kj0OHWvO0+bz0SN3XhV7c1bk1AyalK0SxbSFwxUknj61xIlbAG TWzaynOc9hXTGK9qcNST9lc7hZrloARcLjHQJWPcXU4kbJiPPXy//r1ZhnP2Yc9qyZpMyt9a6YQT ZwOckR3t9MjoCsDZHeOq9hObjWJ1ZY1IjX5kQAmodQbMkf0qPSj/AMTif/rmtTi4JUro1w1STqWZ sX42W5PDYI4asw3PyHEaflWhqB/0R+O4/nWYi/I/FeSj0r6ELXLi6iAhi5brg5H61euCAtwSgYeY OD9Pas4j/TIf96r902I7j/roP5UMuHmU96/8+8X5t/jTXkjCnNtGfbc3+NM8wH1psjjj60tTS0e5 N5iY5t0H0Y/40eZF/wA+6/8AfRqMsCOKb2oIla+hP5kX/PAf99GmPJDj/U/+Pmo80jdKZJMHhx/q T/33/wDWp6yRdRE2f9//AOtVZSdoqROtIBEeBriT9y4PH/LT/wCtTma3VgfKkyeOHH+FQLxcy/Qf 1pW5Ye1AFnMP9yT/AL7H+FWLby9/yqwPu3/1qpA1atDh6BXNuANgbQPxNW8S7eifnVW3YACrRfjF MkqXgYwNuC4xzg1lI8aKOW6d61bts275/umsSNdwUUkNEF1LBtbJlx7KP8atbleGMjcFMXcc1QuV GxhV0f8AHtF/1yP9KCkVlWAMQJH6/wBwf40pWL/no3/fH/16gHDmnZ5oArXUVuZMtMwOP+ef/wBe oPKtv+fk/wDfv/69F5xIPpVWgCyIbb/n6/8AIZo8qDPFyP8Avg1VFLQBZ8mAD/j7T/vlv8KJEt/L K/ak/wC+W/wqtQ4HlE98UAWPIi7XUePo3+FHkR/8/UX5N/hVUHigmkBYMCf8/MX6/wCFHkL/AM/E P5n/AAqsTxQTx7Uxk0luCp/fw/8AfX/1qrtaj/n4g/77psh+XiqzZoA2I4gsZBli6f3xSWiLHMrG eHqOkgqgqF0/DtUllGBJz61VxGxrEZmgYKyD5wcswHb3rBNlIf44f+/q/wCNbetD/RHHoy1zdSyi x9il/vQ/9/V/xoNlN6x/hIv+NQClwaAuTfYpvRP++1/xoFlN/dH/AH0P8ah5pcUCuTfY58/c/UU9 LWYHlDUGKPLz1FAEwtJuP3ZpwtZh/wAsm/KoEHy1IBQIlFtKP+WT/lT1t5QRmNvyqEZxT1Y560xH X2LxiziBZQQoyCaWV0ycMv51Fp0imyiyg+7S3LDkBF/KgzKeobXtCFOTkcCqQz9gmHfHANNv43ZC 2cAelRwxYtZWBOcetBpEi0wykOeAPQIOag05pXuCAFU47KKl05W3nfLznj5xUVmspuiJZTt95P8A 69ZmgM8n9rMoVQd/XbTtTZlvYwUUnYOSPekmSX+02BkOzI539sU/URN9oiEbtt2dm96Qx2qO6wW+ 9VY5PUHimXZkbRwWCgZGMCn6gkotIDG7E7vmIbPam3Ct/ZBLOxbjILUCOf8A4jRRkbqUd6sYUoO3 BBptLQBMJGYqGZiB05p8hw5HaoAfmFSTE+aaLIBXIYDAwRQoZiNoy3tUW45qWOUq3JGPcVLjpoAj DsV5phT2/WrI/efdYBqFgIG93H0rNytuMrceg/OjahHBJqV4VByBx9agClpOPw7UKVwDZg5BOfSr H2fKAl8nuAc4qJkx7mguFXGBk9hQ9dgJVcxcB/1pHlySQRmqxPvSEDGc0cgE/mnacMefeo9y/wB6 oyQOhzScev6VXKgNm2H+iQ/7i/yqTFPtYiLOAkqMxrjP0qx9nbHQflVXQFPFIRVrycnAIo+znHUf rRdCuUmU0Y+X8atNAcZJGKQW5CE5XFLmj3C5XRCTVuG23GkjTB7VOs+zGE/Ok6kV1C5pWdmi8kVu 2x2oAK5+LUURfnGPeta0uhLGGTaQfehTjLVAaLH5eaiFNMh2fdOfameaR/A1UMc3U1H/ABUhkyfu mm7+ehpAS4oxmmeZ/smlD5P3TTA6OxiX7ImQenrVoRJ6frVexP8Aokf0q0K0RDIpIk2/dGalEaYH yimydAPepAaBCeXH/cX8qXy4z/Av5UuaXNADfLT/AJ5r+VRTRx7B+7XqP4amzUMx4X/eFAEgSP8A 55r+VL5af881/KjNLn1oATy4/wC4v5UeWn9xfypc0ZoAikjTYcIv5U/ao/hX8qbL93r3p2aADav9 0flWL4jAGnrwOZUHT3razWJ4jP8AocI9Z1/kaGNGGQPQU0hf7o/KnH6008VIyLavm/dHT0oKr/dF H/LU/SkY0AVLtFEbYUdPSpNHCf2TIXOAWPb2qK7P7pvpU+ksBojZTILHvUz2GSaVFEt0T5qNhDwA fT6UyeKF70nzkHPQqf8ACpNJMIncokmQh6sP8KjeS3e/O6OQEsP4xj+VR1Av6ukMsoUuFwe6nmp4 oIV0tY94IJPIBqrq9xDHcjfG/U4w/wD9arS3MSaXHL5T7MEnLc/yqXewyawsoIbmJ42+bIrnutxc H1lP866PSLqC6m/dq4KjPzHj+VY8baY3mHF3kuc8L1/OvQwEuW9zHEK9khgztqWMcipgbDHCXX/j tSK1nkfu7j81rolX3NFSEk4C0oPAqSSW0BXMU/8A30tKJbX/AJ5T/wDfQr53Fx5qjdz6jBz5aKVm Rk8VVtv9Wx/2jV5pbXHMM3/fY/wqGCWzEWVhuMZPWQf4Vgqem5u6uuzK0h+RvpWxbcQR5/uis55b PYwME+P+ug/wrThmjEa4t3xgYzIP8Kxrw03MJVNdmSg81ZTqarCZM8Wzf9/R/wDE1Ok/Jxb/APkX /wCtXJ7LzR4mZy5nEnA+asjxBpSapp7R4/erzGff0rWExz/x7j/v5/8AWpjzHH/HsP8Av7/9aqpx cJKSkjy1danklrd3OlXm3LLgkMh79iK6yKZJ4VkQ5VhmoPGGkFz/AGhFAIxwJAGzz69BWToGpRWz tb3MTSI33cSbcH8jXtJRqx5o7nuZfjFD3Xsz0LQYi1pnH8Vasy7Z0/3W/lVXQWaSxDQWyqhbo8mT /IVbu2kWcCSNAfLbBVqxlS9+LKr1uaUjEuetlx0g/rRCCWFE8oR7VTDvP2cHO/GOfpSxzZYYtlz/ ANdP/rV62G0cjnjL3Eddbc2sX+7Usx4H0qjbPdm3j2rEBjgHJqSZ7zPIh/I1tfUxvqDDLiotSOLB 8d6aGuy3SH8jVfUpbpLX5xCyk9ACKaY76nNXTiNGYnAHWuF1a/a+uyQTsXhRWx4k1nfm0iVVwfnK k8+1Z+g2Xm3AuZolkjU8K2cE1nVld2Kd6j5Yo6Dw3p5s7QTSj945yB6Ct8y4FVRdnH/HvDj6t/jQ 14f+feH82/xrCVktDtpUmuhbSXNSB/lqit63a3g/8e/xqX7XIR/qYPyb/GsoPU1qQdvhJ9/Ip7v+ 5c1TN3ID/qYPyb/GnPdTfZ3PlwYx02t/jXRc4pwfYp53TE+9WgfkFU4rt2ORBbj8G/8AiqsG6mCj 91b/APfLf4168JPkWh89XivaPU42/gMN1LGf4WOPpVFkGelb2uxlrkSlVUsv8AIHH1NclLczLIy7 +hI6V5lVWkztp6xRa2ClNuwPT9aoG5l/v/pSfaJT/HWLv0NVYvGFh2z3zSeS2AQMg+lUDcS/3qPP l4+alaQ9C95Ten60eWckdxzUcG6QNljwpNNXzCTgmizHoTeWw64H40nlt14x9ah3N60bm9aNQ0J9 hxkY6UgQnPI44qLc3rVizQTXccb8qzYIo1FoM2HjpzTvLOcZFac+nwLayMCVdWwOTiq9lZRymTzJ MgLkYz1/KlcLoplCp5pQKntbdZLlUkb5SecZpJ7dVumRH+QHAxmmpIkYKsw4KVXdAlzIiFiitgbq swdCKuLuxSTSHlaYVqWmsK0MiArg061XN2f900rUWoZroqDgbc8Cqp35kKfwsv4wa1Lc9KzNrKDl s/WrsSSE5EhXgcACumLftTnnZ0tzqoWP2YfSs2QnzW+tOjt5TAD9pmHHrVNkmDn/AEhzz6D/AAre End6HG4x7kWoE+bH9DTdJ/5DMue8Qpl288boPOzkd1U/0p+lSTT6pJE0gwIwQQi5/lU4qUnT1Rph 4x59Ga+of8ejfUfzrPThH+laxtWYYaQkehUVlXkr28zRrggD+4P8K8tHoLUpsP8ATIf96rl3/q7n /fX+VUGu7gzxhSgyw/5Zr/hWjMTm4IAPzLwRntQy0ZWaZJ2PvVzc4/5Zx/8AfApHdtv+ri/74FAX RXHSlqwHb/nnH/3yKXe3/POL/vikK6KwpGNWt7f884v++aQu2OY4v++aYXRXX7op6/eFSK7HP7qL /vml8xh0ij/KgLlTP+lv/uj+tOYgPTo5ma4cNBDkL1xUwycEwxe3BoC5FVm1yXpAM/8ALKP8j/jU se4HISMH6H/GgLmvbjgVb/hrKjmmHQqPwqcTz7fvD8qCSa6H7h/XaaxoOVFaUjyupDMMH2qky+WM KicfX/GgLmddjAarQ/49of8Arkf6VXupWVCfIjP1J/xqeJy9vAzIo+RuBnHagpFDP7w/T1p2acXG 8/6Ov5n/ABpd3/TBf++jRYLmbe/fH0qpWndMmRutlP8AwM1W3Q/8+q/99mlYLlTuaXtVndD/AM+o /wC/ho3Q/wDPt/4+aLMd0Vqc3MLfQ1PmH/n2/wDIlLuiKlVtwf8Atr/9aga12KYPAozVzZFgf6Of oJv/AK1M/cZP+jv/AN/P/rUA9NyoelGaskQY/wBRJ/38/wDrUuLf/nhJ/wB/R/hQK5Tf7tVm9602 FuQf3Ev/AH8H+FQMtr3hm/7+D/CgLktsuUH0ptqP32KkjmgQYEMmMd3H+FEMsCSfLDJn3cf4VQi/ rAJtJPbbXOYrp7/bJauZFbBVSQDzWJ5dt/cm/wC+x/hUlaFTFFW9lt/cm/76H+FLst/7sv8A30P8 KBXRUxQKteXb5+7L+Yo2Qekv6UBdFcU4VPsg/wCmv6Un7he0p/KmBCn3aeDT0WAjjzRz6CniOH+9 J+Q/xoAhGacoyal8qP1k/wC+f/r05Yo/7z/l/wDXoEdLpkebCL6VLNHljVCxvvJgWJYy20dSasve M2SIwPxoZnYrX0X+hyGqMAzaTDPYdatXV1uhZGUjPoapwSjypUCMQV6ntQXEpaakQlYbwxJ7A1Fa pEl6cygjJ4AP+FT6e6LM4VGPPOWqG3Ma352oxbcepFQajrkRf2oW8wYyOMHPT6U7U44jLA3mKoK9 CD6/Sm3pjXUt2xt3BxkVJqpjItiysp2ngGkAuoLC1jDtcLhupB54+lNkEQ0hwnzMByQKluU+0adE PLbhgRj6UkkbR6W8bQyKCMB2UgfypDSbOcP36WpXt2DZ3L+dNEeD95asbG44o6Cn7M9WWm+Xn+Na YgHWpJuH9OKZt/2lp8y5YfMBx3oAj70oo29t60uz/bFAEkDKrcqD6cZq4zuxyy5PoRis8LjneKf5 jkf64VjUp8wySSVW3blKn09aqsVVwalwhAy65phRSf8AWD8aIwsArSwhcKCffFQmQMemPpUnkjPL rR5aA4Dr+tUo2AZjK5A/OmdDzVhUTkb1JpVjTBO9c07AVt3bApMmrPlR9S6/rRsj/wCei/kaLMRo 29xttYs5OEUcduKmF2D2aqMLBYI9xP3B/KpVZsb0Q49a5JR1JLm92Ibb1HrTDcFGwWIPtVNppWHJ 2kUzDP1ck0uR9WFi8J3PTJFItySrZxis4gBsFiPxqSKItu+bgjrVKkh2LH2pVP8ADx3NAuIyckg+ hA6U1bFiC8e2RQM9etRLE8km1Y23+gp+zQWJTduDkYwe9WLW6k8xRnoexqkUGcDrU6brcqWXGenF UoxQHaWVz5sGW61Y81eef0rO0eUva7mXAzwa0hgitrlEZkGf/rU0yrk5OKewFVmyX68U1YCbzk/v cUCZCRhqiwMcipBHsKkYKnuKqwrnWWWPskX+6Ks1Xs4t1vEN7D5R6VaEMBlMX2mbeOoEYNO5JE/O PrTxipWsFIB824xn/njQtrGRnzrjH/XGncLDM0ZFOW2Rn2LJck9/3NPNiAP9Zcf9+qLhYhzUMx+Z f94VNcW3kxtIJXIUZ5AFUWkDMvzPgHOeKBF0GlyKgBBAxI36UEqCB5jZNAE+aUEVBwP+WjUKQygh 2INADpSNo+oqSq7gHA3t19akCf7bUAPJrD8Qn9zbj1mH/oJrZMY/vt+dYPiJcLaje2TIe/8AsmkN bmU30phpuM/xNVa5uY7cfO7ZPQUr3GNub2K0JaQ9cACm2199rchYmUepB/wrD1C+juH+7nH940ke syRqqgfIOynFTK/Q0io/aNm9b9yxHp2q1pzMmh5AUj5iQR1rFbUY7qBlG5Wx0JzVyDVLeDS0h85l k54U0NOxL8jV0iQM0+2JFITgjPr7moIpA+pqhgjLFwCcH1+tVdP1yCAS+fcvyMLjJ5qKLxDHFqCu 1xN5QfJxnpS5XcRrazNtuFDQxvnONwP+NWp3K6LCwij2lPu4OOv1rCvddjmkEkF3IE7gkirMviS2 ksoo1u5RKqgHOcVNnYZuaC4PmFY0XAH3c1hWwzEx9ZCf1qzpvimyhWVbi4ckjC/KT2NQWKmWzVkB YEk5A7Zrvw0lGMmzOUbyRYHapkPIqMRPxhT7CpcMpxg8VzOsjv5ULMfmGKAeOabMCXGBxijBx0ry a7vK59HhrKkhWOFP0qK2/wBQKe+dp4PSmWwP2cfSsraGjtcbJ/q2rZi+4v0rGcEoeO9bUYIUcdqw rrRHPNq5IOo+tWo+pqqqnIz61aiU5PBrkaZ4GaP3ok61E/Sp8HHSoHU4HBqYp3PLZT1NA+mzqwyC mD+deaXtoba4OB0OR9K9VuNPu7y0ljtraWZiBwiFu/tXJ614Y1yLY8mk3WGOFKxlv5ZxXsZepJPT Q9CgofV/O51vgC+hvtG8ncPPib519uxrS1fC3hA7QtXlmharceHNZjuArBVbbLG3GR3Br028nXU5 fPsw0qS25ZNoyTXoVYK6aCEm27mJc/6+3HpbD+dOh+8KmuLC7N5Aotpc+QFA2Hr6VLBpeoMx22U7 beuIycV04aSTlc3WkEdBauq2sZYgDHUmo7jUbMPtNxHn61yPiDxZaadG2mS2kzzoBuydgB+vOa4e XXS5LB2XJ6DFVKb5tNjHmitz2pR37VzPjXWo9O09YVYfaJc7R6D1rlNP+IOoQosTqkyKOrjBx9RX P399da7qjSuS0krYUdh6AU3O+xPN2Iba3kv7rqSucu3pXV24WFEjQAKvAFCacum6YsYGZGILtjqa iUtngGsqvuux7OAox5OZ7mlv4FI0nSq24gdDSlj6Vy1JHoRpospJVlXyvWs5WPoashiFBxUUnqTW ikiVnAFVNU1NrGwG2EyGTjOcAcVlaxrElmwhiX5yMlm7Vz0+s30vDzll/ukDH5V1q7PHxFeEfdW5 s22v3QdQbVSM9ic10lxewWsKyTyLGD61w1lrCQyh5rdZSOhBxj+lOu9Qa+vDcOuBt2qhOQK7oYhw hq7s8KrSVSd7HQ3uoWd2qn944HQrxmqD6FbX9nPPamUXKciMkEN9OM1jNMT1Jx6ZqzaavNZMGjIJ HTdziuOpKUnc6IKMdBD4X1sQmY6bOIwMklcVlSwyQuUkRkYdQRiuytfGku0JLBkgYDq5zUuq6Lfa 7Zw3kEMa5ySxfqPrWKnJO0kauEbXTOFoHUVLcW8trO8MylZEOGB7VGASRWyMmdZ4YFh5E/m488ja pYZwD3HvUl+Jbc4imjZfRnXP5VzSMYkxnBPWmG4YdGNRKF3c0VRKNrHTzWdimmNLcrF5pQlSjDGe 3SuYzR5rMME5owe1OKsS3fZCqjucKrMfYVZsTsvYi3ygOM57VNp2rNp+9REG34y3QjFMvb86hP5h hjVh3UcmlzO9raD5NPM2LlgNPmLDcu44IPvWXZ6lBbGRWRzuXHXNVjd3SW5hST5D2NURndlj81Ll Jt3NiwdDfR4HOe5pt0V+3vhf4vWnWOnWsw8y6mIJ7A4/WqqnZeyRRSb41bhiaE03ZDcGlctyqTdS kgZ3dqWI4f68U5wPPlwcjdUMjiJs55pU5Wk0XOP7tMt00mqEs5l25baoPODzVhodPAJXU5jxwPs5 5/8AHq6Oa5zcjHscDPanWJBuyQf4ajMenjIXVLjGOnkdf/HqpTmOOXFvO8if3iu0/lk1UJ8srilT 5lY6J8AVoQcj8K5jTrmKKR2utzJt+taGlagn2iVDIVhJym9uR7ZranWUqtzCrRcaOmp2kf8Ax6j6 VQcZkP1rb0SyGpyQW4kCiTjd1xXcQeG9A01N0lubuUc75ScfkOK6faKJyQoSnseP6lFNsWSOGSTa Dwqk1jGTWLOQ3cdtJFuAH3c8fSvoFbyyELW0MFvCh6xqgwa5HWPDj3d0skMvkoxwyquV+vJ4rmxF SpPSOx34fD04fFueeWeta/5yo1ss2f4WAU/pV+6eWSRnmi8uQqMpnOPxrsbjwxHplqJ4HMpxhyw5 H/1q52W0a61ExgHBUZI7CuZJp2ZU+W/uowlhmluYxDC8rg52ouScVHcSau0kpMKQBjyjn5uK6vXf KsdBe30+SO3fgu+4B5B6Z615o93M0hwzZ9zRUVtEaUkvtHQwC8KKZniTHGAM5+vNWG7ZpNAsJ2jT UpYWljgbL7trJ06FTnNT61rUOtoIbeBLfy24aGMJkd+nWsk2nZmkqcZK8dCLPSl5qKJ7GGIQsssj EcluufYjpUU13BZqFklJx0z1NVGd+hlOk4rc1LSylvCwjAwv3iTgCpTpT4b9/DuHYtjNYA8T/ZY5 FtlyXXBJrGfVruSXcZT19Kl819AjCNtTqSjRMyuMHNFY6eIFZFE0bEqMZ3Zq9bXsV3GWjPQ8g9RV mbVmauj/AGFLiZ7mATuAMRl9oPWrt9dafMNiWMVsQPvJLn8+a4G8v3eRjG5TBwCD1GarNPJcMWub p8enX9Khwbd7nTGUVGzR2YIPIOR7VIprik1J7ZdsMjYrRtPEbKcXK5XHBXrWhzuPY6yM1PuwuTVC 0uY7mMSROGU1c4ZSDgigzM278QW1s/loGlcddvQfjVRPEEUj4lt5Ige55FaMml2b/N5SKeuVAFZG pXcmmlFilicnsUHAqG5LZG0I05LV6ly5IaIkcgjgip4v+Pa3x/cNctPrV1NgSTDaP4VUL/Sr1vr2 RGjxLtQEAqeT+Bqk9NQ5LbGmPvn1pc1DBPFP8yN17d6lqjJop3f3hVerF2PnH0qsQaAE70maZLKs Iyx57Cs+e/cjAO36UXGotm5Y3Ntb3Ie4RHTurDOaoaq1uJA9pLkE5KgfdrFa4JPcn603zmPes2ru 5vBuKsWTPIGydxrQW5UIokPzEZ4IP8qyY5C27/dNTRw2rRqzah5bkcr5bHB+oppA7Pc2BFM9u00S bo1HJzVJ7xoceZCQvriqyrCEwNUKgjldj1VnYh9q3BlTHXkfzo1EoxsasN5HcEqvBxTiM1mWk6wk kjk1oxyrKPlNUZyjYeq5qSNcSCmJUqA+YKZBqXozbuP9gVh45rcvObdveMViYpFMQilHWjmloJNm z0+wntyXuFWQr0DE7T+VZ76fdLGZfs8rQg48wIdv51AjMjBlJBHeuk0rxvq2mKIxIJY+6v8A4/40 RjruaOSatY5ooaayHHSvQY/G2iXX/IS8O20hP3mWNdx/4EMGrUWv+Ai4P9gKn+/vI/8AQjVcpKSP NbdCQcjvXSQ2tl9gUr80h6sOD+VeqeHb3wnqc5i07T9NLgFiptQCP++hXVrpemyIA1tbEDgARrx+ XSlOndbmtOSi7tXPnC4s7l5cW29vRWFQy2d1asouoJI2YZG9CuR6jNfSUOk6Vpx8yCCNCB1HFYni TXNEjtyNUtbWeMDC+YgZvwPXP0pQptdR1ZKeyseHQcGpbmWSK3LxqGOfWrWr6no0l2X02xe2j/um UsD+fT86wbm8jnbC5jPsxqrGKhZ6naaUtpHbebcWys/1DE+9UtWW12u1vEsbFcldoGfxFcet1cwZ 8m5dfXJ4/KllvLtwm+dSG68AVyypS5r3OxVKajaxJYyk3LhY0X16n+tRrIf7RYLEgO488/40kUwi feZG564NAeWW+LIzeWW4YCtbNGA6+kZdQXMaFsDnn/GpdUdhHbF40Y888+3vTdQE4u49m4jaOcZ7 1Yuba6uI7dYcscnJPOKS12A09HlljWOQKuV+6Bx2960rqU3MPlzQyyBupbB/lxWPC5sItrSh3x1z gCqzao0jkLlj6r0rT6vzayZpCu4KyRPdaLayRfJF5TZ4Ocn+dYc2jzq5Ee1x9cVp/apj/Hj8ajN0 +eWJP1rZUopWM5TlJ3ZhTW01uxWVCp+lRYwK2by5zbur/NkVik5rKUbMExetST/w/wC7UWKll5VD 7VAyLvQCc9aQilxzQA4e9J2OBSDINKCcUwE5xSk57fpQCcUEEjOKQAc7v/rUmMt/9anYPFBB3dKY DV+9TxjBpozmnAdaQCdsUmKdg46Um0+lAHd6ZA66PZONrAwIcMP9kUtzDBM8ey3Rcf6zIJyfb0qz pTKNEsd3/PvH1/3RT3aJJFfsTyKwnUity0ip/ZtsyY8ofhUQ0u0jflce1S3F6qSfIV9uelXNJvbV rrFzaRXGVJAlLAfX5SKw9rzOyHaxSktbHeCsarkYOBxmnJBAkoURx7SOrDio9Qu9PiVLiGXDSMd0 CxtiMf7xzkfrWe1xFcHYjtt9QalOfNZ7BoaRFsowFGPbvSLHHgsUA9OKz1mWL5SCR6mpDc5jIJJU dDWE51L6D0NDfCHCFVZT0IAp4FuxBEaEZ9Kx4bhFlG5jtHIzVpbpMZSMhQeAD1odSp3CyNWFohu2 4Cj0FPSROcce9ZdnNC022Wba5PAwWAHvitu4TTJdPcwpDbzQpvM8sjjzPYdhn3ArSLqvZg7EDyoB g9aoTXMaBiGyR2xS2lxYyM7XV1xGR8qKX3fiOP1q1qd9pM5BNgkCRpkCHeN/1yWxTTrb3FZFCO7w WJ5yuVqWO6YjnaBnoTzSiLS30wXqWkjAttCrcf8A1qr/AGqwYYXT5s+8/wD9jSc6qCyN+38TrAUV 1DAEDip5PElu1xLKPMXdHtBTt9a5YzWKNkWkowf+euf/AGWpoLjTJJRB9wMP+Wk2B/6DTVaq9ELl RtaXr8Wn3IlZgQ/DBC2W+uT1962LjxNZNCgBKvndtDZP1z61z0x0G4t40hjjsmAJ8+aST58duA2M /Sue/tPT0LFLaR8d/N4/9BrRusvMEkepReJLOSSBi2yVchnxwQePWll8WWybkV2Kk8Mcc/8A1q8x h1uyVlDWsm0Hp5mf6V0mm+MdAt7d0uLB2Y9MRK2B+JrSPtnvoDsbTaodTt50XG0tjHfFZ6fafPYL G+A3AC+1S6T8QtG0553itHiZmOxkgTIHp1qW9+LEbRHyHkUkYGYVFa2mKyI5muooDvgmVh6oRUcF 2Vi3SEgseCTUWnfEawms3TWHuWlLcGLOCPwIqrJ4n0Oe/VLO3Qxv1NyWTB+oaramiUkzQF6JoiCw HOMn+dalpHbhAA7OOhYMSFH0x/WsdtY8OzpCEtUh3SbGme4fyie/uB71nXHibQbdri38l1lQlVkt pfMQn1yTyKzcakvIpWR0H2mWKZo7gW/lA5WSMSFh7YIApJNYtlk+U7U9Wzn+VcefEulk5bzifdar N4g01nLGBj9d39DUtTjqtStHudlHr0LL8wPHcVn61PHdm3CODsJJH1FYcHiLQokYPpxdj0IdgPx5 pU8TaMCd9hvB65ZuP/Hqm9a2wKMe5ZG0DDOv55rO1KJJrVsnDL0YVpnxT4XVPl0qXd67iP5GsqTV bbU5/ItrUL5g2IuTwfxP86FGsgtE5iTBJG7moSMV2t94X064gSDSUuTqIGW826j8tsD5gvA5/wCB H8a5CKVbacrPHvCnBU+tdVyESWcDzSKqgnJxxXTTfD/xC0hMGns8Z+6d68/rUOieJtNsLzz5NOB2 KdgQDhvXmuqT4n2oUZt7rpjqP8aWo2rHKN4B8TjP/EqlOPRlP9awtR0q+0m4EF/bSW8pG4K4xkV6 evxTsh1gu/zH+Ncp4p8QaX4gm+1Fb1blE2Rg7dnXvzmnqJHHjO6lzxntV6yGmbnOofauR8v2fb19 91Rxos0whjB2lvl3HB/GgZWQnPArqtG1a6iSC28ltjDCtng/hWnDoPhyDSnaYXRuxiMyC7Ty0cju AhyPxqvLqlnolgdLurC1nvIiGWeF45VIPP31JqKkHJWGmi9dvqEI88xfI427jzj/AAp4g1GS1V2j kI67QpLH8KpH4hk2bWosMREbSBIB+WFGKpXPi9J4fK2XSrgAMs4Uj9DXHLDzVuU0Uo9TocaqEWRI JeRko/3/APvnGaQvqrHiC8H/AGyI/pXN3Xi+Sax+zx+ehC7Q2/JHvRovjG50tZxK0lz5q4G987fz p06U5J82hvHEeztbU6QrqxU4S6zj+4f8Kj36jFCrTPPHuHG4YzVAfES4E6SeSdqxlCuRz71XufGv 23yxLblio4yaqVGSWjOmnjYOS5oo0WvbsD/j5kzn1rUWSYj/AF8n/fVVNBFhqMD3V7DKIgcKsUqo SR9QePwrTuYBbwLeRMgtpDhAZQzr7HgHP4VxV4VUtzo9rRk7JEIabcP38n/fRqzCrseZpf8Avo1m nULq8QXD5lYfKik7eAangvUkPlvI1rKezgfoTwa46jmnZSPKx+sou1jUS2lkO1HmZjwAGPNa9r4d eFFn1K6e2iz91nO5v8KzLW7urFCYLuUFhhiCOfyFVrm6mnIaWV5COhdicVpQxFOGsm2zz5WR2cOv WMU8VtAPJtl7lshj6mtRdXEoJW3yvdi3avHtd1JrDTJJUOJMgKffNY1j8TdesITCjRz56GdSxH05 4r28JifbRu1YuKUo3R0XxH0HF0dagg2RTHFwqjhW7N+PesPwx4iutLZ7NrmSNCjeSwbG0nt+NV5f FPiHxVL9illXy5PvoigDHuW6D8a2bnwxpl3aR2ukJdPqJXeDNcIFfHXA2j/0KuiTRomye+luPtnl xTMpMSsS3zZJ781kyt4j6JNaFf8Ad/8ArUy21GW6uiLgbZo1Ebe5HGa045eR6UqNCMrto7bJwR57 qU91PeyG5IMinacDHSqmzJAAyTXSeLo0ivoTHEqb49zMo+8c8msFP3a7v4j0oatocklZikeWnlry e5qa4sb7TVt554miWZQ8T56ireiwWbXH2m/mCW8ZyVHLufQD+taHiHxMNYT7LDb+TbrwATycdPpT VgSNGLV57nS45kvJfNGA4Eh4NNXUr7vdzf8AfZrL0q1u3gWKGKFlZhkBvnNdi+haZLBFaWQvH1R+ MGVfLLY5GAv/ALNWNeTb0PawdbDxglNamL/aF5/z9zf99mmm/u/+fub/AL7NXJPDt7bFvtsltZ7T g+fMM/kMn9KrrpqOTt1G1bHoH/8Aia43Vk9Eeo/qyV9LDBf3n/P3N/32am+23RXP2uf/AL+Gm3el SWdus8lxEVb7uA4J/Nap+bHjAmUn0Ab/AArSjCrPVJnPUrYPujJ8QSySzRvJI8jbcZZs4FYLZNbG rnLh1k3Y4IwePzrJzntXYlJKzPn8VKDqtw2EjieQ/KM1aMMkCDzQRu5HvT7GRvOREVdxPUipr62F vOEDbyV3E49aDnKedx4qa5sbq0iiluLeSOOYZjZ0IDD29a6TQfD1hcKX1uW7tQ65hjiRd0g7n5u3 4VhavKhvWht7qe4tIjiHzjyo9MdB+FMCraxo8yh3Kr3IGcV6XpM8OhacYFvlZZQGAcEYP8q82tLp rSdZUfy2HRtoOPzrZj1KO4mjN3qXmR55QQlf5CplsUmWvF+lsVi1aNo2jkxHJscNhu2fqK5I7l4C mt5dP1PU7m4g0qG5ubZmz8qHGPf0/GiXw1d2pCXd7Ywv18trlWI+u3OKhTitGxuLZhBWIyTRtxXQ QeGp7ttlve2cjgZIRmOB+C1iXEDW88kLMrFGKllPB+lONSMnZMTg1qafhqCCbWYUuIw6HPynpnBo 1PTY7CSbdMxCuQAqj8O9N0eVbO5W6lD7VBxsbBzjimTaus1vcxzWscs8zEmdh8wNU1cqm+V3M8yB urH8RTo5FQYB/So8eopQMdQfypWOhSs7jpWLEHkD2phPTA5+lSIYy21y209do5qaeCxijO2W48zs jR4/rTRhWabumLbyrJ+7mZ9mOijNNWOMXg8piyA8HGM09Li2jtyikliOeKbZSujkBFIJ/iUUW7Gd 77mlNmJ5HlUpub5QxAB/E1C5jkUMUDAjuKS+iuLy4YsQzL8o9Kv2/hjVLralsPMcDogJx+lRGKTu x1KtkovYw5TGc7FA57VFXQ3nhTU7UAXM9ovs1ygx+tV4vDN9OSIpLWTHXZOpx+Ro9rBbsSi3sY3S jNK6lGKnHBxwc0larUkerYVj7UwS5YYqSJGdiqqSSDwBWhodukmpKk1rHMuDlZHKge/FF7DSudb8 OLgnU0EkkgETAqFPXIPFer3LtLGc7kOO4ryq0S3t2la2tUtznBEbFgfcEk+tdpp2oXMumRSIqNtB Dlzu6d8V1xtyJnMpWqOJPaRSBnbzFLFjkmrqylRtdiR3BGR+eKpWeoWt3JJtcCZT86lcH/vkEYp8 85zsM0MYz1MbZP6UuaPc1sxdV1tLCzab5Si8sGNeT674yur+48qFUht1J2pGMfjXf6jYrqNtLaGZ H3cNuHQ1z974GtVsWMJCSkfxKc/hk1z1KybsXGLOKk1C4niO5yfxqp5pV81fudLubN2t3iy69Spy DVOS0nP3IZCfYVFwJBrV3GoRJmC+lTafi4lMj3aQY67gTkfSsma3miP7yNlI9RTS2EzQ7sasjrJv 7MDowvOQPmJjx/U1zt/dGadypyoPBHpVMSVIGJQkA4HUikk1uypST2RGpbHNLuI//VR5gFIZR6VR AqkFwGO0E8nHSphKYJ2+yzOy4++Bg1AHBP3a6PSNRXSwWFtDIrIQySxBxg9+QfzoEYSnA5GTUbnn muyl07w7JoBuXlWG75Kosm4n0GPr7Vy8S2pmG9Swz0zjNOzG2ijt3HjtTs469K0Li2jdi0UPlp6A 5qzY+Wij90hK9yKOVkuSRoeG0cQSPuZVJwBXRxk9SSayFvBHbGRyIwO+auWWqLHA0/kShkw0LOo2 Nj1B6j2xQ0ZJtsuymF7duHEp4+6Cv864fULRBdSGKaJ8k5UNt2+3Jr0i3059WsWv3u7KBnyxQttz 9FUHFeY6pFs1CdQhPzk5Ixmo5bPc3jO+6M6XIbHH4GpVkAX1OKiZSD93FLEhkcKATn0FUBYiuZEY FSy49DiumtLiWW3Vt7YPTJBNZkGnRloxJuIx0J6Vr281nDcRQSmQIeohUMwH0JH86Zm3fYguZplY YkP5CoBcT55kOPoKt6tqkdwkTyRJHs+QGKJVBH+1jqfer2k3Fkv2f7LAt1cSqRILmEFEPbaDn86B W1Ob19Ed4pbdpChQAh+fm78gYrE2Afe/nXoWu+HP7Oijunv7Ke3d+YY2Y7frxgD6GsX+wTq+tfZb D7HEpUESGTZGMDnljUo1ucuQvbFN+XPLVu694dudAnWKee1uAwzvtpN6j2zjrWI2B2oAdGRh8f3a i71LHja+AOlRgZNMBtHtXTaN4MudZsGu0v7G3jBICzu25segVTWBNbm3meJiCVOCR0pDHw2kssRk UDaOpJp9i8kchKNg49Kat2Y7UwJ1Y8n2qfTo5bi5SCGMySSEKqgck+lCvfUJWtoXFurj/np/46P8 KctxclwPM4/3R/hXa6d4Rh0/TZ73WIraUhMiD7XskQ+6jnPtXG3WpQxNJBbQKAXyJGGXHtmhuxEY NmlPLstQXf5ynXFZbamyLtVQTnqQKrNNPK2JJSmO1RFE3cybj7is7yZuoxRbGoTysFUKPwqXzJ1U sZFGOcbc1G1iBp4ulurVjnBiWQiRfcgjpWdE1wshwu9M/eP+NCvcHypbGiJpyAS/P+6KuadbXV/O VV8Iql3baDgCpdClja/jiSGC4mk+VROB5a+5J/wror67fw2ogmmsnVxuzZ5YD25UVU5SS0RlCF3r oU3tdIjtwfMvGkI6kAA/htrJuIklikeymfMZ+ZHUZPuOKdcX9nqUw2yyws3TIAH86jKjT4yqTbi3 ORWEKknPl6m84wUdEN0/Tp79mL3Tx8cbV7+/SrUOl6lZ3OI9UEIHIcF8j8hWc2rPGMFyfoaum/8A tNn54mG5eoOc/wAq9CFO+tzldSytY7fSPFs+n6VcRanfSX9yuPs4WNjn2ZiB/WuC17XL3UbpprqN gTnaMEBR6CoRqbZ+9Tv7TbHJoYJmFJcyseMjNJGrfeJOa0LuaGfBK4YdwKjCx7RgHJ9qgdyDfgYy D+FTW1pNeMUgheSQc4RSxx+FJLHswcD8KtaVq9xpVy09ukbHaQQ65GKlsqNnuUL+3urKQR3MMkLn kK6lTj8abbsQys4YqDzV/VNYutfu43nSFSq7VEa7Rj8TWxB4fh+wN5V2JJwobH8BPoCOpqHNJalO F37upiX5jeaIo4xt78d6nl1U2caLasytjBIXg1Ld6NfJ5Pm2c6sE5Cxlv1FLe6ddPBCqWcwOcEmM ipUovRMlJpkNjbyairT3DfLnGTxV1oreNMCUYHoD/MVNaWVvY745izsMYHOPemywWRGVh4rpjNJa EtNszpHGSEbcPqKhaRsYJVB7cmp547VTzEpqt/o5YAQj6UnUHylS6cbQO3vVbjbW9baC2pXMTIBH Axw7b1+UdzgkVqat4OtVX/iT3EkpVcsLh0Ut/u4P6Vi6kb6spRZxmamk5ij+lacPhfVZp0jNs0YY 43t91fc4zV3V/CN7YbI4G+3YXl7eKTH0+ZRmlzx7hys5oilAYngcd6uHRdTHXT7of9sW/wAK2rHw rbyae0t9eXNtdH7kCW27I7EksMfkafPHuFmYdvHErhruOYxnpsO0n8SDWwD4TMQ3Q6sj45xNG3/s grHubG7gneJ0m+TjJBqJTMm7IJ4x86g/zp8yCzOht4/B7MfNl1cDHH7uM4/8eFXY9N8DuBu1XWE/ 7dIz/J640FgOB+dOXzCM5GKdwsdwmieBJX48RalGP9qwH9Gq3H4Y8ASHnxfcKR2axauBEpTg8n2N aug6HcatcFxHN9kjO64mRN2xe59M/Wi6EdjD4J8FXcoitPFtxJK3RVsWNFv8NdDuBhfGFtHJ3SS3 K4/EmsvUNTNo6aP4c/0aCQbZZguJpPXe/Xb7DA9q53UtOl064aP7ZFOwGS0W7H6gUXQz0eP4OWGz c/i6yC9iEH9Wp/8AwpzSv+hxs/8Avlf/AIuvJxe3IGBPLj0Dmnf2lff8/U//AH8NAtTsrNmj0OwO 0sDbx/d6/dFV5ZTtYlHI9xiun0G2V/D2nFhnNrEf/HRV77JDn5owfqK5JUot3ZdzzmdFfO0/Pnoe 1T6VvS4YEniNj+legNaQkECJfwFVrmzSOD5YxzxnFUoJBc8+YSyLkMSB1GaINOfz432Oqk5BA6n0 r0KSCzjADCP6AZqJ1tihCQFvTgDms0knoOx51JDciZ1jbcM9GHSpI7TUZFLJbllHVl6frXdLDLJ0 hij99oJqQ6e0mDKxcj1o5JPoGiOFW0lDiO4DIT3jCt/JqsiK3hAxbXE+OMyyhR+S5/nXaLpkOPnU E+4p32C3A/1Kf98in7K61DmSOMN7eQqEtzbWq5+7EnP5tzT7qKS4itxIWuJDn5m+bJrrvsFn3gj/ AO+BSW9rBvY+UuAcLx0qlSSDmucGbOSF2Afy3/udjz+lTXZuxOEZVdtoOE5/HBru2021OT9njyR/ cFRRWMPzGWFd4bjcvIqlHSxJx0scP9kRyLHPDclzuZUbDfXjBqlvukUsICyj+MKV/nXfXcKNCsYj DAdsCqV9bx+QB5Ue4jByo6elS6dwRxTzvMGLBolA7KST+I4qITQxsHB56E9Sa6g2kW0qVjAPbaKg lsrfoETHsopxpJDMW/uC+mwSIpzuIrHZmd9zcH2rqbq2jW3VVUbQemK527X99hVAA9K2irEjAWHQ 5pQzDkr+RoU4FGS1WIQyEL0NQSsSRnjFSP8AexUTjPbvQA7kjk/lSgYNAyRTgp9DQM1ZgT4bib/p sR+lY3863ZTnwqq45+05H5VhEHNJAJk0ZpcH0pMGmAZ96TdThn0rX0nQl1HLTX1vZxD+KY8n6DvS bGlcxsk+1PTgjmuhl8OWEN2sP9recrDl4YMhfrkiqF1pL2c4WOWO4jJ+VkOD+I6ilzIbi1uS3sbv YWaoCSFORnpWPNBKnLRn6jmunuF0+WAExzJLtGSo4zj61hyxOpKo7N9Rj+tKLYNJdSgpAp4NKbS4 HJifHqBTfLkBwVYfhVkjweKaxyetLtb0pm1jzg0BYd16Uqk5pFRsfdNPET5+6fyoA20cr4VmHrMP 5VgmtwxuPDLfKcmbpWMIZD/yzf8AKkgI6KlFtN/zyf8A75NL9lnPSGT/AL5NAEXNJmphZXJ6W8n/ AHwaeNOvD0tJj/2zNAFbNKp564qz/Zl9/wA+dx/37P8AhT00rUG6WNx+ER/woA6Dw3LEtrOu/EgB OMdvXNW7+80y4tDGJDJIB8uUIwfrVXw9pt3D9oE1tLFvUKu9CufzrWPhiUwtIXQMBwjA8n61hOjB u7N416i0RnR6rHYxoI7r7VGMfIyFWH0OMGtWHxLo7R4mdlz1R4zWJc6dqducfYlI9VIb+tZkk06T +TJbKWzjAGf5Vi8JQm7kVeeduboda2saHj9zdTQ/9cwwH5dP0qFtascYXVXP+/Dn+QFZ9roD32dl nIpHXfHt/nU8nhK4jXIs93sME/zqlgqJg4JmV4i1eK5gSGG788FssBHtAxWTYRxMxMhjTPRpMkD8 AOa1LrwvrMsvyaa6oOn3R/WteHwteR2qb4DuCjIAFbwpQhHljsXD3NjkJNlveFUlEqA8MoIB/Cun 125S7itJ0JRDFkA/yq9YeELSe4abVmntoFGAqAKzH8c4Fb76N4VuLeOL7XcKsS7VJkXP48U3NIpR ctTzuJzbOLi34I+8p6Gtuy1uzYf6RIYW91JH5ipNT0KG0nVtOnN5A5wQq/Mp/Ctmy8O29naIb6yt 4iy7me5faf8Avk8/kKirjVQjfe5rCM72Oc8S6np19Y28UBEsqNnzMEbR6fj/AErlhl3zjNdbLpvh 43MxW6nupckiK2i2RL7bm5P5VspbT6fag2GjWlu23JlKiWTPr8xOD9BQq7nqkTKOurKmi6PYa/pS RXGkywvGNv2qNCqn3LdM/WqFz4W0Wwu8TeI4vLB+5CnmSD2yDt/Ws/Um8Q6hORdyX10O25W2/l0F WrDQNRZMT2oC9izqD/Or9+W7sS5JbIvRS6BZkfZLaG4cdJL+dsZ9diDH5k1duNbu5bVYxqlvbQtn /j3UxRt7YAz+dUD4emB/1Sf99ipH0mSWFYRGCU68ipdGD31KhWlB3SM6S0tnkMi6vbK56kluf0rY 8N2LXOqBGmhmgRd8skTHAA9cgVUXw9Nn/UjH1FdN9ibRNAFtBF/pVz80pHVV7CplFRajDdnQ8ZUm mnsc54i1mLUNQcJIFSP5VXp0rnppnUHa2K17nTrmUk/ZJG+q1my6Je87bKX8Aa9mHLSpqEWePK85 XaMSeSRySzE/Wogpqa4hlguGikRkcHBU9RTra0muJ1jjheRmONqKSTXBOV3dnQlZaEtnJJbN5qJl sYGRxRNcyz3Rd1UErjgV1cfhK/kVftJiskx/y8vtOP8Ad+9+lQS6fomlz/v3utRCj5hCvkqD9SCc fgKxdWOy1Jpe0k7tWRz8dzciQOkjh8YDA849K07Pw1rN7GJltDFAefPnxGn/AH02AanPi17XK6Tp 1np4HR1j8yT/AL7fJH4YrGvdUvtRkMl5dzTse8jlqm9SWysdFoo3P7M0Ww/5CGsxzyDrDYxeZ+G8 4A/WkPiPTbL5dL0S33DpNefvm/754X9K5kk0Zo9lf4ncXNbZGxeeJ9Xvl2T3shj7Rr8qD6KOKoRX MokDLt3A5ztFVetb/hbSP7W1iKJ+IFO+ZvRB1py5acbgrydjppdRudG8GLcXEpa9vuIgR9xPX+v5 V5+bqXkZXB/2B/hW54v1caprUgi4toP3USjoAK541GHi7Oct2VN/ZRObyZlClgQOxUUn2h/RP++B /hUNAroMycXLg9E/74H+FXF12/SAQrJGsY7CFP8ACs4Ak8CtPT/D+q6mM2llLIneTGEH1Y8Ck5KO 7DluVBezed5o2CQHIYIAR+lLPdz3Th52ErYxl1Brabw9Z6cFfU9Vg64eK0/esPxHy/qaf/beiWHG maKJpB0nv38w/wDfAwv55rP2t/hVy+S25l6fpeo6i+2ysWmPfZDkD6nHFbA0CGxGdY1WztSOsUSi aT8l4H51mX/ifVtQXy5rx1hHSKL5EH/AV4rIdyeppWqS3dg91HXx+KdH0mNo9M0oXbnrNfKh59lA /may7zxhrN4nl/avJg7QwII0H4CsDoPrS9qapR3eonJvQtte3Nx8skhYE9wK7Sc/8I34Gj4C32oH PTkL2/T+dc94U0n+19ct4CP3QO+U+iDk1Y8b6uNT16RI/wDj3tx5UYHTjrWNX35qmi4Lli5HNl29 aUSMOpphp0ZTd84JHtXWtDIt2lw8TtOjEPGNycd6s2e69vXlnjCk/Mx55NOs7W4uFDW1u4jzjdt/ rWqYW09BJO3I9al1EnqUqcpLQ0LeW3htvLEiJ6Lmr2lax9juQizoUcjcuQc1kLc2E9zHcKyK0fUI nX6jpW1oiw6nq0SLHHtQhySg6DmtI4ptcvKZPBL4+bUPF3ivUtI1UW9otusDxK6OYQWIPuetc4fH OtHH76Pjp+7FdT8SrNb2wivY1Hm27YbH9w/4GvLgam5fQ6YeOdaUALNGAOmIxSS+ONalGHuFI9Ng rmM809UaRsKMmlZDuzVn8Q3twwaQxsR0O2mf25dD+GP/AL5qIWCxpumfn+6KUC1BIMQx67jU866D 5GPk1q4mXbJHGw/3f/r1SaWJuTbR5+rf41Ye3SVH8hMFVLE57fjVCqUkxONiXfD/AM+0f5n/ABpw liAIFuoBHIDNz+tQClxTESb4B/y7J+Z/xpwlhH/Lsn5mocDNBIHpQBaS5hRlJtImAPQk8/rVwa0s ZYwWUMO4YYI7/N9csax99GSaQi2bqMpsMAI68sai3w5yIfyY1EBS4A6nFO7CxaF3Hkbodw9C1WW1 O22BY9PjjPcrK/P5mskyKOnJphkY+g+lF2NaGg+oRllLRsdv3QXzj9Ksr4jkEZjMYZTx8xrECknJ p6pRcXKjrLTWJv7InmCgeSy7QeRWZq/iebWFgFzZ2qvCNoliTa7L2B5wcfSlt/l8N3J/vOBWIQD1 ovqFiYzK3SP9adFctC4eMbWHQiqvK/Snqc0XCxfOoylgyu2cd6v2krIhCLEXPV3cDP580yx0Ca8h WaOORkP8QUkD8hRdaeLWQiVVznAx3+g607ktIlltSQrXE8RyNwUuFX/69SaNrF5pN/KNMgt5nKFQ 8g3iP1ZDnAPvzVbULGULbtLafZYzGOXwC/vjtVnSNPv5WdtPsJJwI2yxGABjk+9K4JErarOlgkz+ SzjepEo3BvaqdhrU6QeSqQDzZFBcD5wM9PYU9NBunKxSRu0+ciPsBjsKk/4RjUUmSUWroFILZ6Yp FC6xqMltqd3A0cc0UihSkgzj3HofeuXkJPbHPStvxCc6xKe/FZrWk0ts9wkbGOP75A6ULYGQRjCO famI+GzxSpkBumMd6YfamB06+JLq+gVGhtYUtoNiLBCEyAc5Pqc9zWDeXsl7cGaRY1YgZ2LgGprL i3uOgO2qGPWl1AtwGIWzM67nzhfarmlasdK1GG7itYJnibcEmBKZ9wCKzVB8snPy55oBAOB0pjPQ bzxHe6poNzq94InkE6xmMLhWzk+tcjp06tqUT/ZfMO/Jj27sj6U5p3GhLDn5Gl3Ee4FWNBZIJJJ3 BHy7VNTbcaZ0V5DZ3zLvtY4WPIDAIx/KuU1GziW4b7PMjk/wIDxVnUJPt938oOF/iJp0K29suS2C OpIrNRtrc2dTmVrGamlXsiErEzD03Y/nUTRT2ZHnW0gA7ODiteTVFH+rMhHrV60tVvbQySTlWPQM vGKbmkRGm3sZGneIpdNS5SGztGaeMx75Y9zRg9Smeh96bdapNGrx7I5BIgyXXOPp6Ut9pBibfGyE 56Kao3yEOmePlFWmpImUWnqRG4ZzyM+2avGPUJYBLswhHy5I5HsKs6RptjIqz3c4briJDz+NT3Mv zjy+AowBjoK66OHUlduxzzqNOyMlLW4kbJVifYVoJYXdvCWdBsbggMCR+HapI59vJy79s9q1baSF LO5E6qpaMkMc/e7V1RoRh71zJ1G3axzQRs854pJNyoTipZJmLhcgLj86G2sh6HIrimrNo3WpXs0a aUZ+4CNx9q66PSNNxjYrHv8AOc/zrmLae7hBW2RvTKrV5bPUZVDzPtz2brXJUd+tjohG/Q07jRbE glEZT/vGsf7Hb+Y8e1lwcEhutdBaxolsBM4yBz81Zlx5YuXKjjNYKTva5bijNvIVsIw8BGW4O5Qf yz0psV9Kd0jhiAByh+Uf4Ul/PFNNHG0m2NT8xHOKt2WlWt5IILDU/wB5JxsZCua6Iq61MXvoVZr6 eRhLE7R4HIWQ4NbGk61dSK6hiMLgncSaZ/wh13DxcW05H9+DDj8uv6VctdMFmhjQS5JyTJCY/wCY pqMb7CuISXJeRsk+pqpcTxxIQCM1NdSrHlerepqnHbNPEzNDM4f5UIXqc9B6mrbEZrM1w5ODirMN q0hCRqxduAM9TUkdq0LEMpUg8q3UU2aaSF0MRPmlgECjvSd7aDIo9W1K1kaFnjiKfLtaJSQPyq1N rlw8MSxC2lkx82bZCB+Yq54j0S9t7O1v9XFvHNOOI43+cj1Ixx+dc8twyweQW+RSSARz+dZKCa95 alOXZmxb+JdVsZFS3ayVnYMdlugGR68VLP4gvonEiw2jOV+ZvKHOetR6d4bnuLYXW6Ft4yG84AAf kas22hRai0qS3KqLcYYowKnr3pulDsHO+5mp4mm3YNla9eoDD+TVpWmvF3Km0g5Gflkk/wDiqxdS gsIiIrWd5iGwfkwPw5p8tg2krHM7bZWGRE+OB+ByKXsYdh+0kaZ1w25Yx6euCefLuph/7NUieIBK uRbyY9Beyf1NZljb6desPN1BreRjyGXj860LrwvaW9o10dUynQFADuPoMGk6EA9pIYdcRHZpUuth /hW6PH5g1BJd6RdlpJbK/Zz1IuR/8RU9v4Qvp4EmEkKZ5CSNgj64Bp0+hTWK5ury1X0RHLMfwwKP YxWwe0ZXgv8AR7VSkcWoxhjkjzEbJ/FKtG+0xFDyS6jGOuAYxn64HNZNzp8rlfLVvqVxWrpHhZtV tVulussDhlKZ2n060eyW4c7JZZbCWHzXnv0WQdRDHnH4EUy3/suNWK3dw64yc2aMV/HdmtG78NTW 9rHE827dJgNt6Z/GqTaa+nXE0ErZCx/fIwKzqRtHRjjK72M2Sw0fBlOqXADf9Og4/J6b/Z+if9Bx /wDwF/8Asq1f+EfidMnU7cA9QSP8ai/4Ri2/6Cdp/wB9D/GtFF23JcvI6PR7vUU0KwEUMbILaPBL jptFXRfap/z7Rf8AfYrL0i0DaLYvtv8Am3j+6Wx90dOOlXfsC4BxqA/76/wpdQsW49R1SMgi0hz7 kGrY8Q64FKC2hC9wFQZ/Ssj7CB0OoD/gLUCzXP37/wD74NAy1Nd31w+6Swhz6ooX+QFOFxdbNptI 1H970qobQY/117/3xUNwjWsJmR7uUr0Qp1pq4GjHd3kY2pZxzAfxYqT+0r4f8wtf++f/AK9Y9obj UNzMLq1I7CPOfzqybGTH/H9cD6xCi7Qi2dXvQf8AkFf+Of8A16UaxdHg6T/45/8AXqmLKXtqE3/f sUv2OftfSfjGKLjsjTi1yWPk6HExHcqf/iqW48Qyzcto0Y9Nke3H5GswWd1gkX0n/fsUn2a9/wCf 5v8Av3/9ai7FYvxa9cRMGXT2+mwf/rpZfELTSFptKLOe5z/jVAW9/ni+OPdD/hVq00rWL2QR2915 jnoBGaLsBRr8Sf8AMJ/ME/1pH1+0fHmaOrAeqGtI+DfFI/5bQj6uP8ajfwn4qQZ8+2P/AAMf409Q 0M3+29N76LH/AN+6cmt6WD82ixH28s/4VFNaa1bymOa5hVx1BVqi26pnP2qA/wDAWpXHZFybXdJm iEY0S3VQc8Qk1UN/o5PzaPbn625/woxqhH+vtz/wE0AaoBzJbfkaV2KyH/bvDhHOhQ59oiP6Un2z wz/0A4h/wA/4U0pqn/Tsfw/+vUUn9popLfZAOuSR/jT5mFkLDe+FzcSg6PA3TA25x69qtC68Lf8A QEg/GP8A+tXHWk08Osu6mLJY/MSNvNdOp1JgCIbVgehBWm20CRb+1+Fx/wAwO3/79f8A1qel/wCF 166Nb/hEP8KqD+0sc21sfxWnH+0Cf+PS39zlf8KLsLF6TVfDDIqLpEShTn7owfwxio11Pw+Tzpdj j/rgtVSNQ/587c/iv+FNA1HOPsEH5j/CldhZGoNQ8M4H/EttPfEKUo1LwuP+Ybaf9+Y6ysakM406 H8x/8TTWGokc6ZGfpj/CndhZGq2reGADixtQf+uSV59dJKLt2SOKRd5K4kUDr6ZrqSt4w+bSF/L/ AOtUZjnHXSB+tCk0FkcrqN9qEkReRbZEGPliEYP6c1jG4kZtxY7vWuq1+OQWYY2H2dQ3L81yzlD7 /hWkXdCYhuJO7n86QSEnrTf3eeQfwNOCxnG3d+VUI6LwzbW1zehr6dkt05bHVvavTY9Z0NEVFChQ MABBXnHh+F1gkdtPknRjhSF/+uK2QkZ66NJ+C/8A16ylJ3Gkdj/bGie3/fApf7X0U/xAf8ArjvLt 8f8AIHl/74/+vQUtsc6Q/wD3z/8AXqeZjsdl/aujYyH/ACSk/tPSj0f/AMdrjgtn30lvy/8Ar0f6 AD/yDG/75/8Ar0czCx1kt3o4kS4jlczAYIYfLj8utOXVtPJ5yPpzXI507POnOP8AgNHm6aOthJ+A NF2Fjthf6Ycfvz/3yad9t0w/8vH/AI6f8K4UyaaOljL9dpppm0vH/HnL+R/wo5mFjvBe6Z/z8gf8 BP8AhQbzTOn2tf8Avk/4VwQl0k/8u0w/A/4Ub9KP/LGcfn/hRzBY737Tpp/5fV/I/wCFRm808EgX Wfyrhs6V3juAfx/+JpP+JSf4bkfif/iaOZhY7G9utHjt2uZ9QKmL5lULnca4q88evIzpBars7GRi T+lZOvyWywotr52CTu3k/wBQK52MOQSBWkVdai22Oj/4SO+uJPmVGTugXihNblWdZEUQuvUxjnH4 1z4eVM4yARzjvQZ5dxOOaiVLW6NFU0szs4/HMsZCyJ5nqSNp/Suv0XVLDWLTzBdCGRfvRuen09a8 ZZ3kYBq7fQYdItdNWS5urg3D8mKM7QB25/8ArU5S5Y6k7s9C8mz/AOggn/fQrlfE3iWx0tWgs77z rrH8A3BfqelMuNe06xs5ZLVVWQKcGQmVif8AgRx+leX3EzSyvI5yzEkn3pQblugaSNN/EWovc+bL cySDP3Wbj8q0x4vbyiPK5/unkVyqysBgH9Kfu3EZFW4KW4Kbjsdrofi26bUEjeRobZ/ldYyR+Nd+ 2g6XKRK12jMecmSvD45TE2QcZ9K7iHUI7nSoZFuHWXaEZM8DHeolSg90HPK+50tno9nqGqTMJ1S2 tztUkgb2/wAK3f7Itj/y/D/v4K4uGG0jjCrqjK3U4xjP51IRADj+13H/AAEUlZaIHqdh/Y1t/wA/ v/kQUh0a1Xre/wDj4rkCsZPy6u3/AHwtJ5Snn+1j/wB8CjmFY67+yLVuBdt+dRf2FbwSu73qsrdA jcj61zCwO3C6qxbP/PMf4VdXRNRKB5L/AMlP70yhB+o5pOoluNRN+DTbJczid5Fj5IORn25qabRY 7yQzSXXztyQG6VjySacmkrYNqUjsTumeFMbz6ZPQfgari7ht4xHZC2TA4knzI/6gL+lc8ZuU3Kxo 4pK1zeHhaNgSJiQOp3VSudK0q0MYub9VMjbECndk+men61g3M2o3WPO1rco6Ltwo/DGKz7+xubm2 IbUUkK/MoIxyPwrdOb8iLJHar4P0jeXazhkfP3pjn9B/jVpdDEUZjtp4rVD1W2QR5+u3k/jXnmnT X97ahxqUcbAlSrg5Bq4sOojO7VofwU0cq66iu+htat4W020tZbuYpI4HGeSx7CqS+A4bzSFEt3Hb zS4bpnYOwxkVkSJd3VwYDeo4T5ixBC1dWHU886hCPwNaXstBHn9/p09hezW0sbbo2K5x196qmNwf un8q9Ka31Hr/AGhbk+6n/Go3h1QAbbm3YnuTjH60c4WPONreho2t/dP5V6QLfUiMefbn6f8A66Db apniW3/E/wD2VHOHKedJGzEDbXdQ/wDFMeCnnxtvdTGE9Vj/AM8/lWrp9jeS3ka3DQeUWG4qcnHt zVrV9P1K71VpWa3trZVCRrM/IA/2Rz+lc1epzSUXsawjZNnkrKSc4OaBE5OApNespZWsCfvF+1ye ibY1/Mkk/kKia51CNv8ARLGxtwOhTBf/AL6PP5VsqzekURy92cHZeE9YvYxKto0UH/PaciNPzbGa t/2Noenc6jq/2iQdYbBN34b2wB+RrodQi1PUIJEuEjlLD7zSZP5msrSFmkWS1NnbvJbna28Ln/69 K83u7BoikfENhYjGk6LbxsOk93++f64Pyj8qoXuvapqzhbu9mlHQJuwo/AcV1psbjp/Zlqf+Ar/h VW4t5AVgGnwJK3K7EXP5gU4xj2E2zk79wmy3Xon3j6mqWa9AXT5gihtHt2PqyqSfx20jadJ/0A7c /wDAF/8Aia09okKx5+WpqgsTk4FegGwZRzoER+ka/wDxNKNOYjnQIR7eWP8ACj2gcpwGRmlAJPAr 0H+zBj/kAxfgg/wqa00hZrmOM6NFHuYAuyDA9+lJ1UkHKV9Ex4b8FXeruNtxeDyoQeuP/wBf8q8/ Zy7FicknJJr1bxAzvdx2cOnCeyt1CopiDLn2yKzVhQAf8U/D+Nun+FYUN3N7s0qbJI88Rd7Bc1aQ RwuCoDEd2Gf0rp9dls47URy6dHaynlGSJUP446iuRfPYg++a6lK5ib8fi/U4IRDHNEsYGAogTA/S qlzrtxexlLkRyZOc7QCPyrFZH9KYWZeo4o5V2Hzy7nYaVcaXcHyUjW2mfg5Gc+wJ6V0tnbfZJWkt Zvs9xnsoKEHsR6V5dHNtIIPIrftPE7QxhJozKV6Nu5rojKNtRqXc9NmlivLIpP5OXTEkfzHPHPav KLvRryK9dILWdkydg2EnFa6+L7xozHbWMLMejNHvYVp2OuarHDiVhGT18qPBx+Fc83Z6AkmcQ9je RE+ZbTL9YzSQyvbSbiuD6MK9Ft9Y8mUSsJpXH99M1keKru31O3e5e3ZJ4x8pVSBye9Tzphaz0OTu b0zPkjHsKrmZs5GKhzlulLmq5UDmydLmVcjdgEYIHeul8N2Oj6rHNa3Mci3m0mJw+Afw9q5TPHNW LG8ls7mOeJiGU9u49KipFuL5dGEZa6kl3C9pcy27riSNirCq2ZD0FdP4rtY7i2stZtB+6nUI4HZv 85H4Vm6VYW907C9FzGuMqyDj+RpUqnNC7HONmZWxz1NLtUdSK6g6Bo5/5ern8v8A7Gmf8I/pB6Xd x+X/ANar50RY5rcg75+lIZR2X866YeHtJ6C9m/If4U3/AIR/StxH26UH3SjnQWOZMjHvj6U3BPqT XV/8I5pn8OpH8UH+NJ/wjen/APQVx9UH/wAVRzoLHLbTShR2FdR/wjVgeRqqn/gA/wDiqUeG7L/o KL/37H/xVPnQWOZ2mlxXTr4bsc/Nqi49lH/xVXYPDmhj/W3kz/7rIKOZBYxEXHhWU+sn9RWDXqzW vhl9G/s0W5Vc5Mom+Yn88fpXOXPhTSTk29/IvoHKt/LFLmQzjM1JEgZueM10i+E7XPz6qB9Iwf8A 2arEPhayjkVjqpbBzjyf/sqfMhWOu0nwPp/2K1n+0XscjRqx8twnJGeoGf1q2ngzSotRMn+l+Y65 Ennvuz3561ai8SwRRJGJEwqgD5PT8aefElpIyF5R8pyMJj+tLmQWZLB4a0q3JZLRC3991Dt+bAmr q6fAg+VQv0QD+lU/+EmsSDh+f9ymjxFat1mUfSM0rhZmZfwW9r4ltzI6xxsgJYgADqPSn6rqmnWl oxS9E79FiQrz+Qq3cXuiXmftVss7YxudTwPaqq23hp3y9raov/XDJ/pTurBY8u19DJqjsBwQOc1q +HzBFoeoxXGqfZzMu1YVhEhk4PqOPzFd79i8LqXPlJMScjzoskfjTo20CKKSFLKONH+9sQYP19aO ZWA8XNs48zK5wO9V/LOeleuXvh/w3e8m8aBf7kUKqM/gOarR+DvCwOTqE7fUf4CnzIDz6ytd+n3c hQEooIJHSssq2ele4Wun+HLbS5tOSSFopfvM8OW/7661jzeC/C0hymoSRfQE/wA6VwseWqmYDxyp zU1vYy3Clo1XaOpZgMV6nZeGdC09JBHfRTB8ZM8anGPTKmr39k6DKoWWSzCjrsjUE/kop8yDU87+ 32Vvp0EG23eWI8nyg4b86o3GtLOpX7FDFj7pgG38xzn9K9Q1Pw94QuIEEZSARryVc/Mfpj+VcXf+ G7EENbSR28ZJ2tcT8yEdABjj8TSuijn7aTzG6Hc3YCrr2DhN0rhf9kcmoEzYyMAu1xwRUE13IxOW NUhXNC2uLKBCnzqxPIbkU2bVzGwjiVGU9MnislXDklhmpEWJmG1hnPQ1DpxbuaqrJKxce7llADAD HYCqV8hkj35+Zf5VrQ2hvY5PLeNZIk34ZsbwP61SRUdgHBwetNJIiUnLVmLuI71MlzIpH7x+O2a9 BtvA3h64gjnOrlVcZ2MQCKtf8IN4VAGdTfP/AF1H+FVzWIPPSXkUOJGwfemMGC5LE/U12Ou6LpGl wRJp1y85YktlgwH6VzRiVnCk7QeM46VSlcmxRiiDDdI3FSl4UGFU/U0yeJoJnj3K204ypyDUBzRc aROk7xPvidkPqDitWz15xKou0Eidz3rnycHrTgx4qHFPcpSa2PQFjgvEEiMPL7AVn+IbNo7GH7Ov zF8YHfis/wAOag8N0IGYFW6BzwDXTXHl3qtFLdRw4HDFCwz+Fc7jyyNVK6OBOm3rg4t3JPpVixst StLqOZbSfKMDwhrroNOto2y2rwlfQQtVl4rcJ+61GLd7xNW3MZWOzg1GJrRJfKXaUBP7wZHHcGuR 17WlvZikPyqvA+WqTedj5b+0/wC+X/wqq1vOwOb60Of9hv8ACqTVxWMm6Y/eJ4/U1r2t5DHocEYk aK5hmMoEg5bOMYHpx1qlPpPnJj7ZCGPf5j/Sqi6E8ThhqEXH+yf8KfMgsTSyGaRm9TknHWsvUSV2 Hp6ZrbEDrHt+0QH3BI/pVK40p7jrdQAfQk0OSCxhG4ZupJ+pqMsSa1zoQHW8h/KkGiKDzex/l/8A XpcyCxl7iBjeael1PGrIkjBWGGAPWt6GysokAlaCQ+u0D+tWBb6TkfuoifY//Xpc6A5cOc5bO71p 8koZerE/WusTS9Ml5Fsp/wCBN/jUiaFp2R+4wfZ2/wAaOcDi44yx+Zto9667SLfQbew+06tcfaJl X91aRg/huZe/48VP/wAI5pxOfLb8Hpf+Edsz8oMo9g4/wo5wscxLcJHK0qIoJJIUDgVDZ301vdiR HKsTg89R6V1TeFrRmxum/wC+h/hTf+EStc5Esox9P8KOZAaGiahBqF8iXSKiuCj46c55/PFTadex +HfErwyvi1uG2uQOA3Zvx/rWcPDqL925lU+yiop/Dwl5a+nJ9Smf60cyCx6XexWuo2jRrOqE8q5H T+tcjrUQOtuSdwMK5YA4JFZkGnX0Kjbq07AdAVP+NLPp+pzjDas5XsCnT9azmuZWQ4uzLl7eyvKG M7BVOVDcbag/taf/AJ+j/wB9VkTeGruVtzXwc+rA1B/wjF1/z8w/kf8ACqjZK1wep6j4dEX/AAjG lEyRg/Y4cgsP7gq+Xt88zxfi4rzjTCf7Js+f+WCf+gireT6mnZBc7kzWoPNzF/32KQz2YP8Ax9Rf 99iuHyaM0WC53XnWSYzd2/P/AE1X/GtK11jRbRQS1tJKP4mZW/KvM8n3oyfWiwXPVn8b2kfCyR4/ 2SP6VTufFen3i7ZlgbPduo/ECvNcml3fnS5UB18mpaashAnGO20E/wBKYdX00dJmP/ADXJ7qM81V kFzq/wC2dOC/fk/74pv9uaf3Mv4J/wDXrlaWiyC5039vWX9yX8AP8aQ6/ado5vwwP61zWaM+9FkF zo3160PSCY/U1Gdcs262ZP1YVgZNHNFkFzok160VcC0YH2cD+lO/4SK2wf8AQ3J/66j/AArm6QHm iyFc6I+Ioh/y5n8Zf/rVG3iHni2A/wCB/wD1qwqYxx1osh3Ns+IJN2Vgjx7kmop9Za4jMctrbuh6 qwJB/WuZudYggO0Zcjjiqh15zysC492paFRhKWyOm+0W45Gm2I/7YircetTxoEjigRB0Cp0rjP7e lz/qYx9WP+FB12fGdsQ/Oi6LVCo+h2f9u3gPBj/74FNOuXpPEij/AICK4w63dHp5Q/4Cf8aYdcvE 5KROvfAIo0D2M1ujtP7Zvs/67H0UUh1i+LZNy9YOnaml+pGwo4HIzV+ixkzT/t3UMf8AH035D/Ck bW9RbrdP+QrNpQKYF06tfY/4+pB9GxUUlzLcf66+dB/eZs/zqvinp5Yz5lsZx/dH/wCukwM7XY1O lykah5xGDswOea4pmweK9Gka0KkHR2x34P8AjXB3sAjvJlUbVDnCnsPSlBgxsOpXcI+Qqyj+9GrY /MVdg8TajHjY0C+4t0/wrQ8PW9sbec3Nk04bCgjPFZGoaa9ncMRG4gJ+UsMfhVqWthWOx0W6vtUt Xmmv1Rg+PuAZ49hWoLe67akh/wCAn/CuR0G806JGhvLbzGJyrZ6e1dB5mkdPscoPsD/hWUk7lIvi C86/2lH+Kn/Cl2X4OBqMP5H/AAqgH0g/8u034Z/wppfSecw3A/P/AOJqSjRK6jxjUYP1oK6lx/p1 ufoT/jWZv0f0uR+J/wAKC+j8fvLkf8DP+FMDS/4mna7t/wDvo/40v/E1xxcwfg3/ANlWXu0f/n4u R/20NKG0kni8uB/20pCNH/ib5/10B/4F/wDZUoOr93tz/wACH/xVUR/Zp6X9x/39/wDr0bdNP/MS uB/21/8Ar0wLv/E2P/Psf+BD/Glxqv8Actz/AMDH+NUdun/9BSf/AL+f/ZUeXZEfLq0o/wCBD/4q kBdP9qY5gtz/AMCFIBqYPNpAfyqsI7UjjV5P0/xpfIgbB/tiT8h/jQBZn0z+0LJ47u3Xf/Cse0c9 ucVx194f1OykKy2bgDpsG4fpXaWJhglwNQMgIxhgBzXWwyxzw5IG8feFOg7TcWwqfCmjyjQ9K3Xa yXcWI15w4xk1e8QaNFdgTWUKeaPvKnG4V6HPawnkRrn/AHaoSRonQKv04rsaRz3d7nAad4S1hXiu n0tniDZKuOo+npXRAXOdp0dQehyn/wBatie9vRCY47+SP5dqkscCsaS2vWZmbVFYnkkj/wCtXPU3 NY3sU9Us7m8s5LcaaE3DhkHQ/lXndxbtBPJDIBvRip5716W9tehTjU48444/+tXn2qWNxY3B+0gZ kJYEEHPPtUwZTKQCDqCfoafIYQqeUHBx827HXPaolBZsL1Par1xpF/a2/nz25WP13A/oDWoiiWye DXQeHb9ILjy5bcTI/bHOfzFc+qAmun8N6HeXMiXVvJENj8Bmwc0pbAkdVBNBLKsf9m7NxxuYHj9a uy2thG2JEgBx0CyGtrRdAvWLPqF4MqOIkJyT/tHPFbUlojKEkWJFwM7TtPT3965pKV9HodEKd+hw wi0peSkf4RvSLeaSinOkSSyA8EsQuPp1/WurvNHXyR9nvGWXbyCwZc/mDWNcaV4gjfFvJBcA5+6S p4+v9KOV9WDhJK9iimvxwAiCxFt7wx7T/wB9df1qhc31jcOXuLSeR/VySf1rQlTXoW2yqiN6MwH9 aiMmsj+GNh7MDSUUuhndmZ5+kHgae4/A/wCFAk0g5zZSADp1/wAKvmbWR1tlP5f4Uedq/e0B/Af4 VdxFDdouf+PeUfn/AIUf8SdukM4/P/4mtBp9UABOnKfog/8AiaY13qnbSc/9sx/8TSAwlbTrbUXR 45VtpB8h53BvTp/Srsv9mCJjH5+/HG48fyo1dNRvbUZ00o0Z3qypgjH/AAGkju7u/aGb7ASYx8y+ XgE+/HNV5ki2407yg0sk3mHrtyP6VYH9l54uLgf8CP8AhTvtd50OlLj/AK5D/ClF5cDrpS49oxS1 ZSLCaXayKJBLPtPTdNj+Zp39kW3a5kA/6+V/xqW3lN1AyyWu1k5VWXg1Sa7AyDpR+u3/AOvWEZzl Jx7FuKSuTGy0qGQJc6pLGSM/LLv/AJGpIrjQIG+WSacjvNOQP++QR/OqYvYz/wAwok+6f/XpxuoO M6Wf++f/AK9Xyt7snmXRGhPrEU0Zjj1MW8X923VY/wBQcms8R2BOf7Umyf8App/9emvc2e7LaWfq VP8AjSC808dNMP5H/GrjBLZBzMc0FoeV1WUf8C/+vQLa3yMavJ+n+NN+06aeumt+Tf40hm0sf8w5 v/HqZJJ9lgYf8hWT/P41j3sCadqME0V8xjlOyVwOV9/etX7RpOP+QeR+DVXvhpdzZSRpZskhU7WC t8p7dqaYFz7INu4auxGM521VtbRrlmma9KFTtUlck1nWrW39kQloQs4Yozlj29vWtFJ9GCKGtX4H LZPP6VVrCLosJiPl1Tj3T/61SLZyKBnVOf8AdH+FZwm0Un/j2kAPfJ/+JpQdDb/lnKv0P/1qkZea 0lz/AMhVfxT/AOxpPsM56aqmfp/9jVQRaEwzmbPpnn+VAj0TP+smB/3h/hRYC21jc441OP8AL/61 OWyvAoP9px4Pt/8AWqn5ei9PtEw/4GKXZpAIxezY9PMH+NAy8LW8/wCgjGT+H+FIbfUQCBfxY7c1 U8vSj0v5h/20H+NIYdNIONTnH/A//sqAOW8SmVtU8qeRZHjQAsp/GsgqgHQ/nW1f6TNJdyyxTwyq zfKTLzjtnNZFzBLbNtlAz7EEfpWsWrEMrMB6nFRscDinNz0pyLg5NVcRXCnNWreYQNkorZ/vDNOw DRdrEqQlHBkIO8Dt6UJgdloM0j6f51tOpuWbaYVXGB25rVD6yOsKt/wI1yHhW1kuL1it15AjXcTz z2rrvsFx21Rfy/8ArVFSWpSY7frDZ/0ZR+NZmuRarPpU8clt8uNxI68c+laa2Vx21RPy/wDsaQ2d 3g/8TKM/h/8AY1ncLHlv8RzVu00+5vWxBGWx1NdDrmjnDPHGgwMsyL978RWIitEAEJHuK2i7oUlY 07PwuZSwu7hoPTELNmrn/CHWwP8AyFh7ZtnFYn2m6xgXEv4OaY0056yuf+BGmSdha6asel3GjSXs cqS5aJnVk2OPrUdlealYFbS5tFulUYWaNM/nkVy9lOIr6GWTkKwJr0WB1kQOeQR1FeZiq7w8vdW5 10oKotehUF5Of+YbkeyKaDfS5/5Bbf8AfsVJOL83H+gzIqY+ZXOM+45FNxrn9+L/AL7/APsq3o1P aRUjOcOV2IzeuB/yCyP+2Y/xpGvcn5tMb/vgf41N/wAT0Yx5Z+kn/wBlTSdeHRB+D/8A160IIjfx jrppx67B/jSDUYe+nNn/AHf/AK9TCbxB/wA8T/32aUXGv8g27fXJoAgGpW2Tu038lP8AjTxqNoxI Ontn/dP+NSfadc/59m/M/wCFILnWh1tG/H/9mmIifUbIHBsDn/dakGpWOObDA/3WqcXmrA82JP4f /Y0hvdT76dn/AICP/iaAIf7T03vZEf8AAGoOo6X3tGH0Rv8ACpftt9jnTR+KD/Cj7dd99NX/AL9r /hQMh+3aOets3/fLf/E0hutFbrbt+R/+JqU384PzaYp/7ZrS/wBot30xf+/a0AV/N0Q/8sX/AC/+ xpC2iH/lkw/z/u1YOoqOumDH/XNf8aPt8bD/AJBf/kMf40AViuh9ww/Ef4U5RoX+1+JH+FSG/gzh tN5/3P8A69Bvrbvph/75P+NADB/YY6MfzFB/sQ9JD/30Kcb6z/i07A9drf40hvtPP/LiR/wFv8aA EA0bp5xH/Ax/jTvL0c8i6YH/AHx/jTRd6Z1axb8mo+16Sf8AlzI/BqAHeVpBODeSfg//ANegQ6W2 dt/MB/v/AP2VN+1aPx/ozfk3+FJ9o0Y/8uzD/vr/AAoAmFvpva/m/wC+/wD7KnfZrA4xfzf99H/4 qoPO0Q4/cN+v+FLu0Q/8sm/P/wCtQBObOz6DUZh+J/xoFja9tQmz9T/jUIXQzkkYAH94f4Unl6Ee h/8AHh/hQBJLpkckZCajIrdicnFMbSfNjAkvt2eD1IP4EUgXQweSP++l/wAKUroZ/jGPTctFwOa1 i2W3vCokMnHU1kupOTXU6tDpskCJZJulOfmDg4/AVypLK5DZ4PSt4tcpGtypuKyHk1PGBkHNO+yl yWDL9DQsMisAqZ+hpjL1pK4lXY21s8E9q2xoV03zG+txnnof/iaxLKFvtUYuA0cZblgucV1LafZM OL+YD6H/ABrOY0ZrafIh51SEfg3/AMTUZtQODqyf98t/hV1tBtH6ajN9Nh/xpv8AYmleUFe5naTP 3hxn8Oai4Mybs+Sdq3BnyOuCFH51UhQSzKjSbcnk9cVuHR9OXK/ap8emR/hUbaXYD7sr/VnH+FaK SsTYwr+FIbgrHL5g9cYqkav6pDHDchIn3LjrWfzmqTugEYd6bViG2muG2wxtIfRBmpLnSry1XfNb vGv+0KAsVkcowKnpW5YvFcxHdOqN3G3/AOvWD0qW2cRXCsyFkzyB3pNXBM6dbSyC5e6bPsf/AK9O Fvpve5Y/Uj/GiOTSCgbyWz6F/wD61PEukd4D/wB9n/CstShhh0oYzM35ilEOkdDM34sKk8/SB923 P4sf8KQ3OlD/AJdf1alcBnkaPn/WnH+8KPL0X++xP+8P8Kd9s0wf8ug/8eoF9p3/AD6fo1MCMjRw OAT/AMCH+FAOkd0b8/8A61SHUNPB+Wzz/wABNA1C0P8Ay4j/AL4P+NGoEW7SR/yzY/if8KQT6UD/ AKhv1/wqb+0LXHFgP++P/r0f2jFjiwH/AH7H+NIRCbjS+1sf/HqQ3Gmn/l1P/j1SDUQD/wAeSn28 paX+0H7WCj/tmKBiJqFrGMJA2Pxp/wDbCA8Qt+Rpo1CbtYj/AL4FL9uu+1l/44P8KYDv7YweIm/7 5qe31YTSYMePwxVb7bf/AMNkf++B/hR9s1TPFm3/AHz/APWoA3I5kbB71YGG5BxXO/adWPS1cfh/ 9alM2sEcQuPzp3FY6VVHrSlB3xiuYD6yTkxt+daFpLeBcTKfxNCFY19gx2/KgRqarrP03cfjUouo 8Y3frT0AkaAY60z7M1KLmHHMij8aX7TH/wA9B+dGgGDpg/4lFl/1wT/0EVbxVfS/+QRZ/wDXCP8A 9BFWhVAJijFaEcERUZTr701okXoopXGUegoxins5XoF/75FVpbmVG+UqP+AD/CmFibFGOKx59VvE HyyKP+2a/wCFZ02vakp+W4A+kSf4UAdVj2NGPY1xjeIdVz/x+MPoqj+lRHXtVOf9Ol/A4pgdxijF cTDreps43XspHua7iL5rC3lP32Xk+tAhvbpSUtFIBKKXvRQAUlLSUAGM1FKhZCPWpqQcmgDk7jS7 qGUlUMinoR1qE29zj/j3kz/uGuxwD2oIGOlK1zWnXnBWRxhtL1uls/5UCxvj/wAuzfia7IAYPFLg elLlNPrVTuceNNvjj/RyP+BVZh0i7fh1Cj3NdPil7U0kTLEVJbso2GnJZqT1c9TV8DiilFMwDFGK PSl7UgExU0Pnh/8AR5ER8cF+lRgAg1paRaw3V6kcyblPUZI/lQ9hogY6vjH2q2z/ALx/xrg9dili 1abzWUyMdxKngk167LomnjpA3/f1/wDGuI8Yafa24haOMgkkZLE/zNTDcZR8K3V+qTQWjJgYYhmx /WtTV4NT1CxeGdI3X7ww4yCPxqHwzY2zWc0xQ+YCBkORx+BrUktogOj/APfbf40S+IEedRb45AVB yDXd2l/q9xaRyrbo4YDBOOf0rM1OaW0vY7S3lkjtyoJjViAcnnPrVp/3Y2oSoA4ANOTuBo+frHX7 Cn5D/Cl87VT1sY/yH+FYrXMy9JG/OkF7cjGJWpWGbRk1HvpqH6KP8KUyX2OdLQ/8AH+FZUd/dbv9 c1Trf3WP9e3WpYFvzbrPOkj/AL9j/Ck8+UcnSB/37FQpqF2es71ML66wP379PWhANF22edJ/8hj/ ABoM6dTpI/74/wDr1Kl9dEj9+/51ZF3cZ/1zfnTCxS862OMaS2e/y/8A2VKZbX+LSv0P+NXhd3H/ AD1b86cLu4/56tUsDMM+nA/Nph/X/GhbnSz/AMuJH03Vp/ap+P3h/IUv2qbH3h1/uj/CgDPSfSww Is3H0Df4VuWt3E8ZnRmRcbTkkGqYuJD12/8AfA/wptw7NbnOOvYAVlUV2n2NKe9mT3GtRxggFj6k ZqhLdXhuARcSeUwyAef50unhS/Kqc+qg1blA81uOh4p80l1NbRbtYz5p7CZfLu3mZlPIA4/lVcJo mf8Alr/n8K3IYomiy0UZOOpQVILeA9YIv++BV81zne+hz7Q6HjmSYfVh/hXKeJmsfPiisi7bQS7M c/hXpn2K2OcwR/8AfNeYeJ40j8RXSIoVQRgD6VcNWJjPD9jbXN6Gu5NkKDJORyew5rsnt9EZMNdP g9jIP8ak8HWFpLoQkkgRnMh5Nbkml2JTm2T8BSnLUEjybU7e0tdReOzlMkPXJHT2r0P4dT6Vb2k7 3dzHHOzARliRt96891aNI9auUQYUSEAV3XhzTrSTRopHhBY9Tk1o3ZaiW+h6nClvcIHimWYED50I PI+lRyWypuwsZH8WeTXFwQR2zhoAY29VYg10WjXM1y7JM5kAHG7r+dTddjVTm3qzVXy13NKYvlHJ xjArG1HxHbxq0dg0fm9PMK8D6etUPFg3kQknysj5AcA8d/WuPe0g5/dLS5iZepfuYbi8mM02qs7t 3IP6cVD/AGfNj/kJL+R/wrNa2hwf3a0qW0JIzGOlQ9RGh/Z1x21RM+4/+xoXT73/AKCkX5f/AGNZ 7QRjOF6e5pphT/a/77P+NFguaf2C9zxqcP4j/wCtS/Y9QHTUrf8Az+FZWwAHDP8A99n/ABqPB5+e T/vs/wCNMLmz9k1L/oIWxpfs2qDOL22/P/69Y4BA+/J/32f8aEZyOZJP++zRYVza8nVx926tz/wL /wCvSrDrOOZ4M+z/AP2VY3myhRiWT/vs0faZ8/65/wDvo0WA34E1YSqZnhZM/MA4/wAafc/2n52b VlMfozYwfzrnDeXIziZ/zrVnuJf7Bjl3nzOPm79a56nu1E0ax1i0WS2uAfdQ/ST/AOvQJNdzzF/4 /XOHUrzH+vP5CmjU7zP+uP8A3yP8K6UjM6Uz67/zwP4NTftWuD/l0c/8C/8ArVgrqV2R/rj/AN8i po9Ruyf9cfyFFgNgXetdTYv+J/8ArUn2rWM82LH6j/61UPt90OPOanJfXRBJmakBb+2aqDzp/H+6 P8KH1G+H3tOb/vgf4Ugup/JP71uo7/WrllI7sdzsce9AjOW9lLZ/soDBzyi9aX+0GAO7Skznj5Fq /PPKkhCyOB9aj+0z5/1z/wDfVAFYagSMnSx/37H+NJ/aUffTF/79j/Grq3dx/wA9n/OnteXBRf3r UXAzv7UgBP8AxLB/3x/9emnVbcn5tOH/AHz/APXrR+1z8/vWoF3P/wA9DQmBmnUbNxzpw/I/40G8 sDgHT/yDf41ofa58n5/0FPFzKRywP1Uf4UAZf2zTQOdPP/j1L9q0kjmxcf8AfVapmbbnCf8AfA/w qTd/sR/9+1/wouBiG60dRzZuP++v8K4/Xbq2uL5zax7IQMAE5rsfErkaWQAq5YA7VA/lXnso+Y/W riJkUZ/e9Mg1OwUH5RmtGK0gXRI7kRjzmmKlsnpiqTgZqySIA46ZqoWy+T0zXaeErO2uri58+FZN sRI3dq4+VQJmAHc0J62A6fw1/ZT28guiyTAjBDAZH410Cx6KP+W7f99rXNeCreK51ry5k3p5Z4zX oDaNp+f+PZfzP+NRPcaMUR6P0Fw3/fQ/xpDb6U33b2RfoR/jWy2jaeT/AMey/wDfR/xqvJpFgvS3 H/fR/wAagoypLHTZEKnUJsHg9/8A2asibQoPOIhuWeP1K10Emm2YP+oX8zVVUWGRkjAVfQVSbWxU YpvU4/Uo/sDBFO8nPUU2ys729x5cIVf77nArp5LWC4uWMsSuV6ZHSmG1gB4iX8qpTdhSilKyMmPR WlRiX+YdQBV3RzcPdTWU180OxQVyDyK2dLjRWZVUAelZmswxjW7fCgblOcd6iUVL4i7WV0aS6fjO 3VR/3yf8KeNPkPTVk+h//ZrIMKDsev8AeNNdAv3Sw/4EaFFLRGbu9zZ/s+47atH/AJ/4DSf2fdZ/ 5CkP6f4VikEfxP8A99mmhnGf3kn/AH2adgNz+zr0fd1KE/iP8KUWOoDpqEH/AH0KwfMkB/1sn/fZ ponmz/rpP++zRYDohZaj2vbf/voU77Jqo6XcB/4EP8a5o3VwP+Wz/wDfVH225H/LZ/zpAdJ9n1kH ieA/8DH/AMVSiHXO0kJ/4H/9lXNm+uhyJmoXUbv/AJ7H8hQ0B0/la7j70f4P/wDZUu3Xx0Cn6Of8 a5dNTvD/AMtj/wB8j/CpP7TvNv8Arj/3yP8ACiwHShte6FOP940nma8p/wBUxHsxrATUbs/8tj09 BVpL65JGZT+QoA1Tca53t3/76P8AhTlutawM2zfmf/iaz47uckZlarInlz/rGqbgTtfaup5smb6f /s0w6hquPmsG/L/7GlWaUn/WN+dK08wGPNf86YXGf2hqAHNgf++B/hTTqV530/8AONf8KsefMMYl f86Bd3G4fvn/AO+qYFf+1Jv4tOH/AH7Wgaq3fThj/rmtW0u7jzUHmsQeuTTjdzg/61qQFIaovfTl /wC/S/40f2lD1OnD/v0v+NXftU5PMhP4UJcyk8sD+AoQFH+0IeQdOwe/7of40n2+2/58P/HP/r1p CeQ5yR/3yKRpmz0T/vgf4UIDNOoWg62X/jh/xpP7RsP+fP8A8db/ABrWVgRykf8A37X/AAqRUjI5 hi/79r/hRsBh/b9OPWz/AEeka70o9bXH4PXQGCH/AJ4xf98Cm/ZoM/6iL/vgUIDnJptLeJlWNoyR 95d2R+YrFurK1LBkBkQfe6g4+pruzZ2xPMEf/fIrP1m1gisGeOJVbI5Aq4y1sJ9zmornSYVANqhH fPJ/M0ebZNKDbRso/wBoismVQZDwKu2wGzpWihZ3uKVTmVrEkt2RcbAoKr1B71pRjTJYg9xGwPch gB/KudYn7Y31ra0wB5QrDKntVSjeJnFtFkw6Ce7j6SLSeRoI7yH/AIGv+FdCdIsCP+PdfzP+NMbS bDbj7Mv5muc2OfMWgjs34yL/AIU3Ghr0U/8Afwf4VuDSLDP/AB7L+Z/xpx0ewyP9GX8z/jQIxbe0 0S8nSMADJ6s4x/Ku0h0Hw81sqi008tjklVzWQdIsAhP2Zenqf8a86uXeK5mEbsuHIGD05q4aiZ6r LoUNuD/Z9vaxn1jH+Bpi6W0iFNQtlljPbDD+VeXQapfxN8l7cL9JDXofh2+up9LV5biR23HlmzTc baspTdrITU/CXhxbV5YreeOXHRZDj9RXn4WO3uWUDIViOa7/AMR3MyaTMyyEHB5FeZrI7HLMSc96 qDuyJbHUw39l5S5tELd8A/41J/aFoDxYJ/3wf8ao6B/x+AEAjHQjNdaSBHkIn/fA/wAKipZMIu5z /wDaUHawX/v3/wDXoGpxj/lwX/v0P8a2/OcA42/98D/CmvcyjowH/ARWdyzHGpA9NPU/9slpRfSn ppyn/tktaDXtwOkp/IU1r66/57NRcCj/AGjOp/48FB/65r/hR/aN2TxZAD/cH+FXTf3X/Pdqia+u i2PPf86LiIRf35+7aH8h/hR9t1M9LVvwH/1qeb25I/17/nQLq4/57Sf99U7gM+2aqf8Al2f9f8KX z9YP/LB/1/wqQ3M5/wCWz/8AfVRm4mOP3jfnSuMN+s54hb9aaV1luDG360NcS/8APRvzqu91OB/r DQwLIh1o9EwPx/xpptdaJ5Cj6t/9es97y4/56nrULX1z/wA9f0FAjV+x6uerIP8AgQ/xpPsOq95Y h/wIf41inULr/nqfyFN/tC6J/wBcfyFPUDaNhqR63EX/AH0tNOnXve7hH/AhWP8Abbk/8tmpPtM5 PMr/AJ0agbB0+7z/AMfsX/fQ/wAKP7PnHW/j/Bv/AK1ZXmyZ/wBY/wD30aRnf++//fRppMDYWxcE E36H8f8A61T/AGZv+fyP8zWEhJblm/76NW9vu3/fRqkgP//ZDQplbmRzdHJlYW0NCmVuZG9iag0K MTIgMCBvYmoNCjw8L1R5cGUvWE9iamVjdC9TdWJ0eXBlL0ltYWdlL1dpZHRoIDgwMC9IZWlnaHQg NDI3L0NvbG9yU3BhY2UvRGV2aWNlUkdCL0JpdHNQZXJDb21wb25lbnQgOC9GaWx0ZXIvRENURGVj b2RlL0ludGVycG9sYXRlIHRydWUvTGVuZ3RoIDM3MjE4Pj4NCnN0cmVhbQ0K/9j/4AAQSkZJRgAB AQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwc KDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIy MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAGrAyADASIAAhEBAxEB/8QAHwAA AQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpT VFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5 usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAA AAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEI FEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVm Z2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK 0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD2aebUJdVmgt7iCGOGKNvn gMhJYtnncuB8o/On7NU/6CNv/wCAZ/8Ai6F/5Dt9z0hg/nLVqgCts1T/AKCNv/4Bn/4ujZqn/QRt /wDwDP8A8XVmigCts1T/AKCNv/4Bn/4ujZqn/QRt/wDwDP8A8XVmigCts1T/AKCNv/4Bn/4ujZqn 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 UAFFFFABRRRQAUUUUAFFFFADk++v1qto3+rvP+v2b/0KrKffX61W0b/V3n/X7N/6FQAwf8h29/64 wfzlq1VUf8h29/64wfzlq1QAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUU AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQA UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABR RRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQA5Pvr9araN/q7z/r9m/8AQqsp 99frVbRv9Xef9fs3/oVADB/yHb3/AK4wfzlq1VUf8h29/wCuMH85atUAFFFFABRRRQAUUUUAFFFF ABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRS49KCrAZIOKAEopSrBckHFJQA UUUUAFFFLtY4+U80AJRTHljjcI8iK56KzAE/hUm1sZwcUAJRSgE9ATRtOCcHjrQAlFBBABIwD0pQ CemD+NACUU7y3/umkIx1oASiigYyMnAoAKK5a9+Jvg3TbyeyvNagiuYWMcilWJUjqOlT6R8QfCmv 6hHpumavFcXUgYqiqwJwMnqPSgDoqKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAo oooAKKKKAHJ99frVbRv9Xef9fs3/AKFVlPvr9araN/q7z/r9m/8AQqAGD/kO3v8A1xg/nLVqqo/5 Dt7/ANcYP5y1aoAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoo ooAKKKWgCnq2q2GgaVNqmpXAgtYF3OzfoAO5J6CvnLxh8ddf1m4kg0NzpViGwrJzMw9S3b6D86tf H7xXLf8AiGDw7BL/AKLYIrzKOjTMM8/RSPzNefeDfCd/4y8QwaZZo21mBnmA+WKPPLH+g7mgD6Z+ EdzqF38OLG61S4muLi4eVxJM5ZiN5xye2K7aorDT7bStLttPtAFhto1jRf8AZUY/pUtABRRRQAVy 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 mp6NZ3ErDmRowG/76GDXLS/BHwLKxf8As+ZDn7qXDgfzr0KigDhbT4OeBbVgf7GEp/6bSsw/LNdV pnh3QtEXGlaVaWhxjdDCqk/j1rQooADz1OaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig AooooAKKKKACiiigAooooAcn31+tVtG/1d5/1+zf+hVZT76/Wq2jf6u8/wCv2b/0KgBg/wCQ7e/9 cYP5y1aqqP8AkO3v/XGD+ctWqACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACi iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKK KACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoooo AKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAHJ99frVbRv9Xef9fs3/oVW U++v1qto3+rvP+v2b/0KgBg/5Dt7/wBcYP5y1aqqP+Q7e/8AXGD+ctWqACiiigAooooAKKKKACii igAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKK ACiiigAoorgf+Ev1yf4m3nhCCPT0WGA3CXDqxJXaCFK5689R2oA76iuQ8F+MpvEmo61o9/ZR22p6 PMIZvIYtFICWAKkgEcqeD7V1EV7bT3EltDcwyTx/fiWRWZfqAcigCeiqh1bTlleI6hZrJH99TOoK /UZ4q3nIyDkeooAKK4f4g+MNZ8HtbXljpkN/p+0yXa/MJIUVlDEHoQdwHt34rWTxKNW0vRdU0Oe2 ls9QuFjcyqSyqc5AAPDKQQQaAOioqvJfWsdylvJdQJcPgrE0ihmz0wM5Pt61YxzigAoqjqv9qm12 6QtoLhs5luyTHGB0yo5bP4fWsPwD4j1XxLotxdarYw28sFy8CzW7Ew3AU4LpnnbkEeh60AdVRXHe Kdd8X2Wrx2fhrw7FqMKwh555X2KrEnCg8ZOMH8ateCvEOoa34auNW1y3trEx3EsaiJiy7YztZs9/ mDDj096AOnorjvCHjlfENp4k1G8jSysNLu2iQyKVZYlUMzPyeepx26Vf8M67qPiiBdYjtYrLRZSR bLJlp7hQSN55ARSeg+Ykc8ZFAHRUVyvxC8Xt4K8NDUo7dZZJZ1t4/MzsQtk7mxzgBTwOTTtC8SXN 74q1HQp2trsW1tDdRXtopVGWT+Fl3MA3cYJyOeKAOoorj7fxob34nHwvaxK1rFYPPLcMDl3DKAFO cYGSCccn6Vl/8LHnOjy+J1htzoceq/YPKw3mtHkL5obOM7jnbj7o65oA9EooBDDIIKnkEdCKKACi iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKK KACiiigAooooAKKKKAHJ99frVbRv9Xef9fs3/oVWU++v1qto3+rvP+v2b/0KgBg/5Dt7/wBcYP5y 1aqqP+Q7e/8AXGD+ctWqACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAo oooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArxO+t5NT+Put2mn6qbG9fTSsE8UgB WUKpAI7+4645r2yoVs7VZRKLaASBt28IN2fXPWgDxzwBqk1h4W8WeGUtPsvjW2inkZs5lvH2thwx 5ZgT9OQR1NR/Dqy03V9N8N38XiWK01PT4p7d7SGFRMxcsWMmSSV6NuIwPY17UYYTcC4MMfngYEm0 bumOtV/7NtI2uZba3gtrm4Qq88UKh2JHUnHzYPODmgDxDw/4di1q08LWAv8ARnSw1WW5kvXuI2e9 RnyFER+YlsYIYDt1r2TRPEuk6/d6pa6bcNJLpk/2e4QxsoVskYGRyMqw49K4dfg9pb2QtJrPTQ+M NqEQlW4Y5zvC7tqsfxA9McV6TBa29rv8iFIzI252VQGdum5j3OO55oAyrs2kviyysrloWM1hcqYX Iy6logRtPUEZrzix8M6l4C+JVhpNk7SeF9Uu/PgV8nyJVViVB7HGf95cdxmvXjDC06zmCIzKMCQo Cw/HrT2w2Mqpw24ZGcH1oA8G1j7R/wAI18RzqQX+3f7Utxb5/wBcBvXyvL74xnbj3xXq+l+KLT+0 rLwzf3P/ABUI0+O4uIthxu2gt82MZzk49K3JbK0nu47uS1t3uY8bJmiUuv0YjI7/AJ0428JuzdGG L7QV8szbBuK5zt3Yzj2oAwPE/iPw7pk1ro3iKQRwaqjxhpVKxYGMqz5G3OeP6cVwHgO6t/AWieKN YnubuTwkl6q6acFzIu4ruQHGQSVXdwGxntXr8sUc6BJ4o5UByFdQwz9DUWoWv2/T57MyNEs0bRll UEqpGDjPGceucUAY3iHxAlv4Im1jS5BLJcwKLEjgvLKQsYAP+0ynHsaoahoeuaX4e0LSfDVvp1xF YBVmjvZGjV2UDax2jJ+bLEdzXUWdlbWFhbWVvCot7VVSJCMhQoG38eOvrVgHnOTnrQB87+HbHxDr Hw9+Idnb28LM940jrAxMjSq6s6KO67QcdyeK6PQpYovFXgy58MyEWbaPu1eKNyyIiKBmRckKwbcB 3yMV7JGkcG/yY0TccttUDcfU470RLFCXMcMaeYxLFVA3N6nHWgDzPxD4v03xl4SsPsCh9Fv9SWy1 G4uYRm1Qn72DkIScBWP3cg8Gsbwlper6Jr/jLw94Suo73S0hR7WaZ8pHM2392ZF7hSw46bR0Nera Vo9tpcF1HGPMa7ne4uHcAeY7deBwBgAAelXokjt4lihjWONeiqoVR9AKAPEtEXxEnx2S3vLLTIJh pQimit5mKR23HKluSw44PHWqMWkTRfCK58Ht/wAhgeIBbi16SN86ncF6ldvzbumOc172UQzmby18 0rtL7Rux6ZpDFEbgXHlJ523b5mwbsemeuPagBLeL7PbRQ7twjRU3eu0AZ/SpKDyTRQAUUUUAFFFF ABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUA FFFFABRRRQA5Pvr9araN/q7z/r9m/wDQqsp99frVbRv9Xef9fs3/AKFQAwf8h29/64wfzlq1VUf8 h29/64wfzlqHWn/4lN3bx6hFYXM8EkdvPI4XY5UhWGTztJB4oAvhgxIBBKnBweh9KWvO9ItwdbZL S2tdPL6otzHKl1E37nyoleIBWJYu0Zzxjox5xXog6Ckr9QCiiimAUUUUAFFFFABRRRQAUUUUAFFF FABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUU AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQA UUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAOT76/Wq 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 M2RuJI+UcAKoB9ADQ13XG0K0N1/Zl1eQRKZbh4CP3US/ebBI3EDJwOcA+2STxBZpcyqFcwQzRQSX HRUeQKVHPXhlye24de0HiZNXnWG1sNKjvbOUFrlWuliZgCMR8g/Kf4vbjuap3Xh29ulvbdxEtvqF 7BezlWJMTIsYdB658pdpxjk5xgZANOTxFaW8msLcxSxJpQQytwfMDLuG0A9T0we9W7O+S7nubZo2 hurYI0kTEH5WBKkEdQcMPqprDv8Aw3d6nceJkfZHHqCwG2k3ZG6NRjcByBuA/DNathYTprGo6pdB I5LuOGJIkbdtWMNyT0yWdvwA70AaVFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUA FFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQA5Pvr9araN/q7z/r9m /wDQqsp99frVbRv9Xef9fs3/AKFQAxf+Q7e/9cYP5y0zVzcLol+1pcR21yttIYp5SAkT7TtYk8AA 4JJ7Cnr/AMh29/64wfzlqh4p0+11Hw5fpc6WmplLeVorVgd0j7GwqkcqzdARyM0WvoC8zmdOgvbb VnWGzvrANqqyRzXkmIzbtFCskWSx3Mzq20DPPORnnvx0FeY6dHHZeI7Fo4tFnhM8PkvZ6RsZ1kLL lGMrYKMh3Hb8qkHqcV6cOgptJbMNL6BRRRSAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACii igAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAEZVddrKrDIOGUHn 15pSSxyetFFABRRRQAUUUUAFFFFABRkgcE0UUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAB RRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFF FFADk++v1qto3+rvP+v2b/0KrKffX61W0b/V3n/X7N/6FQBGP+Q7ff8AXGD+ctYviLUIoNd0mxu9 V/s2yuI7iSSYTiJmaPygq7m7HexI74HpW2P+Q7e/9cYP5y1YdEcYdFbHQMoOKFbqBzXhfxJp1/p8 UM2sWVxeLdXFvGDcIZZFSZ0Q4BySUVSSBznPeunpghiVgwijDDoQoBFSYPoabt0G7dBKKXB9DRg+ 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 ZG9iag0KMTMgMCBvYmoNCjw8L1R5cGUvWE9iamVjdC9TdWJ0eXBlL0ltYWdlL1dpZHRoIDQzMy9I ZWlnaHQgMzAzL0NvbG9yU3BhY2UvRGV2aWNlUkdCL0JpdHNQZXJDb21wb25lbnQgOC9GaWx0ZXIv RENURGVjb2RlL0ludGVycG9sYXRlIHRydWUvTGVuZ3RoIDE5MDcxPj4NCnN0cmVhbQ0K/9j/4AAQ SkZJRgABAQEAeAB4AAD/4QBwRXhpZgAASUkqAAgAAAABAGmHBAABAAAAGgAAAAAAAAABAIaSAgA7 AAAALAAAAAAAAABDUkVBVE9SOiBnZC1qcGVnIHYxLjAgKHVzaW5nIElKRyBKUEVHIHY2MiksIHF1 YWxpdHkgPSA4MAoAAMH/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4n ICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIy MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAEvAbEDASIAAhEBAxEB /8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQID AAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RF RkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEB AQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdh cRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldY WVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPE xcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDys8Gm05utNrvM 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 xRigBtLS4oxQAlFKBRigBKWjFGKAAUtAFOAPPFADacKAKUCgBBXbfCX/AJKbpH/bb/0S9cWBXbfC Yf8AFzNI/wC23/ol6U/hY1ufTtFFFchqf//ZDQplbmRzdHJlYW0NCmVuZG9iag0KMTQgMCBvYmoN Cjw8L1R5cGUvUGFnZS9QYXJlbnQgMiAwIFIvUmVzb3VyY2VzPDwvRm9udDw8L0YyIDcgMCBSL0Yx IDUgMCBSL0YzIDE2IDAgUj4+L1hPYmplY3Q8PC9NZXRhMTggMTggMCBSPj4vUHJvY1NldFsvUERG L1RleHQvSW1hZ2VCL0ltYWdlQy9JbWFnZUldID4+L01lZGlhQm94WyAwIDAgNjEyIDc5Ml0gL0Nv bnRlbnRzIDE1IDAgUi9Hcm91cDw8L1R5cGUvR3JvdXAvUy9UcmFuc3BhcmVuY3kvQ1MvRGV2aWNl UkdCPj4vVGFicy9TL1N0cnVjdFBhcmVudHMgMT4+DQplbmRvYmoNCjE1IDAgb2JqDQo8PC9GaWx0 ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDEyOTA+Pg0Kc3RyZWFtDQp4nJVXbW/bNhD+bsD/gfs0a1ho USRFaSiKLW9FunrzkhT70A6DoygvaGIllrKmf2q/cXdHkRFtS/EShBHJ473fcySbztmbN9PZwckh i9++ZfuHB2z/fDyaHidMJOz8ajwSLIZfwUzC40QxE2c8Zef34xEs8zSHQQrFVtdrC6fvxqNPk1+j vWRyG+3JyRK/LiMzucPZt0hNGH5c4VBF2WQV7anJVxwWsLeKNBDDCeaoqydYIiIWpZbwFj6WwHEZ Crl2vE8jOTk6ZjD+9jvSc6Cljc8Ttr8//QgbZ1MYMljXcbSnrbrTBOaxwLnyJyLWIAvUlBaaG9wv IyHtvLjDOapOitxHkvQkG0qYPOCHtQzYNPe4Rto2cDwlvktvbwNib7xRdZTD8l/s/P14dASxwfis BSXNJc8VReUTiUP5XhnyeGt4Dx8Rp1yEbOgoqU2qeA2RfULeEqCmKtAektAxHrzy9yVu0PnmZwjd o40/DF9h9lxz3C4qS79dqSRLeJKHWvU5Isk0j3VI+zmKROvRRd+x3EC2hseWXlOMoAt0J2d98t1Z 76Z2GfMO6WxEL1zAiy8MOWBMK/ry2Rwys4JCkcwnNc6eGyeqbnC0eWUgr7cbp6WAUu11HzuaHTDW AQDRAYD1BDM5l7vwSAZ4pIqn6StxNIqbbI12flcuwF11ySrvjxBF6nJ56Xzji8c7kHAA0hegAHxt sYD8XPkv8jhGoSaa7SXEkSsnh8PHRi1Nj8U6Zia54lp3rYkZAeW7bT7YArouP7sMXkddNKStXEi6 pbOorVqFSbkJV1Cw2tcrnHiEs4jXlKA71asykststzgrA4CzFudOvc4/gDJHv6CSZ0evgZ+O4X/L w0b3HAcM+U8e+k7AlCs/C2vw0gHcS73hzBbyyrmvALQX1l//lC7brlwh4t9LxwqqX7ki34D2pesv KgEqjBZJs0n44Jpl2WYiFMB1CTr3AEzlzHnCnboPFZRU6K7Aa4MlLQdKWmqM+A5M1ACTJObGAdTM tUjufTlfYIXCorFOK764SB3fIizcOB+t+pqbznmWhnIGldUDylKjbHFpRZnyhOpu3mzqB3e1oYSq Kxx9Ml26yFMY7aEe7TNJna0jmNwwvyGObXfoaW/C8Cw8+y8lz6zvgDRcmOBAdRHpDghaVH0d+bCw Q8m9rTs1XImA9OMZQ7NOyLgCJPK+wzKWXMleORuhTftDq3PBpcuPAwub16tFA7GhEN/BJ3aJyl45 1eT7+nUAFzqBxhmw7g20hitMGtL69ClK5uod7xkeuWnzu97wJ1zpfukb3jED3gHANrs17y7paQuN TumVLRYsiB/7/ABJa/oFbiidBe8WuZGJQnCVM60E1zs5Id/pHaRljA1sDbWwTbYtZtZa/K39T6j8 TMj+IWpBuujPhRyBNRAyfHeLB0IHNZLIELTuK7pC3gYYRXofYH5XK0QJBKmXLEMjqMm0r7AezfOY 5yaUOaz5wLUTbwnK/F/Uw8dMloSHHezZJ9yF7cBpF9Jc3LyD4NnVOAdYNKD9swUs+o36yj1Zi8bh pCNOWxKK+bVLAV8Fi0io9g1Y+ttD2/Z6wE6lPM9Dw4Z9mwS5jLXFY7UtnRVcB+CmOnRF3eQ+cDNQ ieZiJ0QW7mrwOB7twZ2EfjKIH1UstG2oP3jI5AlblePRnz+wJQjjuZA5SYy5UtJoBndPbY8YVoDU 6axsFiJjhxX7o5X6H+csdmcNCmVuZHN0cmVhbQ0KZW5kb2JqDQoxNiAwIG9iag0KPDwvVHlwZS9G b250L1N1YnR5cGUvVHJ1ZVR5cGUvTmFtZS9GMy9CYXNlRm9udC9UaW1lcyMyME5ldyMyMFJvbWFu LEJvbGQvRW5jb2RpbmcvV2luQW5zaUVuY29kaW5nL0ZvbnREZXNjcmlwdG9yIDE3IDAgUi9GaXJz dENoYXIgMzIvTGFzdENoYXIgMzIvV2lkdGhzIDYxIDAgUj4+DQplbmRvYmoNCjE3IDAgb2JqDQo8 PC9UeXBlL0ZvbnREZXNjcmlwdG9yL0ZvbnROYW1lL1RpbWVzIzIwTmV3IzIwUm9tYW4sQm9sZC9G bGFncyAzMi9JdGFsaWNBbmdsZSAwL0FzY2VudCA4OTEvRGVzY2VudCAtMjE2L0NhcEhlaWdodCA2 NzcvQXZnV2lkdGggNDI3L01heFdpZHRoIDI1NTgvRm9udFdlaWdodCA3MDAvWEhlaWdodCAyNTAv TGVhZGluZyA0Mi9TdGVtViA0Mi9Gb250QkJveFsgLTU1OCAtMjE2IDIwMDAgNjc3XSA+Pg0KZW5k b2JqDQoxOCAwIG9iag0KPDwvVHlwZS9YT2JqZWN0L1N1YnR5cGUvRm9ybS9SZXNvdXJjZXM8PC9Y T2JqZWN0PDwvSW1hZ2UxOSAxOSAwIFI+Pj4+L0JCb3hbIDAgMCAzMzQuNzcgMTM1LjU4XSAvTWF0 cml4WyAwLjIxNTA4IDAgMCAwLjUzMTA3IDAgMF0gL0xlbmd0aCA1Nz4+DQpzdHJlYW0NCnENCjMz NC4yIDAgMCAxMzUgLTAuMDAwMDAwMDAyIDAuNTc1OTkgY20NCi9JbWFnZTE5IERvIFENCg0KZW5k c3RyZWFtDQplbmRvYmoNCjE5IDAgb2JqDQo8PC9UeXBlL1hPYmplY3QvU3VidHlwZS9JbWFnZS9X aWR0aCAzODIvSGVpZ2h0IDg4L0NvbG9yU3BhY2UvRGV2aWNlUkdCL0JpdHNQZXJDb21wb25lbnQg OC9GaWx0ZXIvRENURGVjb2RlL0ludGVycG9sYXRlIHRydWUvTGVuZ3RoIDYwMTY+Pg0Kc3RyZWFt DQr/2P/gABBKRklGAAEBAQB4AHgAAP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8e HRocHCAkLicgIiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIy MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAFgBfgMB IgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUE BAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1 Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOk paanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAf AQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQF ITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdI SUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1 tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/APf6 KKKACiiigAooooAKKKKACiiigAo6Vl634h0zw9Z/adSuViVjtjQfM8jdlVRyT9Kw4R4l8UfPM0nh /Sm5WNMG8lHueRF9Bk+4oA377XNO06ZYJ7lTcPylvGDJK30RcsfriiK9v7kbotO8lOxupQrH32ru /Ug0aVoenaLEyWNqkZfmSQ5aSQ+rOeWP1NaB4GaAMu6XxAIy1pNppfsksUgH/fQb+lcrYfEa4g8X xeF/EWjmxv5iBDLBL5sUmeh6AgHH+OK2dQ8Xxm4ew0G1fV9RU7WSA4hhP/TST7q/Tk+1VNA8FNBr r+JNfuEv9dkGFZFxFbL02xg89O59/U5AOxFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQ AUUUUAFFFFABRRQSAMk4AoAKKiiuYJyRFNHIV6hGBxUtABRRRQAUUUUAFFFFABRRRQAUUUUAFFFF ABRRRQAUUUUAFch4p8ajSruLRdHt/wC0dfuP9VbKfliH9+Q9h3qv8R/GkvhbTIbbT083WL9vKtI8 ZweAWx36jHuat+B/Bsfhiwae6c3Ws3fz3l253MzHnaCew/WgBPDng02d3/bWu3H9p69IOZ3HyQD+ 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 wfE/i7T/AAxbx+fvnvZzttrKAbpZm7ADsPetIz6kfuWMH/A7kj+SGudsvC0ljr9xrn9nQXWpTDHn 3WoMxRf7qDysKPpQBVsfC2peJJ49U8ZurKDvg0eNv3EPp5n/AD0b68Cu4RFRQqKFUDAAGABWS17r sfXRbeT/AK5X2f8A0JBVeTxHfWwJuvDGrKo/ig8qYfkr7v0oA6CisLTPFulard/Y4WuYrsDJgubW SJx/30ordoAKKKKACiiigAooooArwWFnbSyS29rBFJIcu8cYUsfcjrViiigBrIrfeUH6ilAAGAKW igAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArI1HwvoerX0d7faZbT3UeNkzJ 84x05HNFFAF6106ysd5tbSCAucuY4wpY+pI61ZoooAKKKKACiiigAooooAKKKKACiiigAooooAKK KKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//ZDQplbmRzdHJlYW0NCmVuZG9iag0KMjAg MCBvYmoNCjw8L0F1dGhvcihBRE1JTikvQ3JlYXRvcij+/wBNAGkAYwByAG8AcwBvAGYAdACuACAA TwBmAGYAaQBjAGUAIABXAG8AcgBkACAAMgAwADAANykvQ3JlYXRpb25EYXRlKEQ6MjAxNDA4MDEy MjEzMzEpIC9Nb2REYXRlKEQ6MjAxNDA4MDEyMjEzMzEpIC9Qcm9kdWNlcij+/wBNAGkAYwByAG8A cwBvAGYAdACuACAATwBmAGYAaQBjAGUAIABXAG8AcgBkACAAMgAwADAANyk+Pg0KZW5kb2JqDQoy NiAwIG9iag0KPDwvVHlwZS9PYmpTdG0vTiAzNS9GaXJzdCAyNTcvRmlsdGVyL0ZsYXRlRGVjb2Rl L0xlbmd0aCA2Njc+Pg0Kc3RyZWFtDQp4nLVVTY/TMBS8I/Ef3hEOjb9jG61W4oKEVlpVu3tDqyqk Jg1N6yhJCeXX8xxX7MJC4gunybPnzTyPq5pLoMA1CAXcgMZvC4wqEBSYpCAY8ByBg9C4KEBRBkJC zmloycNiDpphpUFLrCxoowFbDecgGRiFFQdjsRJg0UpKsLkAJFtrQeboh1JSI2oG0gDDD5A4B5PB EFFbUAwYZwoUR8RCCUR0UhKY4BKUQsxxHfWENcBxX4ZTYV+uOeA0TKM4R542OC/6GEvh6oqsA5nC Hbkna3LzCegjkHUF09r19etXf6GwZQpfpohZyoe6OnWOvG+GN7thaN8RMrhyd/RN/cNtsy914/ps 9N227VzfZ6U/EE4ZJ9SSxld+hVv7fjXWw25Vtzt/dNnXtno7DT9/wD98ezQexzGrfLOt3LF2k9Wx IvWhqFxPovimH4vOf+v39Sa4bwJ7w54s5wN7edRT2/him431vj64bV1kvqtIqNpQERzh4I89kUQq 8nE9TaA2e3c++sFtys63yHtyn7+Ll+7hvG0xuOPQnIu2beKZs4LkBUZMC6UMNTy3mpY0/Aq15dtS fQ71ylA61tE2+X6buimeppXLv5wEikoxf2bH5IxYvuynlylmmWKXKTRhXpbA4QkckcBJyU+lZzzL 0Qkck8CxKRkmBZ2SNEuJmv0ja3Yh3btymK5t2g9v1gQmgp0AX60JWAQeQUSIffgkTJBHiCoitsvY LmO7jO0ytsvYLmO7jO0ytss4hIwqKqqoqKKiiooqKqqoqKImlUe4HPbh3DpyP3SncnjonLvzfiDr osN/oVCGFywkESIQse/Z7q37Pty4M/CL1u3p0H8KT3t0YuG9++W1EOLvCc1Esxz3IwS3/x7h5R6D 20+CnAcDDQplbmRzdHJlYW0NCmVuZG9iag0KNTcgMCBvYmoNClsgMjI2IDAgMCAwIDAgMCAwIDIy MSAwIDAgMCAwIDAgMCAyNTIgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAw IDUzMyAwIDAgMCAwIDAgMjUyIDAgMCAwIDAgMCAwIDAgMCAwIDQ1OSAwIDY0MiAwIDAgMCAwIDAg MCAwIDAgMCAwIDAgNDc5IDAgNDIzIDAgMCAwIDQ3MSAwIDIzMCAwIDAgMjMwIDAgNTI1IDUyNyAw IDAgMzQ5IDM5MSAzMzUgNTI1XSANCmVuZG9iag0KNTggMCBvYmoNCjw8L0ZpbHRlci9GbGF0ZURl Y29kZS9MZW5ndGggODAyMjkvTGVuZ3RoMSAxNzQ1NDA+Pg0Kc3RyZWFtDQp4nOx7B1yUV/ruOd/M MMMUZgYYigPM4FBEQBBQscHQRURAGAUVBcHesGBvMYlJSEzv1WTTNppkGE1E00xisultUzZ1zW42 nfRksybKfc73zrFtkvvf3L27N/fHgWee57ynfKe+30ucMM4Yc+BDy2pL6ysrflj9TRJTzi9lzHl2 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 nCfFuVJ0SXGOFGdLcZYU26Q4UwoZ9nAZ9nAZ9nAZ9nAZ9nAZ9nAZ9nAZ9nAZ9nAZ9nAZ9nAZ9nAZ 9nAZ9nAZ9nAZ9nAZ9nAZ9vDlUsj4h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4 h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4h8v4 h8uwh8uwh8uwh8toh8toh8toh8toh8toh8toh8toh8toh8toh5fsFgJRcyChwIWYOZDgAG2l3GmB hFGgLZTbTLQpkGAGbaTcBqL1ROuI1gbii0BrAvEloNVEq4g6qWwl5VYQLSfjskB8MaiDaCnREqqy mGgR0cJAXBloAdF8onlEc4nmBOJKQbMp107URjSLqJWohWgm0Qxq10y56UTTiKYSNRE1Ek0hmkzk I2ogqieaRFRHVEtUQzSRqJpoAlEV0fiAsxJUSTQu4BwPqiAqDzirQGUB5wRQKVEJUTGVFVE7L1Eh tSsgGks0hmqOJhpFzUcS5RONIBpONIw6yyPKpV5yiIYSZVNnWURDqF0mUQZROtFgojSiQUSp1HUK UTL1mUTkIRpIXScSuamdiyiBKJ4ojshJNCAwYCIoligmMKAGFE0URUYHUSQZI4jCiexUZiOykjGM yEJkpjITkZEolMoMRHqikEBsLUgXiK0DaYk0ZFQox4mYSryP6KhahR+h3I9EPxAdprJ/UO57or8T fUf0bSCmAfRNIKYe9DXlviL6kugLKvuccp8R9RJ9SmWfEH1Mxo+IPiT6gOh9qvI3yr1Hub9S7i9E 7xIdorI/E71DxreJ3iJ6k+gNqvI65f5E9Fogegro1UD0ZNArRC+T8Y9ELxG9SPQCVXme6DkyPkv0 DNHTRE9RlSeJniDjH4geJ3qM6CDRo1TzEco9THSA6CEqe5DoATLeT3Qf0X6ifUQ9VHMv5e4luodo D9HuQFQhKBCImgbqJvIT3U10F9GdRLuIdhLdEYiCv+a/p15uJ7qNym4luoXoZqLfEd1EdCPRDqIb qLPrqZfriK6lsmuIria6iuhKanAF5S4nuozoUiq7hHq5mOgiKruQ6AKi84m2E51HNc+lXBfROURn E51FtC3gaAWdGXDMAp1BdHrAMQe0lei0gMMH2hJwwBnzzQHHcNAmoo3UfAO1W0+0LuBoB62l5muI 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 XPpw6fbS6qVdl/5w6ctLq5d+s8y7rP2y4cvGL8tZtnVZ9fK+yycsv2n5puXPLD+8vGHF2BXLVry2 0r5y7MrwyhdW7lx5elXHVQtWbV1Vv3rE6tLV26NZ3zFXvXz2fNR8tokuPiNyHok+dkaMGeQ7xt6U s0dc83Fi9PTzzjqNM0+cNJ87ojvPiJwdopVnxJgX5Bya/Ezqzg73Mw8fGn2cWVPNweqb+bZ1FvPr pqQtyRsT9zfNmdRt3dAtR7ZNfDlp05m504gSs/MENf8atbombWmMnrwq52JV95C8r+qbEUTvy4mf MJNvocUhpW0/1m3k+5CSM6vDsbNWhQlx68CZlWCLtPuc2f+Zc2Z/tznn36XmezXLKz20TppAeVPj TEg+tpn5Ym4y5h9jfjPzyJzIDCizltM0OzZmlDkudUq0VrY4k+NuM6O10Vq0yVonuJeVVttt5rl9 gnmwMm5GPc88Gz+vnjunmjP3TtWbjFl0WuP8Ked1rvDUaH3aNq7MTM0aOiRzX3ubsY6pb9asDt+0 O0KvSmlcfRpXlZTO7W1nViCjV8q1TdW2yRq0fbN9irwjr8ha8npK58T9jT01tWNKZ1bAFNlelo2r Z9bR+JVU2qJWTXPdjFs5U9Bw9jp5f7PVcb+5MrZttJ773xhPl8+fmtXuSOoE7GkWfRk1GWMyFTdi G2NsjEQZTaOndMsh3lNkNmUkUrPablb53iZzEzeqR6Rtx9fGFbbS0BqtT41G6w2RT5Df3WbKrMiS 0dPkd7S+R0b3wQbGCtd9sFqV4kSucMbqptbH/1LUmhon59ZQK22cmCtuk5zbQq6030/UWnzB0rRi f4ecHSkpTev4d4ha2S9Y1G7jAuXs6Kg9SpycGz+1d4kT2e+NTH8/OVfzf7buwsSIs9y7JG25wj6l 6xWnEw/JXY+SDeqKXe501NmGKV3lHsi8h7CDGi53TcZVOffLkhS1O5qjdlZyD3V89HG1P2J3ROnN Kzao3Um0aRcjZeuMaObhGVG5g1FnW819jlHeyi6oVl6ROxrZLtMUteOJqL0RddXdrfKYtp3aW+Vu itmiZ+Zhte8qNSVLXekpd13qLCvzsJyXzHsIO7dB7NXkDk22W6tKiNqnhdR+jrpqp9a0X5uaNcai InJaxuKaiBGJK+zKHyw2LJ36ttItn7RW6VJ6m4/EczMa3w96VRlnwq5V6Ies0/XXrLNEK+sc4bWG 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 sKsCuyrEODIQJANBbPuYDASx7yQ96AQ96AR2foQl1VhSbZ317QnrnG9jrC6JZGYgq0si2RlovuPv oHedoHedwLpqrKvGumqsq8a6aqyrJjNBMhMkM0EyEyQzQTITJDNBMhMkM0EyEyQzQTITJDNBMhMk M0EyEyQzQTITJDNBMhMkM0EyEyQzQTITJDNBMhMkM0EyEyQzQTITJALVRKCaCFQTgWoiUE0EqolA NRGoJjNBcSVR8BMFP7nYTRT85GO3ZZK4CO8z8T7T/Hnr3eb7dF+i0J4oXEoU2hOFS82fEl9PrnaT q93kaje52k00MolGJtHIJBqZRCOTaGQSDT/R8BMNP9HwEw0/0fATDT/R8BMNP9HwEw0/0fATDT/R 8BMNP9HwEw0/0fATDT/R8BMNP9HwEw0/0fATDT/R8BMNP9HwEw0/0fATjUyikUk0MolGJtHIJBqZ RCOTaGQSDb9w0BdO4LEXj3+Cx4vxOAUPV+HhEpFGjHYQnx3EporYVBGHFGKQwt378H8H/u/A/x34 vwP/q/C/Cv+r8L8K/6vwvwo7qrCjCjuqsKMKO6qwowo7qrCjirES1J86a747IQZYrmGOmwNB5rlb mOMWQj6gG4uPNM11K5kzVut7PMv1Y54VsBJWwWqIwq2wBsrgNrgd1gJzo4e50cPc6GFu9DA3epgb PcyNHuZGD3Ojh7nRw7zoYV70MC96mBc9zIse5kUP86KHeTHJBW7wMOfJmf2Ysj3GGK9jjNcxxuuI m3xP78ndA4zdOsZuHWO3jrFbx9itw/YYtsewPYbtMWyPYXsM22PYHsP2GLbHsD2G7TFsj2F7DNtj 2B7D9hi2x7A9hu0xbI9hewzbY9gew/YYtsewPYbtMWyPYXsM22PYHsN2OWfN0f9EtN8hwm80zVnS o4/EYDwq534t90+SjdNk4zTZOE3dj6jrpK6HkeLG0wxGihtvM8yfAe0kQ6fJ0Gm8LMfLcrwsx8ty vCzHy3K8LMfLcrwsx8tyvCzHy3K8LMfLcrwsx8tyvCzHy3K8LMfLcrwsx8tyvCzHy3K8LMfLcrws x8tyvCzHy3K8LMfLcrwsF5fhSRm52UVudlmCojP52YUH2YyAfzACGvDkNjzpYP5kpoP8yQye/FT+ NIvc7SJ3u8jdLnK3i9ztwqsyvCrDqzK8KsOrMrwqw6syvCrDqzK8KsOrMrwqw6syvCrDqzK8KsOr Mrwqw6syvCrDqzK8KsOrMrwqw6syvCrDqzK8KsOrMrwqw6syvCrDqzLG8Rw1jofjxbvmvzldhdX3 YfWLwoO/e/F3L77uxa92+NSOOw/gz1782Ys/e/FnL/7sFXZLCXldrP/DskT/1HIb/eJH+peWB/4P cfceH3dd53v8l5kmaScTyqUUEBC5iKKriAquICpaWVxXdr3hbcXdFaytFFqgQFsLrSKoXMqdglRg qbWAUCUWLbRRoNgSTEnaSTOdhCY0DUmmv0yTNJlMU+B7npOtHvSc8zjnn3POHy8nM5n5/b7f9/tz +8aQln/S7tWxxLWhGFX4373RSd5RTFwlIubh2tCSuC6amLjep28MvYm7yn9DJexL3BP21Zhva8y3 NUfjrTgGb8OxOA4XeM+F+Dam4zuYgZn4Li7CLFyMSzAbc3ApLsPlmIsrcCWuwjzMD/vG9zNmpV2J haHHXnYm7gi7E0560dcSl4r2yzDXq1fZ5TxcE5oSi7AY38e10aGJ68KqxBLvuyV0Jm7FbbgdS8Ma +1tTkwh/qkliAipRhWpMxCSkUIM0anEAJuNAHISDcQim4FBMxWE4HEfgLTgyFGhYoGGBhgUaFmhY oGGBhoWa00NTzRn4CM7ER/ExfBxn4RP4JKbhUzgb/4Bz8GlcYB8X4tuYju9gBmbiu7gIs3AxLsFs zMGluAyXYy6uwJW4CvMwP6yJJoic7VTcQsVXEneFQbF0bRgSJ6PRv3ChxIUSB8Y4UI6wV3Scoo5T 9I4ilUtULukwRR2mqMMUdZiiDlPUYYrUL1G/RP0S9UvUL1G/RP0S9UvUL1G/RP0S9UvUL1G/RP0S 9UvUL1G/RP0S9UvUL1G/RP0S9UvUL1F/jPpj1B+j/hj1x6g/Rv0x6o/pckVdrqjLFXW5oi5X1OWK ulxRlytSt0TdEnVL1C1Rt0TdEnVL1C1Rt0TdEnVL1C1Rt0TdEnVL1C1Rt0TdEnVL1C1Rt0TdEnVL cu4K0V3OxYU0vVp0XxsdQO0uau+g9u5oNo3raVwv0nu9cyOtu2jdlZjv+cLQ51NDIj8W+bHIj0V+ zIfX+VDPh3o+DCZuDhtkQKsMaJUBrTKgVS79SW34I49aeNTCo3oe1fOonkf1PKrnUT2P6nlUz6N6 HtXzqJ5H9Tyq51E9j+p5VM+jeh7V86ieR/U8qudRPY/qeVTPo3oe1fOonkf1PKrnUT2P6nnUxaMu HnXxqItHXTzq4lEXj7pkSCxDYhkSy5BYhsQyJJYhsQyJZUgsQ2IZEsuQWIbEMiSWIbEMiXlcz+N6 HtfzuJ7H9Tyu53E9j+t53MLjFh638LiFxy08buFxC49beNzC4xYet/C4hcctPG7hcQuPW3jcwuMW HrfwuIXHLTxu4XFLNIOD3Rzs5uAefj/Lxd2cy3FuF+cKnCtwrsC5Av/T/H+CezH34sQNXruJ00vC Yxzs5WAvB3s52MvBfg4OipN1XOzgYgcXYy7GXIy5GHMx5mLMxW4udnOxm4vdXOzmYjcXu7nYzcVu LnZzsZuL3Vzs5mI3F7u52M3Fbi52c7Gbi91c7OZiNxe7udjNxW4uFbhU4FKBSwUuFbhU4FKBSwUu FbhU4FKBSwUuFbhU4FKBSwUuxVyKuRRzKeZSzKWYSzGXYi51cKmDSx1c6uBSB5c6uNTBpQ4udXCp g0sdXOrgUgeXOrjUwaUOLnVwqYNLHVzq4FIHlzq41BG9j0tFLhXHs/G/XBjmwiAXBjlQ5ED53DRI 3UHqDlJ3kLqD1B2kbpG6ReoWqVukbpG6ReoWqVukbpG6ReoWqVukbpG6ReoWqVukbpG6ReoWqVuk bpG6ReoWqVukbpE6g9QZpM4gdQapM0idQeoMUmcwepfK8JrK8Jrsj/XzVOIGu7jRLsZX7+u7sFS/ v0ffPtJUdxSOxltxDN6GY3EcLvCeC/FtTMd3YIKk9SitR2k9SutRWo/SepTWo7QepfUorUdpPUrr UVqP0nqU1qO0HqX1aPQdWvfSuteKYyuOZUFeFuRlQV4W5Mf1/3MG0P1/iHwTfKL8k43/dbT38qOX H7386OVHLz96+dHLj15+9PKjlx+9/OjlRy8/evnRy49efvTyo5cfvfzo5UcvP3r50cuPXn70UjCm YEzBmIIxBWMKxhSMKRjLhrxsyMuGvGzIy4a8bMjLhrxsyMuGvGzIy4a8bMjLhrxsyMuGvGzI/x9k Q55DeQ7lOZTnUJ5DeQ7lOZTnUJ5DeQ7lOZTnUJ5DeQ7lOZTnUJ5DeQ7lOZTnUJ5DeQ7lx3v8wPj/ C3kar2JexapNrNp00z6mfVnjmMYxjWMaxzSOaRzTOKZxTOOYxjGNYxrHNI5pHNM4pnFM45jGMY1j Gsc0jmkc0zimcUzj8h5je4ztMbbH2B5je4ztMbbH2B5je4ztMbbH2B5je4ztMbbHuKYcC3NxBa6E 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 gm1TrbapVjnVKac65VSnnOrUqDo1qk6NqtM2VSmnKuX2V6VG1SinGmVVoy3c2aiytKss7VzayKGN qst21WW7CrJdtWhXLdpVhnaVoV1laOdUE6eaONWkKmxXAdo51cSpJpnfzqmNMr9ZxjfL+GYZ3yzj m2V8s4xvlO2Nsj0n23OyPSfbG2V7Tra3c7FJlrfL8nZZ3i7L252Je03H5bn6g+G16FRZVj5nfVdG LZVRS2XUs3xeJGv28nUFX+v4Widb8nzt4uvjPH2cp4/LiJIsKPFiES8WyYASPxaJ+JIoXyrKl4ry pbxYJMpLorwkypeK8qWieS+9HqfT46J5L60ep1UXrbpE9V56dYnkvfSpo08dfero0yWa94rmvTSq o1EdfR4XvSXRu1Tk7rXnOnt8LtwkYkftYJ1ne6x9JDwiNrdHb7GzPZ5121mfnfXZ2YBdNaoDeTtr tLNGq9tjdY1W12h1e6yu0ar2WNEeK+qzoj4r6rOaPVazx2r6rKbPahqtonyW7YuOcacRd9rmTt3u 1O1OvTQsn1Gb3G3Y3ZrcrcndRtytyd2a3G3E3ZpoMUSLIXcdocWQO4+4c7c7d7tzNy2G3H3E3Ufc vdvdu929yd3L58NuZ4Tt6uWe8JJdv+TOw+7YrpatUXFbVdzy+eC34xW3yruG95+h8vv/G6aTk1+J 3j+uXKfvtPtO5/iz8tlu37iOlfs/NeRZ7PpbXX/QNJw108YUHrPPFCUiVJpJq1CNYz0/EcvCgGts H3em2bvbdJHyGoejE13jed/5Hf2GXOsp73j1z+f78X4TqS/VmIhUeMquPmc336LjEB2303E7Hcvn 6+30G7KGp6zheWt43hqep+Vfn7uPxFFvOn8f6/0nyMUTPS7z/vu9Vj5zV9hzITrM+gatadCadlnT rv0/wdlt9X3Wtdu6dlvHbuvYbQ273XvQvQfde9B9d7nvLvfd5X673G+Xe+12n0H32BWd4OpP2/0f 7Xzjm6pshs6PuVNxvKqmxn9T5If7vdxm9zPKv9Hz5+pjxxvd9Wl3fdpdn/6fVp5ypTnW+8pV5kSP 5YqxzHv/tmJMGu+ie8wBe52tq/j6pTB7/293vOTOXx3/jdH3W/d27/wt1xqdC7Za/++ptOpNFaTc GbKUWsbrct99lVrLqLXMfn7vqje42uNcbDS7baXgMgou42QjFZfJiKyMyHK00f5+Lyuy9rjdHrfb 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 V+BKXIV5mI8F+B4W4mpcg/vDLPVilnoxa8LmaPKELcigBVvRiiy2IYc2tONl0FO0LxTtC9WaBZUH hRZRP1+NmVW5K0qpLwvUlwXqy6zKfdFBVUmIraqDcQiOx0lhVtW7PJ6CD0RT1ZRZVR/y9UVhgfqx QP1YoH4sUD/mqh9z1Y+Z6sfMKrFUNR9iqeqe0FJ17/h/Qd9SfTTeimPwNpyCc8NKmTZfps2XaQur 50STqy/FIizGrbjb6/d7fDB6q2xaWP2orzu9/xXsgJiTOXfInDtkzkqZs7K6P5pUXcBu7x/2ffEn gxZWj0aTJ04JLRMPxVQchsNxBN6CI3EUrHWitU601onWOvFYHIfjcQLejm+51gW4EAs9vxrXhJZJ FaEl9ZVwWeprWBguSl0DeZOSNyl5k5I3KXmTkjepm3AzluAW2G/qNtyOO3An7sLdWIp7cC9+ivuw DD8DfVIP4EH8Jx7C8mhyzQJ8DwtxNa4BbWtoW/N9yO8a+V0jv2vkd4111lhnjXXWWGeNddZYZ411 1lhnjXXWWGeNNdZYY4011lhjjTXWWGONNdZYY/rd0eQDJiGFmvK/9JR8SaZ0qUblr8p/e+SwxJWq WXr8XxeoQjUmovwvy6ZQg/T4X7BPq2bp8r9EbALImQByJoCcCSBnAsiZAHImgJwJIGcCyJkAcirf ISrfISaBvEkgbxLImwTyJoG8SSBvEsibBPImgbxJIG8SyKuS01XJ6ark9PK/dxzNwEx8FxdhFi7G JZiNObgUl4UZKupsFXW2ijpbRZ2tos5WTaepptNU02mq6TTVdJpqmlJNU6ppSjVNqaYp1TSlmqZU 05RqmlJNU/puu77bru+267vt+m67vtuu77ZH5Z93rMTDeARroiNU3iP034L+W9B/C/pvQf8t6L8F /beg/xb034L+W9B/C/pvQf8tqNZzVOs5qvWcqMdZthd9yGMXYvSjgN0YwCCGwt0q+wqVfYXKvkJl X6Gyr1DV56nq81T1ear6PFV9npk+a6bPmumzZvqsmT5rps+a6bNm+qyZPmumz5rps2b6rJk+a6bP mumzZvqsmT5rps+a6bNm+qyZPmumz5rps2b6rJk+a6bPmumzZvqsmT5rps+a6bNm+qyZPmumz5rp s2b6rJk+a6bPmumzZvps+V+1rvgcPo8v4Iu4N2R0ooxOlNGJMjpRRifK6EQZnSijE2V0ooxOlNGJ MjpRRifK6EQZnSijE2V0ooxOlNGJMjpRRifK6EQZnSijE2V0ooyzRJ2zxFpnibXOEmudJdY6S6x1 lqhzlqhzlqhzlqhzlqir+FOUqmjEJrwUpXSxtC6W1sXSidPL/42qx096PCdco5udq5udO97Nvh7i xAWYobu9qaslZoVYZztTZ5ups52ps810Fl+SvCw8lnw6PJusjw5IPqP7veQ83+ycviU6TJfL63LJ ZKvz/X91ukqd7oTxvzGZ9/ounefyKK3LpXW5tC6X1uXSulxal0vrcmldLq3LpXW5tC6XNknnTdJ5 k3TeJJ03SedN0nmTdN4knTdJ503SeZN03iSdN0nnJ9wdChOW4h7ci5/iPizDz3B/mKZzTtM5pzl3 1Tl31Tl31emiKV00pYumdNGULprSRVO6aEoXTemiKV00pYumdNGUObNgziyYMwvmzII5s2DOLJgz C+bMgjmzYM4smDML5syCObMwYSTEE4oYRQl7MYZ9eA1yQmeepzPP05mn68wZnXmO81/W+S/r/Jd1 /ss6/2Wd/7JOCTmnhJxTQt4pIaeDT6vcGQpOCjknhZxOPl0nn15pTZXWpKNP09HTTg25yjc8D6FQ FaECCSSjtE6fdqLIOVHknChyThQ5nT+t86edLHJOFrmqo7z3aBzvtbd7fiLUWqeMnMlgmskgXfU+ 3xeDpoNDnDpyJoRpJoS0k0fOySPn5JFz8sg5eeScPHImh+kmh+kmh+kmh+lV6miVOlqljlZdhssx N8wwTcwwTcw2Tcw2RUxzns2aJDImiUzVz8b/ItPUql/hN+N/lWlq1fMem0KdKSNTxUvn3mzVaDTV xJExcWRMHBkTR8ZZuM5ZuM5ZeK2z8FoTSMZ5eK3zcF31GVHKmbjOuaDgXFBwLig4FxScC9pNKSuc CwrOBQXTyhzTypzqfw1x9TdwfpjnfFCovsjXcqr6YlyC2ZjjmpfCvpwd2p0dCs4OBWeHggknZcJJ OUMUnCEK1T/x/hvG/6pgwdSTcp4oOE8UnCcKzhMFU9A8U1DKFHSEc0XBJDTPJJRytig4WxScLQrO FgVni4KzRcGENMeENMeENMeENKd6p2t341Wo9dVqvanpblPT3aamFaamFaaleaalOaalFaaleaal lLN+1lk/66yfddbPOutnnfWzzvpZZ/2ss37WWT/rrJ911s8662ed9bPO+lln/ayzftZZP2vqypi6 MqaujKkrY+rKmLoypq6MqStj6sqYujKmroypK2Pqypi6MqaujKkrY+rKmLoyE99vTR/Ah0PdxNPx Tdf+lucX4EJ822vTPX4HMzATl4S8CS1jQsuY0DITF/nMEq//wntXhrUTH/b1IxgJ2UlRNNUEl5lk b5MOCXWTDo1SqS+ErtQXcR6+Es412Z2b+ldfXxXi1DwswJ8nvcW+/iGuj9ImvrSJL23iS5v40ia+ tIkvbeJLm/jSJr60iS9t4kub+NImvrSJL23iS5v40ia+tIkvbeJLm/jSJr60iS9t4kub+NImvrSJ L23iS5v40ia+9P/HiS/9VxPfodHN4SMV50efrfi36AsV/x5dVfEf0acqvhV9pOKC6MuJc6KvJGZE 5yW/FD6R/Eo4K/lUWJGsD59N7ggvmA2nJFW45Kvh1mRv2JDsi45M5p23doVidEx08xvPRY+GzdH6 sNnVP7r/r8Ge5urvdvV3u/rHK2aEot7a7S5Oc05lXwqnu8uZ7jI3uTY8nVyH+jfi5B/Caj2uNfls eD75XLjZ3a9151KyO/S4++nuvsTdk+7+M3d/LpqY3BSWJ5usyUk+uTl8K7klrElmfGpraNMVXzan Phr+aG1/9M6v6p2bvPtu716Q3PzGG979oHd/Wh9d7RNX+sS943/b8WSrXaibH617fzrxWZ18RpiR uDhKJh4xJz8X/iOxISxNbI9OTYzoyFOiycmTw8+Ta6O0Ln2yHfzanTY4jyaTm501W8JvdOlKV3/D jjI69YL9nTq5/0yatLOeZJ9d5b2+K/RXfDmaENZElahCNSZiElKoQRq1OACTw9PRgTg9tEVn4Afh V9G1+CGuw/X4EX6Mn+AG3IibabgmNEdPheaKRGirSGICKlGFakzEJKRQg1ociINwMA7BFByKqTgM h+MIvBXH4G04FsfheJyAt+NEvAP/El6u+Bw+jy/gi1iIq3ENFmExvo8f4Fr8ENfhevwIt4RtFbfi NtyOO3An7sLdYVvifeFXiQ/iY/hc+F3ixyGX+EnIifIvcSUWZ6+JsV9xIhZj/426K4GPosjer6p6 ujozPSGEEEK4b9RVwWVR8YjreqwCoqt4cKsoq4IHAiKnx6qICAgKKMghqKu4iBfIIXiAigfIDcFw JEAChAlHSICEqf9XNZ2YkEAOWN1/z+/rqa6u43X1q6/eq+6p6QAdyxc54QyRix5xVElxLJwrjoe3 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 0/dTmyhD3uNmWQ3X5TqWRnfzZ5lHvVMO6g9h7rVfPifF4pvZCRHnbVZ2M07yHi5s1PicttzwUUxs /8+goIcxrydPmJvJ6dN58WKZjwlv1sMal+Xa0c0h9a4qkqpHutyOqj6WbMjUFPkmfuyDkk6jW5z2 l5/LjpXbKef/XJbS2rcoiXelrtyKpxPs6v9v6Psz/c3Hvyzrz3qeiypZ8+uzsLy05bnFW67t+bLl 3Ym1n8Lkftt8PHFNy2XP/jn2tWkSZzcpJHOdcrBNNZKs2bTD9qCah5+S5My8HoODHyeiFlACWdwz /Q8wqK4WvO0qH1GVvgi9mBqYzhe0dDIwMTEHlU6WQO4AdL4wCk5C5c0d87zf6084eRVKnDjnYRd8 4NdqkV06RruF/INONL+1M77paThJY9vElAfyAS27DnlfrGf98b50X/fxFVfXZRakVainvdi2/X3r zrPvVv0VWsIdqaSpf97hZhiLdNnW3JRcr5Dbdz/e2z+/+XjD/XofJvMpXw/M4wiTy3A/e/NAWYx+ 7TZVli1h0Vkyyf8bamzeXWVR9bUsL2GPPRRzo81cp/Qk3ys5S86asn9zc/KqHryx658+r5AvXstf IinBaN6lZj9tpZgM1+57+i0CAZt+bpXqzXmnOlv4x2mB6618X5rKis2OTa1adCaB7Q3rhjbj7T+m RLc4tkS0TsnbIK/jcSZ/jvODrBf1an3ZkPKmiVEDGCIq2HPokOh+CbBxQgdARRlBfSoGpNITa+Eo CdcgwsTCI8fFEMxQypDE4MzgiNo1w+jXYSmgpvgKGh6qCdgt2LcwkZ2Rr6fAtfd9cchee05W3f87 AoNbZd5aTty+OIz7Xs82a+mLv9csP7l9Y6CidD5HZl028yIlt7c5W3JrlHa4XW753Mu/j73L7ODr upcFsa7zJ106c+5u34GH+7XO1rw5uc7oavvO08lHzC5KKO4vu2c9a7N08TzFjhtbtgiF9HyZcyjV a5aG2pyELn7r48KpFR67z69ttvLfkBRxz+DlS0vZx52fblk2/hRW7ElpSGZjmfZpFpOzfrVbx67/ TDdTf3rdu8VcMnkzax7Pmbl3NBJrPD6KzxFUtGCSaV/DdnSa0Y6nDseCbfeu7Lz3Is2894vStDln NpSHBFpdK3LZpPzNsIllPbCQWs3EyGjQ2D6AvTKUviJijHtB4y0DEXh8azAasjOzglcvg1IBNDI5 mQ15kIfVga5B8LgN+QyQZUUNlBEaWQyBaex7vxd7o/fEe1s5ZgVs6Nz/V8N/4laDFCQtPIZhBiEL tBo0GHwZMhmSGYoY8sEj82kMJQwKDCEMlQwFQF46UDwRyMpgqFyo1qCCs3otqSzITy9KLMioVEAr 3liaGBkU9j/bESnJYCUyS6rD99znqRvmTHZY9IrPOJzlnUWx258/G9fNfP/A4HFd19fXX5irv16N +fm1ZG4Dd97mW+v0mfNYCl4xX/sm3ql7oGWq+dLzdi2x4XyVJ29I3tj/17h73p3NCou2u73eWTf/ 7foDdsde7Xe5f9Fxz4+XIpJd3h8nM7qejzfm6a5f17PYuffEH7//yWsnHT5rqB5avCVh+0SW7yd5 y9Z5VKxjmtVwat1EEzO1Y89SeBb0MZ3Mla9dVxdmeuSycM0mJ6WpM89X+RWULV6nfVTpeVXx9dgF /Qvfh/sbMmkLlLn8muImkzRFuLq/5kmL8oPFs/3MWY75pK16sfTW0gjl2k6Di/IiC5uY5A2amKQR ccRm2MTEAxTioHsSRa+RUDoY7NAkuiDWQAI5JXIjZoEYgXbCZVgN+YFVrYWhgRGwojWyNDaNwkiI TP9V+O5vS+yN1Ys36HCV+rr+wZsfaGUWKIncn37Yi0P3/o6T0stuKrIe53mT1qby34npvPOHvScW KpRNe7Tn4eQ+IYdHalqLlk3sTuyR+HlGa2OAVPuP6omvgo86vNitG9t/zmVSSl5YgqoT9/E2pgbH d0ozq48aVQW8y+l48stM/Oux7klJsiGzrjwVFlp4be667//DrZjdX159F/E5zc4x3Ttu+769N1t1 n4TvODFxdVJhlv1yYY5D57XPlN6b2VVZUdC81m3Woc3NnX7uVtrNwYpGK/69Om5fUsZ0YN2qouDY HRnH614b2mbMUm/4vIVtw/PLOwR1mi7l7F9/v3DTi+akFdsYywxu8TkEb4pm/fx9i1kKa7CiaHe6 W55AVm6kcFDeFl4GANkzFYENCmVuZHN0cmVhbQ0KZW5kb2JqDQo1OSAwIG9iag0KWyAyMjYgMzI2 IDAgMCA1MDcgMCAwIDAgMzEyIDMxMiAwIDAgMjU4IDMwNiAyNjcgNDMwIDUwNyA1MDcgNTA3IDAg NTA3IDUwNyAwIDAgNTA3IDAgMjc2IDAgMCAwIDAgMCA4OTggNjA2IDU2MSA1MjkgNjMwIDQ4OCA0 NTkgNjM3IDAgMjY3IDAgNTQ3IDQyMyA4NzQgNjU5IDY3NiA1MzIgMCA1NjMgNDczIDQ5NSA2NTMg MCA5MDYgMCA1MjAgMCAwIDAgMCAwIDQ5OCAwIDQ5NCA1MzcgNDE4IDUzNyA1MDMgMzE2IDQ3NCA1 MzcgMjQ2IDAgNDgwIDI0NiA4MTMgNTM3IDUzOCA1MzcgNTM3IDM1NSAzOTkgMzQ3IDUzNyA0NzMg NzQ1IDQ1OSA0NzQgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAw IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAg MCA1MDddIA0KZW5kb2JqDQo2MCAwIG9iag0KPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCA5 MTUyMC9MZW5ndGgxIDE5MTg4MD4+DQpzdHJlYW0NCnic7JwJfFPF9vjP3Jul2ZqkS5o2bZo2bbqk TbpRKFtDaUtLqXQLtKwtm6AgFagIguCCC4L4RHEH9+WhkgbQIjxFRfQ9RX0+3DdUnitVfG5PoMn/ zD1JaRH9qT9/v/f5ff4deu535syZuTNnljs3iQIDgFi8yKCuvLF6TFPRIi0Ir6DSckVFWXmTxuoY BvDqCgBTfUXZuNEvxc+wARz4FkB5xZjyispPnv7mBAgvGgDEL8fUjW883MI2AXzxMrCb3xvT6C17 5tBhBsJlPoAx08Y3ugtORL2dBsDewBu0zlzQ1v7S1ue0AJlzsQFTZp63xOauHlQNULMEQBExp/3M BXd8XvYgQM4+AFX0mW2L28EMdrz/YSxvOHP+sjl3Xf/OpQD12L6Kurmz22Z9rAhUYv1TML94Lip0 65VJmL4O02lzFyw5X/5g7NcAwhAAR97Zsxedo3hBMQ9gZwyAevn8hTPbvE9VLQXY9AKAtXJB2/nt lqBpO5bvwvK2c9oWzN6wb90tAE9cAxBZ1L5w8ZJgHTyG7dnH89sXzW5/9ugSF8Ag7F/srcB9K9/c Nf2DrfdN1w//DuIjgIfdX6x4gfOZ1BsXHX+rZ73qiPIZtFWBABSwnAICwPapbz/+1rHLVEekmvoE 8Xuu0afCGpBDK4hY0gBujIF2pnRfBqJsrLAHcyPkN8kLsUorUXwZHhMgAgS9UhBlMlGQfQBC0AMP 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 lypcqnCpwqUKlypcqnCpwqUKlypcqnCpwqUKlypcqnCpwqUKl4pcKnKpyKUil4pcKnKpyKUilwpc KnCpwKUClwpcKnCpwKUClwpcKnCpwKUClwpcKnCpwKUClwpcKnCpwKUClwpcKnCpEL2XSxNcmqhV 4+KomQsVLoxzYZwDExyo3jeNU3ecuuPUHafuOHXHqTtB3QnqTlB3groT1J2g7gR1J6g7Qd0J6k5Q d4K6E9SdoO4EdSeoO0HdCepOUHeCuhPUnaDuBHUnqDtBnXHqjFNnnDrj1Bmnzjh1xqkzHr1LZ5jU GSZ14T3meSpxiyhureWP1Xu+HPf6+X1hUsVNqrhJFTep4iZV3KSKm1RxkypuktaTtJ6k9SStJ2k9 SetJWk/SepLWk7SepPUkrSdpPUnrSVpP0nqS1pO0nqT1JK0naT1J60laT0ZfpfUQrYesuGjF1f6V VwV5VZBXBfma/r+rgKWy/Hbd8A7cibtgB5+ofrPx72f7ED+G+DHEjyF+DPFjiB9D/BjixxA/hvgx xI8hfgzxY4gfQ/wY4scQP4b4McSPIX4M8WOIH0P8GOLHEAWLFCxSsEjBIgWLFCxSsEjBajXkVUNe NeRVQ1415FVDXjXkVUNeNeRVQ1415FVDXjXkVUNeNeRVQ/7/oRpyHMpxKMehHIdyHMpxKMehHIdy HMpxKMehHIdyHMpxKMehHIdyHMpxKMehHIdyHMpxKFeb8WW70l3RB17vXnfrOPaStC/S/r+mo5yP C3AhvoKvYh54LsaiGItiLIqxKMaiGItiLIqxKMZiQzUXFqAVV0K+ibEoxqI9bquI/k/NFFV8rN9W K31CT534j2rE3r3VHnuxPP6OfL3F81vtlZa6+14eHRZ9lnIlypVqu/KFuNZRiz3epO/fDPd9arM6 nSs+dWptd7vM83vDGIXHZHdZdpdld1l2l2V3WXaXKV+ifInyJcqXKF+ifInyJcqXKF+ifInyJcqX KF+ifInyJcqXKF+ifInyJcqXKF+ifInyJcqXKF+SfWXZV5Z9ZdlXln1l2VeWfWXZV+bMGGfGODPG mTHOjHFmjDNjnBnjzBhnxjgzxpkxzoxxZowzY5wZ48wYZ8Y4M8aZMc6McWaMM2O1u5UDlNr8+n1L JUrW7mvcSXPp1eiLtO2nbT//yvwrm6X7/XQHJxroW6Bvodb/lnLpbh1lmZ3SvXaw94URuhboWqBr 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 WlL9O13/335H/41/6+sNv2tf/T361JywPCWu1MJwQ+o6qJuUukmpm5S6SamblLpJ3YYlWIrbId7U nbgLd2MZluMe3Iv78D2swP14AA+CPqmVeBjfxyNoj45uuCY6quGbWIhrcR2+hetxAxZhMb6N7+BG fBc34WbcgltxG5ZgKW7HnbgLd2MZluMe3Iv7oqMa3x0dfegh0VGHptAQHWW3uFUV7K79FZOttb98 clziSt2sWTdr1s2adbPm2n8x4RCk0IBGNOFQHGZ3+xbMwuE4AkfinbCDtgPI2gFk7QCyOt+JOt+J dgJ5O4G8nUDeTiBvJ5C3E8jbCeTtBPJ2Ank7gbydQF6XnK9Lztcl50dfdac1DxfhYlyCr+FSXFb9 t+r4Bi7HFaHt3+yoV4fZuuls3XS2bjpbN52tm6Z005RumtJNU7ppSjdN6aYp3TSlm6Z005S5mzN3 c+ZuztzNmbs5czdn7ubM3Zy5mzN3c+ZuTuc9Uec90fytmL8V87di/lbM34r5WzF/K+ZvxfytmL8V 87di/lbM34pufYdufYdufUeUD8WogBG8glEUsRcllLEPFYyFH+nsz+rsz+rsz+rsz+rsz+rqi3T1 Rbr6Il19ka6+yJ4+Y0+fsafP2NNn7Okz9vQZe/qMPX3Gnj5jT5+xp8/Y02fs6TP29Bl7+ow9fcae PmNPn7Gnz9jTZ+zpM/b0GXv6jD19xp4+Y0+fsafP2NNn7Okz9vQZe/qMPX3Gnj5jT5+xp8/Y02fs 6TP29Bl7+ow9fWba56Ojp30Bf4m/wl/jeyFtEqVNorRJlDaJ0iZR2iRKm0RpkyhtEqVNorRJlDaJ 0iZR2iRKm0RpkyhtEqVNorRJlDaJ0iZR2iRKm0RpkyhtEqXdS3S4l9jgXmKDe4kN7iU2uJfY4F6i w71Eh3uJDvcSHe4lOqb9LEpN24I0tkYpU6zZFDvUFGtOuN8xyZoT7mlMs2dNs/NNs/Nr0+xLoZg4 H/PCPW+caomv1f66y2yT7SKTbbbJVv0rST9MXhEeTXaaYuujpmRXuDG5NTxpyjWbcilTLm/KpZLb w7BJt2bqbxcdV/s7l694fzSaYco1m3LNplyzKddsyjWbcs2mXLMp12zKNZtyzaZcsynXbCedt5PO 20nn7aTzdtJ5O+m8nXTeTjpvJ523k87bSeftpPN20vnp94TK9HtxH76HFbgfD+BBPBRmm5yzTc7Z 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 E/mOxWsSKLUUGuscaf6L0Bwb1ecT5bYhquhintsT7RXY/2RU5PQSpzq9xTnOleIB5/ds+1DK/N+h S/V78rdEQ931RPvf8Y4/QK73bK5d/3FpYu3Ry7VHrpNEAXcWQpwifiFOQHOfIX4suoqLxIniUvFb Un9H3PYz8UfxoDhXjBLPixtFkXiLo9l8xogPxWIxVpSgOZ4RFU5K/M1p5bQSi502TmexxDnPOZ/U C5yLxSqnh3OZWOdc4VwhNjhXOn3FRqefc4PY4gxwJojtzhN82jgT+bR1nubTzvmr87zT3pntzHM6 uD92uzg/cU9yT3b+wz3FPcU5xf25+wvnVPc/3bOc09xz3HOcX7i/crs6p7vnu+c7Z7nd3Iucs91L 3e7Or9yebk+nq3uFe4VzntvXvco5373avdq5wL3GvcG50L3ZHehc6t7mDnd6uiPdh5zr3Ifdcc5N 7gT3cec2d6r7384g9x/ue84I95/uYudJt8Qtdwrdle43zuvuOne9M8Pd4G5xZrrb3GpnjqulcN6X rpTOB1LJpPOhTMnGzgKZL/OdRbKZbOkslu3l0c5nsqM8ximVx8rjnS/lv8nOTpn8kfyRs0yeKLs4 y+VJ8j+cCnmKPNVZLU+TP3cq5enydGetPFOe6ayTZ8mznPXyfHmBE8mLZXdnk+wh+zjbZD95PU3f LG91Y3KwHOzmyKFyqBvKcXK8m5QvyhfdlHxFvuLmydfl624jOV3OcRvLtFziHiXL5DfusbJKavdE L+bluqd6+d5x7tnead5pbg+vvzfc7end773q3ui94b3lPun9y5vnPust9Ja7z3krPe1OjwWxwF0Q C2OhuzCWF2vsFseKY5+6i2Ofx75yS2PlsXK3LLYitsItj62MrXKXxb6JrXdXxDbENriVsc2xLe6a 2LbYNnd9rDpW7UaxnX7M3eArP9et9vP8PCn9xn5T6fkt/DYy7rf3fyJT/r/7/y6P9k/2fyk7+Bf4 l8iT/Mv9u+Wp/r3+n+WV/kj/AdnXf9h/WF7tj/HHyj/6j/mPyWv98f5EeZ0/yZ8k/+RP8afIm/3n /OfkLX6h/w/Z33/Nf1MO8Wf578h7/ff99+UIf64/X470i/1Fcoy/xC+Rj/pL/aVynP+F/6Uc71f4 q+XjfuTvkE8poVz5V6VUO/mC6qROku+rU9RpcpE6XZ0uP1X/qX4pl6pz1a/ll6qb6iaXqYvVxXK5 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 vFIIpVdLfS6/fW7yd6UZlZZ/UNq+rthxrxbKWq+WZH9X0rxaPP2eXy+f4a/5kT+YHxFwivJnYcr1 ZYllV+dnsfz6BBb3aSwDYSiMotHPNJgDC2n8swY2wBYaAe2DI4RfFK83/9/W+f+puvI/U792FuT5 HIlDYpQ77oHi7liAcl0SHj246yxCZKZxtKRs7z4jcZQYTe0xwn3G5iQaeUmxQtyg9k1xi8Yrtyma CMqW96n9QDzinPmE2k9FHLXjpfsOJCkN95mN0kdtzW8RsiWNv2VQhvCvMWmMLcOk+4S6xDIJtZNK 97lnETI5tSNlamqnkTRyk+lkRmpnkpmpnYXfWJRVZqV2NpmN2tlldmrnkO7zysbL8dSeICdQe6Kc SO1J6m1+nnA5UKq8mdB9aqtJ+poR7ju8zDLm26DMsmZDajcyW1C7pfmx+yx3sxO1PzH7ULuv2Zfa n5kb3Odvmxup/Z2fIrNf0ihS+jMEPgQRaBUgphdoHZwLIjgvSKPe4PzgRmp/F9xM7S3EVAWmJJ6h iE3G8wiPonKIDEn9/HfWbBkJjbxfB//GQQRzEMEcRLz0K1bBHEQwBxHMQQRzEMEcRDAHEcxBBHMQ wRxEMAcRzEEEc5DnVyiZiQhmIoKZiGAmIpiJCGYigpmIYCYimIkIZiKCmYhgJiKYiQhmIoKZiGAm IpiJCGYigpmIYCYimIkIZiKCmYhgJiKYiQhmIoKZiGAmIpiJCGYigpmIYCYimIkIZiKCmYhgJiKY iQhmIoKZiGAmIpiJCGYigpmIYCYimIkIZiKCmYhgJiKYiQhmIoKZiGAmIpiJCGYigpmIYCYimIkI ZiKCmYhgJiKYiQhmIoKZiGAmIpiJCGYigpmIYCYimIkIZiKCmYhgJiKYiQhmIoKZiGAmIpiJCGYi vz6j5MUTS5K3J5mIt0LyD6N6J2/mC2T5rOxnD4JCyym9k9eiTdWlENF2VMBnZkUlI0yIauizsvqE IXrnk8KY8m5U1ahsL22JnJayZyQvKRWGytAI2kMbCqIxEEv/3SWmolGpXzqZkahBn6JLKxfr/yTP R2/X9z38olz9yetrTemdJEtUbyMsqrd8PEVJISk4bITPCxfun2Bv0fuNr55+Kyr44kqFQdfUNjpr VGafqmHYCdOUbNO2c7sWzZrHpsrUOHOq6AIF8qV6p0Xjdm3at2kam6pkm3Ztc0SnjIp8fnDiV/e0 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 T35NRtaP2XxO7VFFgNOOLuwwGwCTIxchAzIHuYOwIF8Qbutk3gVEAImBMKAgEJ5mudLaHWjf3EBB udIR+/4yvRKC8DhXXwe8W5DYN3gDR9GB2BynIgMTnmUkCq+gUBkzfZm91CwTR1n9lkHdWTBmxeLx lablDxvY3NlRUNBDyfz9aS4tF/VIUNvrsyGDUgyzXfjf6ptPohqNj4/bLyqnGq/PhCmrFLY7NxYH C59s9FDPYr3O5yBoN7n8Vre1U6xD16D70+KeB26nw/Q4b5ug6bCTKvsn+3BkdANJO40+FGma+FLm dL1AvanZ5TYx0czFiYbK29Q5TGpBcotAeOycSMTZ1W7Oxiq9KTX0BLXa8adhfX9iuijTwyJK9W1F b+P+YSaO+KqgiZOnvDtmF6Y7VWZrDrm8Dmz7oJld1corf4dbbezi+i1BFyaHsbgYujMnDtda5EbR iwJR9CJf1ogRFkXPTmti/p+H6LcZ6asCg2k7RHPsAMGdkcj25S0QHe2ef3ggsF20VKsGA+C0RAtH Kqmc/FMgVqinp1mQpo/wMsehlvPUE6UdRXDfMGszRPT0n3FebQkdOljgQKcpxOnbpRCIOYWTJJvN sV6yOigcbui8ljmW35kmYlz7xgYhKXIvtMwjGXzJmrRq5tECbzdn84uf0wgDk8sChYT/yaijnz0S XR/Tv7dADiJ4TNqrWfVy8HBdzW3hCd8H7VfIaN/08ZwVbtnl57CmsLQ0+umscwEpIAqxwlinfbWg vJ9R2pT60NPM8nLdaq5UQa/PYbxhQlF438wkFxUqmHfy13NO7H4BfgZSsvcFR0bPr1GkUDCWjW6J wqGfoVll6/JqdWxCpFtZ5ZUn0BgLUurSi46xZbWParYddWbNQ3YOJLdict20az6lKLgZUoTcvUY5 SHQE/QufTQcsDQplbmRzdHJlYW0NCmVuZG9iag0KNjEgMCBvYmoNClsgMjUwXSANCmVuZG9iag0K NjIgMCBvYmoNCjw8L1R5cGUvWFJlZi9TaXplIDYyL1dbIDEgNCAyXSAvUm9vdCAxIDAgUi9JbmZv IDIwIDAgUi9JRFs8NDkzOEQ2MTJBMkU3RDc0NTg1MkQ2NUIyMzRDQ0Q1MDU+PDQ5MzhENjEyQTJF N0Q3NDU4NTJENjVCMjM0Q0NENTA1Pl0gL0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMTk1Pj4N CnN0cmVhbQ0KeJw10LlqAnEQx/H/7sZjjWfUeMS7UywtAoKFFpJnSFrTeDyAYKtEW2sh72EpeQc7 m1T2trr7++oU82GYgWHGGC+uV8vLKWN8FrAXthGhXxH+EO47/IvIUXR+xGfJx1qdfOzCRYya4rsn xlsxGYppV8xaYvnFzqKpQg0qcO/VvclV/1FZYIMDTxCAIIQgDC5E4BkaEIUYxCEBSUjBC6QhA1l4 hRzkoQBFeIMSlL3D1gN9YqOHOIez+Nv5BNpzY277ohttDQplbmRzdHJlYW0NCmVuZG9iag0KeHJl Zg0KMCA2Mw0KMDAwMDAwMDAyMSA2NTUzNSBmDQowMDAwMDAwMDE3IDAwMDAwIG4NCjAwMDAwMDAx MjUgMDAwMDAgbg0KMDAwMDAwMDE4OCAwMDAwMCBuDQowMDAwMDAwNTEyIDAwMDAwIG4NCjAwMDAw MDE5NTMgMDAwMDAgbg0KMDAwMDAwMjEyMSAwMDAwMCBuDQowMDAwMDAyMzYwIDAwMDAwIG4NCjAw MDAwMDI1MzMgMDAwMDAgbg0KMDAwMDAwMjc3NyAwMDAwMCBuDQowMDAwMDEzNDQ5IDAwMDAwIG4N CjAwMDAwMjMzMjQgMDAwMDAgbg0KMDAwMDEwMDMyMCAwMDAwMCBuDQowMDAwMTM3NzE4IDAwMDAw IG4NCjAwMDAxNTY5NjkgMDAwMDAgbg0KMDAwMDE1NzI0NiAwMDAwMCBuDQowMDAwMTU4NjEyIDAw MDAwIG4NCjAwMDAxNTg3OTEgMDAwMDAgbg0KMDAwMDE1OTAzNSAwMDAwMCBuDQowMDAwMTU5Mjc0 IDAwMDAwIG4NCjAwMDAxNjU0NjggMDAwMDAgbg0KMDAwMDAwMDAyMiA2NTUzNSBmDQowMDAwMDAw MDIzIDY1NTM1IGYNCjAwMDAwMDAwMjQgNjU1MzUgZg0KMDAwMDAwMDAyNSA2NTUzNSBmDQowMDAw MDAwMDI2IDY1NTM1IGYNCjAwMDAwMDAwMjcgNjU1MzUgZg0KMDAwMDAwMDAyOCA2NTUzNSBmDQow MDAwMDAwMDI5IDY1NTM1IGYNCjAwMDAwMDAwMzAgNjU1MzUgZg0KMDAwMDAwMDAzMSA2NTUzNSBm DQowMDAwMDAwMDMyIDY1NTM1IGYNCjAwMDAwMDAwMzMgNjU1MzUgZg0KMDAwMDAwMDAzNCA2NTUz NSBmDQowMDAwMDAwMDM1IDY1NTM1IGYNCjAwMDAwMDAwMzYgNjU1MzUgZg0KMDAwMDAwMDAzNyA2 NTUzNSBmDQowMDAwMDAwMDM4IDY1NTM1IGYNCjAwMDAwMDAwMzkgNjU1MzUgZg0KMDAwMDAwMDA0 MCA2NTUzNSBmDQowMDAwMDAwMDQxIDY1NTM1IGYNCjAwMDAwMDAwNDIgNjU1MzUgZg0KMDAwMDAw MDA0MyA2NTUzNSBmDQowMDAwMDAwMDQ0IDY1NTM1IGYNCjAwMDAwMDAwNDUgNjU1MzUgZg0KMDAw MDAwMDA0NiA2NTUzNSBmDQowMDAwMDAwMDQ3IDY1NTM1IGYNCjAwMDAwMDAwNDggNjU1MzUgZg0K MDAwMDAwMDA0OSA2NTUzNSBmDQowMDAwMDAwMDUwIDY1NTM1IGYNCjAwMDAwMDAwNTEgNjU1MzUg Zg0KMDAwMDAwMDA1MiA2NTUzNSBmDQowMDAwMDAwMDUzIDY1NTM1IGYNCjAwMDAwMDAwNTQgNjU1 MzUgZg0KMDAwMDAwMDA1NSA2NTUzNSBmDQowMDAwMDAwMDU2IDY1NTM1IGYNCjAwMDAwMDAwMDAg NjU1MzUgZg0KMDAwMDE2NjQ2NyAwMDAwMCBuDQowMDAwMTY2Njk4IDAwMDAwIG4NCjAwMDAyNDcw MTkgMDAwMDAgbg0KMDAwMDI0NzQ1NCAwMDAwMCBuDQowMDAwMzM5MDY2IDAwMDAwIG4NCjAwMDAz MzkwOTMgMDAwMDAgbg0KdHJhaWxlcg0KPDwvU2l6ZSA2My9Sb290IDEgMCBSL0luZm8gMjAgMCBS L0lEWzw0OTM4RDYxMkEyRTdENzQ1ODUyRDY1QjIzNENDRDUwNT48NDkzOEQ2MTJBMkU3RDc0NTg1 MkQ2NUIyMzRDQ0Q1MDU+XSA+Pg0Kc3RhcnR4cmVmDQozMzk0ODkNCiUlRU9GDQp4cmVmDQowIDAN CnRyYWlsZXINCjw8L1NpemUgNjMvUm9vdCAxIDAgUi9JbmZvIDIwIDAgUi9JRFs8NDkzOEQ2MTJB MkU3RDc0NTg1MkQ2NUIyMzRDQ0Q1MDU+PDQ5MzhENjEyQTJFN0Q3NDU4NTJENjVCMjM0Q0NENTA1 Pl0gL1ByZXYgMzM5NDg5L1hSZWZTdG0gMzM5MDkzPj4NCnN0YXJ0eHJlZg0KMzQwOTA3DQolJUVP Rg== ------=_Part_1957777_1336190691.1409812315449-- From felipemonteiro.carvalho@gmail.com Thu Sep 4 05:14:53 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 8702D7F54 for ; Thu, 4 Sep 2014 05:14:53 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 589B48F8040 for ; Thu, 4 Sep 2014 03:14:50 -0700 (PDT) X-ASG-Debug-ID: 1409825688-04bdf010a1743b40001-NocioJ Received: from mail-pd0-f169.google.com (mail-pd0-f169.google.com [209.85.192.169]) by cuda.sgi.com with ESMTP id sJGd8rQm1PKHWE5u (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Thu, 04 Sep 2014 03:14:49 -0700 (PDT) X-Barracuda-Envelope-From: felipemonteiro.carvalho@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.192.169 Received: by mail-pd0-f169.google.com with SMTP id y10so3879071pdj.28 for ; Thu, 04 Sep 2014 03:14:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=YOF/0RDY68DMPG1mNbIDgRDfaZOXNCvwUI26sLbUuCg=; b=iCaqoD2dX/6z8ffvKBqQRaJJS4QOVP92kc/toxYXH3dMWbX7i1+WJY8Py8V2lWoLjA W1Uj9MPXrLOy4ufiWXb5yOqhaV8v1D0lEgttLeR7cTTVKVMb01rB7buBWIaZxL+30atX iLNlvCSmm2VFMGTb/ad/+2YxJqk6jGV/fcbEuGFgGyAQBPT8N7V8mBMHXpmmFJf0fShV elLeyBjTsHpIqL1M5VqG6EZv/uZiV/iORB7XZzMyaHlsEE+SDyYC2JKpaY95Q2cQOtzc BEQdYyOAJJsMDt+RPWYku/X2hGU313+Mllyclhk8v5/XUN8rop/EDi5OAjtAj+BdeFfK 8Y6A== X-Barracuda-BBL-IP: nil MIME-Version: 1.0 X-Received: by 10.66.197.132 with SMTP id iu4mr6926541pac.132.1409825679561; Thu, 04 Sep 2014 03:14:39 -0700 (PDT) Received: by 10.66.154.162 with HTTP; Thu, 4 Sep 2014 03:14:39 -0700 (PDT) In-Reply-To: References: Date: Thu, 4 Sep 2014 12:14:39 +0200 Message-ID: Subject: Re: Ghost items in the end of a dir listing From: Felipe Monteiro de Carvalho X-ASG-Orig-Subj: Re: Ghost items in the end of a dir listing To: xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-pd0-f169.google.com[209.85.192.169] X-Barracuda-Start-Time: 1409825689 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9163 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature Hello, No ideas about this? =( Any kind of tip would be really appreciated =) thanks, Felipe Monteiro de Carvalho On Wed, Aug 27, 2014 at 12:20 PM, Felipe Monteiro de Carvalho wrote: > Hello, > > I am writing a program that reads XFS partitions and I am having > trouble with some dir listings. In some directories in the block that > starts with XD2B there is first the list of all directory items, which > I read without problems, and then there is a free item, for example: > > xfs_dir2_data_unused > freetag -> XFS_DIR2_DATA_FREE_TAG */ > length -> 9A0 > tag -> zero > > But after this free item there is still room in the block, so my > program will try to read the next item. I cannot stop the reading > because it is possible to have valid items, then a free item and then > more valid items. > > The next item start might be something like: > > 00 00 00 2E 00 00 00 02 16 > > So it is not a free item, as it doesn't start with FF = XFS_DIR2_DATA_FREE_TAG > But it isn't valid either, as its name is a bunch of trash =( > > So my questions are: > 1> What are those ghost items in the end of the block? > 2> Which criteria should be utilized to differentiate them from valid > items? I tried some guesses but nothing really works so far... > > Here are screenshots of the actual data involved, here showing the > item with XFS_DIR2_DATA_FREE_TAG: > > http://magnifier.sourceforge.net/temp/xfs/xfs_dir_listing_XD2B_FREE_item.png > > And here showing the area in the end of the block with wierd items: > > http://magnifier.sourceforge.net/temp/xfs/xfs_dir_listing_XD2B_after_FREE.png > > thanks for any tips =) > -- > Felipe Monteiro de Carvalho -- Felipe Monteiro de Carvalho From bfoster@redhat.com Thu Sep 4 11:38:35 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 304B67F37 for ; Thu, 4 Sep 2014 11:38:35 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1090B304059 for ; Thu, 4 Sep 2014 09:38:31 -0700 (PDT) X-ASG-Debug-ID: 1409848710-04cbb05488a41f90001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 0xlNVTymWtqfDNyW (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 04 Sep 2014 09:38:30 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s84GcUS5018753 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Thu, 4 Sep 2014 12:38:30 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s84GcTFO032524 for ; Thu, 4 Sep 2014 12:38:29 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 705491256F8; Thu, 4 Sep 2014 12:38:28 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH] xfsrestore: use utimensat() to provide atime/mtime with ns resolution Date: Thu, 4 Sep 2014 12:38:28 -0400 X-ASG-Orig-Subj: [PATCH] xfsrestore: use utimensat() to provide atime/mtime with ns resolution Message-Id: <1409848708-42666-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1409848710 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xfsdump encodes and stores the full atime and mtime for each file with nanosecond resolution. xfsrestore uses utime() to set the times of each file that is restored. The latter supports resolution of 1 second, thus sub-second timestamp data is lost on restore. Add the associated configure checks for and use utimensat() when available to restore timestamps with nanosecond resolution. Create a new helper to facilitate conditional support for utimensat(). Signed-off-by: Brian Foster --- I'm not totally sure on the configure bits here... it's mostly copied from xfsprogs and tweaked appropriately. It seems to work, at least. ;) Brian configure.ac | 2 ++ include/builddefs.in | 1 + m4/Makefile | 1 + m4/package_libcdev.m4 | 16 ++++++++++++++++ restore/Makefile | 4 ++++ restore/content.c | 38 ++++++++++++++++++++++++++++++-------- 6 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 m4/package_libcdev.m4 diff --git a/configure.ac b/configure.ac index 59f9564..28e604e 100644 --- a/configure.ac +++ b/configure.ac @@ -82,6 +82,8 @@ AC_PACKAGE_NEED_ATTRIBUTES_H AC_PACKAGE_NEED_ATTRIBUTES_MACROS AC_PACKAGE_NEED_ATTRGET_LIBATTR +AC_HAVE_UTIMENSAT + AC_MANUAL_FORMAT AC_CONFIG_FILES([include/builddefs]) diff --git a/include/builddefs.in b/include/builddefs.in index 269c928..bdf0ede 100644 --- a/include/builddefs.in +++ b/include/builddefs.in @@ -69,6 +69,7 @@ ENABLE_SHARED = @enable_shared@ ENABLE_GETTEXT = @enable_gettext@ HAVE_ZIPPED_MANPAGES = @have_zipped_manpages@ +HAVE_UTIMENSAT = @have_utimensat@ GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall # -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-decl diff --git a/m4/Makefile b/m4/Makefile index 9a35056..ae452f7 100644 --- a/m4/Makefile +++ b/m4/Makefile @@ -16,6 +16,7 @@ LSRCFILES = \ manual_format.m4 \ package_attrdev.m4 \ package_globals.m4 \ + package_libcdev.m4 \ package_ncurses.m4 \ package_pthread.m4 \ package_utilies.m4 \ diff --git a/m4/package_libcdev.m4 b/m4/package_libcdev.m4 new file mode 100644 index 0000000..6fcbdba --- /dev/null +++ b/m4/package_libcdev.m4 @@ -0,0 +1,16 @@ +# +# Check if we have a utimensat libc call +# +AC_DEFUN([AC_HAVE_UTIMENSAT], + [ AC_MSG_CHECKING([for utimensat]) + AC_TRY_COMPILE([ +#define _ATFILE_SOURCE +#include +#include + ], [ + utimensat(AT_FDCWD, 0, 0, AT_SYMLINK_NOFOLLOW); + ], have_utimensat=yes + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + AC_SUBST(have_utimensat) + ]) diff --git a/restore/Makefile b/restore/Makefile index c6f3f25..c5cf925 100644 --- a/restore/Makefile +++ b/restore/Makefile @@ -102,6 +102,10 @@ LTDEPENDENCIES = $(LIBRMT) LCFLAGS = -DRESTORE +ifeq ($(HAVE_UTIMENSAT),yes) +LCFLAGS += -DHAVE_UTIMENSAT +endif + default: depend $(LTCOMMAND) include $(BUILDRULES) diff --git a/restore/content.c b/restore/content.c index cfcf94d..65dc2f5 100644 --- a/restore/content.c +++ b/restore/content.c @@ -7418,6 +7418,34 @@ done: return 0; } +/* + * Set the access and modification times for a file. + */ +static int +restore_file_amtime( + const char *path, + struct bstat *bstatp) +{ + int rval; + +#ifdef HAVE_UTIMENSAT + struct timespec times[2]; + + times[0].tv_sec = bstatp->bs_atime.tv_sec; + times[0].tv_nsec = bstatp->bs_atime.tv_nsec; + times[1].tv_sec = bstatp->bs_mtime.tv_sec; + times[1].tv_nsec = bstatp->bs_mtime.tv_nsec; + rval = utimensat(AT_FDCWD, path, times, 0); +#else + struct utimbuf utimbuf; + + utimbuf.actime = ( time32_t )bstatp->bs_atime.tv_sec; + utimbuf.modtime = ( time32_t )bstatp->bs_mtime.tv_sec; + rval = utime(path, &utimbuf); +#endif + return rval; +} + /* called to begin a regular file. if no path given, or if just toc, * don't actually write, just read. also get into that situation if * cannot prepare destination. fd == -1 signifies no write. *statp @@ -7671,7 +7699,6 @@ restore_complete_reg(stream_context_t *strcxtp) bstat_t *bstatp = &strcxtp->sc_bstat; char *path = strcxtp->sc_path; intgen_t fd = strcxtp->sc_fd; - struct utimbuf utimbuf; intgen_t rval; // only applies to regular files @@ -7688,9 +7715,7 @@ restore_complete_reg(stream_context_t *strcxtp) /* set the access and modification times */ - utimbuf.actime = ( time32_t )bstatp->bs_atime.tv_sec; - utimbuf.modtime = ( time32_t )bstatp->bs_mtime.tv_sec; - rval = utime( path, &utimbuf ); + rval = restore_file_amtime(path, bstatp); if ( rval ) { mlog( MLOG_VERBOSE | MLOG_WARNING, _( "unable to set access and modification " @@ -7770,7 +7795,6 @@ static bool_t restore_spec( filehdr_t *fhdrp, rv_t *rvp, char *path ) { bstat_t *bstatp = &fhdrp->fh_stat; - struct utimbuf utimbuf; char *printstr; intgen_t rval; @@ -7913,9 +7937,7 @@ restore_spec( filehdr_t *fhdrp, rv_t *rvp, char *path ) /* set the access and modification times */ - utimbuf.actime = ( time32_t )bstatp->bs_atime.tv_sec; - utimbuf.modtime = ( time32_t )bstatp->bs_mtime.tv_sec; - rval = utime( path, &utimbuf ); + rval = restore_file_amtime(path, bstatp); if ( rval ) { mlog( MLOG_VERBOSE | MLOG_WARNING, _( "unable to set access and modification " -- 1.8.3.1 From rh2@mexicocalendario2014.info Thu Sep 4 12:35:28 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 074047F37 for ; Thu, 4 Sep 2014 12:35:28 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id EA101304062 for ; Thu, 4 Sep 2014 10:35:24 -0700 (PDT) X-ASG-Debug-ID: 1409852119-04cb6c54fe7bdb10001-NocioJ Received: from mail2.mexicocalendario2014.info (mail2.mexicocalendario2014.info [81.7.3.198]) by cuda.sgi.com with ESMTP id hxQEjKaTuIGWy2rG for ; Thu, 04 Sep 2014 10:35:19 -0700 (PDT) X-Barracuda-Envelope-From: rh2@mexicocalendario2014.info X-Barracuda-Apparent-Source-IP: 81.7.3.198 Received: from 81-7-3-140 (81.7.3.140) by mail2.mexicocalendario2014.info id h12hde0our0t for ; Thu, 4 Sep 2014 12:35:14 -0500 (envelope-from ) mod: fd25f39a-7480-48bc-843f-89413644a548 Message-ID: From: "Recursos Humanos" To: Subject: Integracion Equipos de Trabajo Date: Thu, 4 Sep 2014 12:35:14 -0500 X-ASG-Orig-Subj: Integracion Equipos de Trabajo MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=SPLITOR00A_001_266525305D" X-Barracuda-Connect: mail2.mexicocalendario2014.info[81.7.3.198] X-Barracuda-Start-Time: 1409852119 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9173 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message This is a multi-part message in MIME format. ------=SPLITOR00A_001_266525305D Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable =20 Liderazgo e Integraci=C3=B3n de Equipos de Trabajo M=C3=A9xico, D.F. 26 de septiembre 2014 Para obtener el contenido completo de este programa responda este correo = con la palabra ET + Nombre + Tel=C3=A9fono y se lo enviaremos a la = brevedad=2E TEMARIO: 1.- Las claves para crear un excelente equipo de trabajo=2E 2.- C=C3=B3mo definir los roles de un equipo efectivo (HOT GROUPS) 3.-C=C3=B3mo crear y desarrollar un plan efectivo de trabajo=2E 4.- Habilidades para lograr la comunicaci=C3=B3n eficaz entre los = l=C3=ADderes y miembros del equipo=2E 5.- Herramientas para manejar exitosamente la soluci=C3=B3n de=20 problemas=2E 6.- Evaluaci=C3=B3n del desempe=C3=B1o y el progreso del equipo=2E Mayores informes e inscripci=C3=B3n, - Solic=C3=ADtala ya L=C3=ADnea directa D.F.: 01 800 212 0660 Para YA no recibir estos boletines a: xfs@oss.sgi.com simplemente = env=C3=ADe un correo con asunto (CMF3) ------=SPLITOR00A_001_266525305D Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable

 

Liderazgo e = Integraci=C3=B3n=20 de Equipos de Trabajo
M=C3=A9xico, D.F. 26 = de septiembre=20 2014

Para obtener el contenido completo de = este=20 programa responda este correo con la palabra=20 ET + Nombre +=20 Tel=C3=A9fono y se lo enviaremos a la=20 = brevedad.

TEMARIO:
1.- Las claves para crear un = excelente=20 equipo de trabajo.
2.- C=C3=B3mo definir los roles de = un equipo=20 efectivo (HOT GROUPS)
3.-C=C3=B3mo crear y = desarrollar un plan=20 efectivo de trabajo.
4.- Habilidades para lograr la=20 comunicaci=C3=B3n eficaz entre los l=C3=ADderes y = miembros del=20 equipo.
5.- Herramientas para manejar exitosamente = la=20 soluci=C3=B3n de
problemas.
6.- Evaluaci=C3=B3n = del desempe=C3=B1o y=20 el progreso del equipo.

Mayores informes e = inscripci=C3=B3n,=20 - Solic=C3=ADtala ya
L=C3=ADnea directa D.F.: = 01 800 212=20 0660

Para YA no recibir estos boletines = a: xfs@oss.sgi.com=20  simplemente env=C3=ADe un correo con asunto=20 = (CMF3)

 

------=SPLITOR00A_001_266525305D-- From sandeen@sandeen.net Thu Sep 4 14:47:03 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 4AFC87F37 for ; Thu, 4 Sep 2014 14:47:03 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 33D1F304070 for ; Thu, 4 Sep 2014 12:47:02 -0700 (PDT) X-ASG-Debug-ID: 1409860020-04cbb05485a51810001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id AS83GgTBHfO7MCNE for ; Thu, 04 Sep 2014 12:47:00 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 69B46653AF00; Thu, 4 Sep 2014 14:47:00 -0500 (CDT) Message-ID: <5408C1B4.1010001@sandeen.net> Date: Thu, 04 Sep 2014 14:47:00 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Brian Foster , xfs@oss.sgi.com Subject: Re: [PATCH] xfsrestore: use utimensat() to provide atime/mtime with ns resolution References: <1409848708-42666-1-git-send-email-bfoster@redhat.com> X-ASG-Orig-Subj: Re: [PATCH] xfsrestore: use utimensat() to provide atime/mtime with ns resolution In-Reply-To: <1409848708-42666-1-git-send-email-bfoster@redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1409860020 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9178 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/4/14, 11:38 AM, Brian Foster wrote: > xfsdump encodes and stores the full atime and mtime for each file with > nanosecond resolution. xfsrestore uses utime() to set the times of each > file that is restored. The latter supports resolution of 1 second, thus > sub-second timestamp data is lost on restore. > > Add the associated configure checks for and use utimensat() when > available to restore timestamps with nanosecond resolution. Create a new > helper to facilitate conditional support for utimensat(). > > Signed-off-by: Brian Foster > --- > > I'm not totally sure on the configure bits here... it's mostly copied > from xfsprogs and tweaked appropriately. It seems to work, at least. ;) > > Brian > > configure.ac | 2 ++ > include/builddefs.in | 1 + > m4/Makefile | 1 + > m4/package_libcdev.m4 | 16 ++++++++++++++++ > restore/Makefile | 4 ++++ > restore/content.c | 38 ++++++++++++++++++++++++++++++-------- > 6 files changed, 54 insertions(+), 8 deletions(-) > create mode 100644 m4/package_libcdev.m4 > > diff --git a/configure.ac b/configure.ac > index 59f9564..28e604e 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -82,6 +82,8 @@ AC_PACKAGE_NEED_ATTRIBUTES_H > AC_PACKAGE_NEED_ATTRIBUTES_MACROS > AC_PACKAGE_NEED_ATTRGET_LIBATTR > > +AC_HAVE_UTIMENSAT > + > AC_MANUAL_FORMAT > > AC_CONFIG_FILES([include/builddefs]) > diff --git a/include/builddefs.in b/include/builddefs.in > index 269c928..bdf0ede 100644 > --- a/include/builddefs.in > +++ b/include/builddefs.in > @@ -69,6 +69,7 @@ ENABLE_SHARED = @enable_shared@ > ENABLE_GETTEXT = @enable_gettext@ > > HAVE_ZIPPED_MANPAGES = @have_zipped_manpages@ > +HAVE_UTIMENSAT = @have_utimensat@ > > GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall > # -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-decl > diff --git a/m4/Makefile b/m4/Makefile > index 9a35056..ae452f7 100644 > --- a/m4/Makefile > +++ b/m4/Makefile > @@ -16,6 +16,7 @@ LSRCFILES = \ > manual_format.m4 \ > package_attrdev.m4 \ > package_globals.m4 \ > + package_libcdev.m4 \ > package_ncurses.m4 \ > package_pthread.m4 \ > package_utilies.m4 \ > diff --git a/m4/package_libcdev.m4 b/m4/package_libcdev.m4 > new file mode 100644 > index 0000000..6fcbdba > --- /dev/null > +++ b/m4/package_libcdev.m4 > @@ -0,0 +1,16 @@ > +# > +# Check if we have a utimensat libc call > +# > +AC_DEFUN([AC_HAVE_UTIMENSAT], > + [ AC_MSG_CHECKING([for utimensat]) > + AC_TRY_COMPILE([ (as discussed on IRC...) I think you need AC_TRY_LINK here; changing utimensat() to utimensatFOO() still passes. ;) -Eric From bfoster@redhat.com Thu Sep 4 16:35:23 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E62877F37 for ; Thu, 4 Sep 2014 16:35:22 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 835F5AC003 for ; Thu, 4 Sep 2014 14:35:19 -0700 (PDT) X-ASG-Debug-ID: 1409866515-04bdf0109a766a40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 9Aqr9nZo3erhH2eJ (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 04 Sep 2014 14:35:15 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s84LZEP2008001 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 4 Sep 2014 17:35:14 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s84LZD7h011318; Thu, 4 Sep 2014 17:35:13 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 2BC191256F8; Thu, 4 Sep 2014 17:35:12 -0400 (EDT) Date: Thu, 4 Sep 2014 17:35:12 -0400 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfsrestore: use utimensat() to provide atime/mtime with ns resolution Message-ID: <20140904213511.GA902@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfsrestore: use utimensat() to provide atime/mtime with ns resolution References: <1409848708-42666-1-git-send-email-bfoster@redhat.com> <5408C1B4.1010001@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5408C1B4.1010001@sandeen.net> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1409866515 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Sep 04, 2014 at 02:47:00PM -0500, Eric Sandeen wrote: > On 9/4/14, 11:38 AM, Brian Foster wrote: > >xfsdump encodes and stores the full atime and mtime for each file with > >nanosecond resolution. xfsrestore uses utime() to set the times of each > >file that is restored. The latter supports resolution of 1 second, thus > >sub-second timestamp data is lost on restore. > > > >Add the associated configure checks for and use utimensat() when > >available to restore timestamps with nanosecond resolution. Create a new > >helper to facilitate conditional support for utimensat(). > > > >Signed-off-by: Brian Foster > >--- > > > >I'm not totally sure on the configure bits here... it's mostly copied > >from xfsprogs and tweaked appropriately. It seems to work, at least. ;) > > > >Brian > > > > configure.ac | 2 ++ > > include/builddefs.in | 1 + > > m4/Makefile | 1 + > > m4/package_libcdev.m4 | 16 ++++++++++++++++ > > restore/Makefile | 4 ++++ > > restore/content.c | 38 ++++++++++++++++++++++++++++++-------- > > 6 files changed, 54 insertions(+), 8 deletions(-) > > create mode 100644 m4/package_libcdev.m4 > > > >diff --git a/configure.ac b/configure.ac > >index 59f9564..28e604e 100644 > >--- a/configure.ac > >+++ b/configure.ac > >@@ -82,6 +82,8 @@ AC_PACKAGE_NEED_ATTRIBUTES_H > > AC_PACKAGE_NEED_ATTRIBUTES_MACROS > > AC_PACKAGE_NEED_ATTRGET_LIBATTR > > > >+AC_HAVE_UTIMENSAT > >+ > > AC_MANUAL_FORMAT > > > > AC_CONFIG_FILES([include/builddefs]) > >diff --git a/include/builddefs.in b/include/builddefs.in > >index 269c928..bdf0ede 100644 > >--- a/include/builddefs.in > >+++ b/include/builddefs.in > >@@ -69,6 +69,7 @@ ENABLE_SHARED = @enable_shared@ > > ENABLE_GETTEXT = @enable_gettext@ > > > > HAVE_ZIPPED_MANPAGES = @have_zipped_manpages@ > >+HAVE_UTIMENSAT = @have_utimensat@ > > > > GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall > > # -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-decl > >diff --git a/m4/Makefile b/m4/Makefile > >index 9a35056..ae452f7 100644 > >--- a/m4/Makefile > >+++ b/m4/Makefile > >@@ -16,6 +16,7 @@ LSRCFILES = \ > > manual_format.m4 \ > > package_attrdev.m4 \ > > package_globals.m4 \ > >+ package_libcdev.m4 \ > > package_ncurses.m4 \ > > package_pthread.m4 \ > > package_utilies.m4 \ > >diff --git a/m4/package_libcdev.m4 b/m4/package_libcdev.m4 > >new file mode 100644 > >index 0000000..6fcbdba > >--- /dev/null > >+++ b/m4/package_libcdev.m4 > >@@ -0,0 +1,16 @@ > >+# > >+# Check if we have a utimensat libc call > >+# > >+AC_DEFUN([AC_HAVE_UTIMENSAT], > >+ [ AC_MSG_CHECKING([for utimensat]) > >+ AC_TRY_COMPILE([ > > (as discussed on IRC...) > > I think you need AC_TRY_LINK here; changing utimensat() to utimensatFOO() still > passes. ;) > Yeah... I tested that by breaking the function signature. I'm guessing this does a 'gcc -c,' which lets me compile pretty much any kind of call if no function declaration is found in a header. AC_TRY_LINK() does what we want. Thanks for catching that. Brian > -Eric From bfoster@redhat.com Thu Sep 4 16:42:23 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 2B5157F37 for ; Thu, 4 Sep 2014 16:42:23 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id E0E43304059 for ; Thu, 4 Sep 2014 14:42:22 -0700 (PDT) X-ASG-Debug-ID: 1409866941-04bdf010a1766ec0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id rq5gKN3Nl0utAWH7 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 04 Sep 2014 14:42:21 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s84LgLXD009509 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Thu, 4 Sep 2014 17:42:21 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s84LgL8J013261 for ; Thu, 4 Sep 2014 17:42:21 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 98E0F1256F8; Thu, 4 Sep 2014 17:42:19 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2] xfsrestore: use utimensat() to provide atime/mtime with ns resolution Date: Thu, 4 Sep 2014 17:42:19 -0400 X-ASG-Orig-Subj: [PATCH v2] xfsrestore: use utimensat() to provide atime/mtime with ns resolution Message-Id: <1409866939-1480-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1409866941 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xfsdump encodes and stores the full atime and mtime for each file with nanosecond resolution. xfsrestore uses utime() to set the times of each file that is restored. The latter supports resolution of 1 second, thus sub-second timestamp data is lost on restore. Add the associated configure checks for and use utimensat() when available to restore timestamps with nanosecond resolution. Create a new helper to facilitate conditional support for utimensat(). Signed-off-by: Brian Foster --- v2: - Use AC_TRY_LINK() instead of AC_TRY_COMPILE() to ensure utimensat() exists. v1: http://oss.sgi.com/archives/xfs/2014-09/msg00025.html configure.ac | 2 ++ include/builddefs.in | 1 + m4/Makefile | 1 + m4/package_libcdev.m4 | 16 ++++++++++++++++ restore/Makefile | 4 ++++ restore/content.c | 38 ++++++++++++++++++++++++++++++-------- 6 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 m4/package_libcdev.m4 diff --git a/configure.ac b/configure.ac index 59f9564..28e604e 100644 --- a/configure.ac +++ b/configure.ac @@ -82,6 +82,8 @@ AC_PACKAGE_NEED_ATTRIBUTES_H AC_PACKAGE_NEED_ATTRIBUTES_MACROS AC_PACKAGE_NEED_ATTRGET_LIBATTR +AC_HAVE_UTIMENSAT + AC_MANUAL_FORMAT AC_CONFIG_FILES([include/builddefs]) diff --git a/include/builddefs.in b/include/builddefs.in index 269c928..bdf0ede 100644 --- a/include/builddefs.in +++ b/include/builddefs.in @@ -69,6 +69,7 @@ ENABLE_SHARED = @enable_shared@ ENABLE_GETTEXT = @enable_gettext@ HAVE_ZIPPED_MANPAGES = @have_zipped_manpages@ +HAVE_UTIMENSAT = @have_utimensat@ GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall # -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-decl diff --git a/m4/Makefile b/m4/Makefile index 9a35056..ae452f7 100644 --- a/m4/Makefile +++ b/m4/Makefile @@ -16,6 +16,7 @@ LSRCFILES = \ manual_format.m4 \ package_attrdev.m4 \ package_globals.m4 \ + package_libcdev.m4 \ package_ncurses.m4 \ package_pthread.m4 \ package_utilies.m4 \ diff --git a/m4/package_libcdev.m4 b/m4/package_libcdev.m4 new file mode 100644 index 0000000..8301ca6 --- /dev/null +++ b/m4/package_libcdev.m4 @@ -0,0 +1,16 @@ +# +# Check if we have a utimensat libc call +# +AC_DEFUN([AC_HAVE_UTIMENSAT], + [ AC_MSG_CHECKING([for utimensat]) + AC_TRY_LINK([ +#define _ATFILE_SOURCE +#include +#include + ], [ + utimensat(AT_FDCWD, 0, 0, AT_SYMLINK_NOFOLLOW); + ], have_utimensat=yes + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + AC_SUBST(have_utimensat) + ]) diff --git a/restore/Makefile b/restore/Makefile index c6f3f25..c5cf925 100644 --- a/restore/Makefile +++ b/restore/Makefile @@ -102,6 +102,10 @@ LTDEPENDENCIES = $(LIBRMT) LCFLAGS = -DRESTORE +ifeq ($(HAVE_UTIMENSAT),yes) +LCFLAGS += -DHAVE_UTIMENSAT +endif + default: depend $(LTCOMMAND) include $(BUILDRULES) diff --git a/restore/content.c b/restore/content.c index cfcf94d..65dc2f5 100644 --- a/restore/content.c +++ b/restore/content.c @@ -7418,6 +7418,34 @@ done: return 0; } +/* + * Set the access and modification times for a file. + */ +static int +restore_file_amtime( + const char *path, + struct bstat *bstatp) +{ + int rval; + +#ifdef HAVE_UTIMENSAT + struct timespec times[2]; + + times[0].tv_sec = bstatp->bs_atime.tv_sec; + times[0].tv_nsec = bstatp->bs_atime.tv_nsec; + times[1].tv_sec = bstatp->bs_mtime.tv_sec; + times[1].tv_nsec = bstatp->bs_mtime.tv_nsec; + rval = utimensat(AT_FDCWD, path, times, 0); +#else + struct utimbuf utimbuf; + + utimbuf.actime = ( time32_t )bstatp->bs_atime.tv_sec; + utimbuf.modtime = ( time32_t )bstatp->bs_mtime.tv_sec; + rval = utime(path, &utimbuf); +#endif + return rval; +} + /* called to begin a regular file. if no path given, or if just toc, * don't actually write, just read. also get into that situation if * cannot prepare destination. fd == -1 signifies no write. *statp @@ -7671,7 +7699,6 @@ restore_complete_reg(stream_context_t *strcxtp) bstat_t *bstatp = &strcxtp->sc_bstat; char *path = strcxtp->sc_path; intgen_t fd = strcxtp->sc_fd; - struct utimbuf utimbuf; intgen_t rval; // only applies to regular files @@ -7688,9 +7715,7 @@ restore_complete_reg(stream_context_t *strcxtp) /* set the access and modification times */ - utimbuf.actime = ( time32_t )bstatp->bs_atime.tv_sec; - utimbuf.modtime = ( time32_t )bstatp->bs_mtime.tv_sec; - rval = utime( path, &utimbuf ); + rval = restore_file_amtime(path, bstatp); if ( rval ) { mlog( MLOG_VERBOSE | MLOG_WARNING, _( "unable to set access and modification " @@ -7770,7 +7795,6 @@ static bool_t restore_spec( filehdr_t *fhdrp, rv_t *rvp, char *path ) { bstat_t *bstatp = &fhdrp->fh_stat; - struct utimbuf utimbuf; char *printstr; intgen_t rval; @@ -7913,9 +7937,7 @@ restore_spec( filehdr_t *fhdrp, rv_t *rvp, char *path ) /* set the access and modification times */ - utimbuf.actime = ( time32_t )bstatp->bs_atime.tv_sec; - utimbuf.modtime = ( time32_t )bstatp->bs_mtime.tv_sec; - rval = utime( path, &utimbuf ); + rval = restore_file_amtime(path, bstatp); if ( rval ) { mlog( MLOG_VERBOSE | MLOG_WARNING, _( "unable to set access and modification " -- 1.8.3.1 From david@fromorbit.com Thu Sep 4 19:39:26 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 9F0967F37 for ; Thu, 4 Sep 2014 19:39:26 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6AC818F8049 for ; Thu, 4 Sep 2014 17:39:26 -0700 (PDT) X-ASG-Debug-ID: 1409877560-04bdf0109776e7f0001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id o5qq1Y2gP3PMqeGc for ; Thu, 04 Sep 2014 17:39:20 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AiV/AN0ECVR5LKYhPGdsb2JhbABZgw2BKoIshQeGFaIBBppBhWkBAwEBAYEIFwUBAQEBODaEAwEBBAE6HCMFCwgDGAklDwUlAwcaExSIJge9WAEXGIVkiVEHhEwBBI8pjUKZFisvgk8BAQE Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail06.adl6.internode.on.net with ESMTP; 05 Sep 2014 10:09:20 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XPhYc-0007hT-Mv; Fri, 05 Sep 2014 10:39:18 +1000 Date: Fri, 5 Sep 2014 10:39:18 +1000 From: Dave Chinner To: Felipe Monteiro de Carvalho Cc: xfs@oss.sgi.com Subject: Re: Ghost items in the end of a dir listing Message-ID: <20140905003918.GT20518@dastard> X-ASG-Orig-Subj: Re: Ghost items in the end of a dir listing References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1409877560 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9186 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 04, 2014 at 12:14:39PM +0200, Felipe Monteiro de Carvalho wrote: > Hello, > > No ideas about this? =( I know *exactly* what is going on. > Any kind of tip would be really appreciated =) TANSTAAFL. You are asking an open source community for help developing your closed source project. If you want our help, then it should be pretty obvious what you need to do.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Thu Sep 4 19:45:15 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BA0327F37 for ; Thu, 4 Sep 2014 19:45:15 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 617FFAC003 for ; Thu, 4 Sep 2014 17:45:12 -0700 (PDT) X-ASG-Debug-ID: 1409877910-04bdf010a176eb20001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id VDGRG3O3zj19nlhw for ; Thu, 04 Sep 2014 17:45:10 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AuIuAFoHCVR5LKYhPGdsb2JhbABZgw2BKoIshQeoFgaaQYVpAQMBAQGBCBcFAQEBATg2hAQBBTocIxAIAw4KCSUPBSUDBxoTiEG9WgEXGIVkiVEHhEwFnGuXPoFYKy+CTwEBAQ Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail06.adl6.internode.on.net with ESMTP; 05 Sep 2014 10:15:03 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XPhe9-0007iN-HC; Fri, 05 Sep 2014 10:45:01 +1000 Date: Fri, 5 Sep 2014 10:45:01 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfsrestore: use utimensat() to provide atime/mtime with ns resolution Message-ID: <20140905004501.GU20518@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfsrestore: use utimensat() to provide atime/mtime with ns resolution References: <1409848708-42666-1-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1409848708-42666-1-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1409877910 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9186 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 04, 2014 at 12:38:28PM -0400, Brian Foster wrote: > xfsdump encodes and stores the full atime and mtime for each file with > nanosecond resolution. xfsrestore uses utime() to set the times of each > file that is restored. The latter supports resolution of 1 second, thus > sub-second timestamp data is lost on restore. That doesn't seem like a big deal. What sort of problems does this actually cause? FYI, many linux filesystems only have second resolution timestamps and hence applications can't rely on sub-second timestamp resolution to actually mean anything useful.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From sandeen@sandeen.net Thu Sep 4 20:04:55 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id A41717F37 for ; Thu, 4 Sep 2014 20:04:55 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7F4B38F8040 for ; Thu, 4 Sep 2014 18:04:52 -0700 (PDT) X-ASG-Debug-ID: 1409879091-04cb6c54ff7d2990001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id fJwsNMReQI2QNni7 for ; Thu, 04 Sep 2014 18:04:51 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 371AE653AF00; Thu, 4 Sep 2014 20:04:51 -0500 (CDT) Message-ID: <54090C33.2060102@sandeen.net> Date: Thu, 04 Sep 2014 20:04:51 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Dave Chinner , Brian Foster CC: xfs@oss.sgi.com Subject: Re: [PATCH] xfsrestore: use utimensat() to provide atime/mtime with ns resolution References: <1409848708-42666-1-git-send-email-bfoster@redhat.com> <20140905004501.GU20518@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfsrestore: use utimensat() to provide atime/mtime with ns resolution In-Reply-To: <20140905004501.GU20518@dastard> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1409879091 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9186 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/4/14, 7:45 PM, Dave Chinner wrote: > On Thu, Sep 04, 2014 at 12:38:28PM -0400, Brian Foster wrote: >> xfsdump encodes and stores the full atime and mtime for each file with >> nanosecond resolution. xfsrestore uses utime() to set the times of each >> file that is restored. The latter supports resolution of 1 second, thus >> sub-second timestamp data is lost on restore. > > That doesn't seem like a big deal. What sort of problems does this > actually cause? > > FYI, many linux filesystems only have second resolution timestamps > and hence applications can't rely on sub-second timestamp resolution > to actually mean anything useful.... But why not restore the same resolution as is actually stored in the dump? Throwing it away seems odd, and restoring it looks easy enough. In any case, there was a user who noticed & complained. Seems like a very reasonable thing to fix, to me. -Eric From david@fromorbit.com Thu Sep 4 20:24:15 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 30C907F37 for ; Thu, 4 Sep 2014 20:24:15 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id AFDC2AC001 for ; Thu, 4 Sep 2014 18:24:11 -0700 (PDT) X-ASG-Debug-ID: 1409880248-04cb6c54fe7d31c0001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id htIZOf7L21BC1k27 for ; Thu, 04 Sep 2014 18:24:09 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AuQuAI0PCVR5LKYhPGdsb2JhbABZgw2BKoIshQeoFwaaQYVpAQMBAQGBCBcFAQEBATg2hAMBAQQBOhwjBQsIAxgJJQ8FJQMHGhOIOge9YAEXGIVkiVEHhEwFnGuXPoFYKy+CTwEBAQ Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail06.adl6.internode.on.net with ESMTP; 05 Sep 2014 10:54:07 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XPiFw-0007nZ-V6; Fri, 05 Sep 2014 11:24:04 +1000 Date: Fri, 5 Sep 2014 11:24:04 +1000 From: Dave Chinner To: Eric Sandeen Cc: Brian Foster , xfs@oss.sgi.com Subject: Re: [PATCH] xfsrestore: use utimensat() to provide atime/mtime with ns resolution Message-ID: <20140905012404.GV20518@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfsrestore: use utimensat() to provide atime/mtime with ns resolution References: <1409848708-42666-1-git-send-email-bfoster@redhat.com> <20140905004501.GU20518@dastard> <54090C33.2060102@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <54090C33.2060102@sandeen.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1409880248 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9187 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 04, 2014 at 08:04:51PM -0500, Eric Sandeen wrote: > On 9/4/14, 7:45 PM, Dave Chinner wrote: > >On Thu, Sep 04, 2014 at 12:38:28PM -0400, Brian Foster wrote: > >>xfsdump encodes and stores the full atime and mtime for each file with > >>nanosecond resolution. xfsrestore uses utime() to set the times of each > >>file that is restored. The latter supports resolution of 1 second, thus > >>sub-second timestamp data is lost on restore. > > > >That doesn't seem like a big deal. What sort of problems does this > >actually cause? > > > >FYI, many linux filesystems only have second resolution timestamps > >and hence applications can't rely on sub-second timestamp resolution > >to actually mean anything useful.... > > But why not restore the same resolution as is actually stored in the dump? > Throwing it away seems odd, and restoring it looks easy enough. Comes from a time when we couldn't restore what was in the dump. :/ > In any case, there was a user who noticed & complained. Seems like a > very reasonable thing to fix, to me. Sure, but we don't make changes with the justification "just because". xfsrestore has had this behaviour since dump/restore was first introduced, so first we need to understand what the actual problem is. Was the user complaining because they noticed they were "different" in passing, or was it noticed because the difference is the root cause of some other problem? Cheers, Dave. -- Dave Chinner david@fromorbit.com From s.priebe@profihost.ag Fri Sep 5 04:47:36 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 1E1AB7F3F for ; Fri, 5 Sep 2014 04:47:36 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 0B44F30404E for ; Fri, 5 Sep 2014 02:47:32 -0700 (PDT) X-ASG-Debug-ID: 1409910450-04cbb05486a6b8d0001-NocioJ Received: from mail-ph.de-nserver.de (mail-ph.de-nserver.de [85.158.179.214]) by cuda.sgi.com with ESMTP id dbMlkDQsBWLZKJDR (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 05 Sep 2014 02:47:31 -0700 (PDT) X-Barracuda-Envelope-From: s.priebe@profihost.ag X-Barracuda-Apparent-Source-IP: 85.158.179.214 Received: (qmail 8072 invoked from network); 5 Sep 2014 11:47:29 +0200 X-Fcrdns: No Received: from phoffice.de-nserver.de (HELO [10.11.11.93]) (185.39.223.5) (smtp-auth username hostmaster@profihost.com, mechanism plain) by mail-ph.de-nserver.de (qpsmtpd/0.92) with (ECDHE-RSA-AES256-SHA encrypted) ESMTPSA; Fri, 05 Sep 2014 11:47:29 +0200 Message-ID: <540986B1.4080306@profihost.ag> Date: Fri, 05 Sep 2014 11:47:29 +0200 From: Stefan Priebe - Profihost AG User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.0 MIME-Version: 1.0 To: "xfs@oss.sgi.com" Subject: Is XFS suitable for 350 million files on 20TB storage? Content-Type: text/plain; charset=utf-8 X-ASG-Orig-Subj: Is XFS suitable for 350 million files on 20TB storage? Content-Transfer-Encoding: 7bit X-User-Auth: Auth by hostmaster@profihost.com through 185.39.223.5 X-Barracuda-Connect: mail-ph.de-nserver.de[85.158.179.214] X-Barracuda-Start-Time: 1409910450 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9198 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi, i have a backup system running 20TB of storage having 350 million files. This was working fine for month. But now the free space is so heavily fragmented that i only see the kworker with 4x 100% CPU and write speed beeing very slow. 15TB of the 20TB are in use. Overall files are 350 Million - all in different directories. Max 5000 per dir. Kernel is 3.10.53 and mount options are: noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=256k,noquota # xfs_db -r -c freesp /dev/sda1 from to extents blocks pct 1 1 29484138 29484138 2,16 2 3 16930134 39834672 2,92 4 7 16169985 87877159 6,45 8 15 78202543 999838327 73,41 16 31 3562456 83746085 6,15 32 63 2370812 102124143 7,50 64 127 280885 18929867 1,39 256 511 2 827 0,00 512 1023 65 35092 0,00 2048 4095 2 6561 0,00 16384 32767 1 23951 0,00 Is there anything i can optimize? Or is it just a bad idea to do this with XFS? Any other options? Maybe rsync options like --inplace / --no-whole-file? Greets, Stefan From bfoster@redhat.com Fri Sep 5 06:07:54 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A9BD97F3F for ; Fri, 5 Sep 2014 06:07:54 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 536B7AC003 for ; Fri, 5 Sep 2014 04:07:54 -0700 (PDT) X-ASG-Debug-ID: 1409915270-04bdf010a0781990001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id uisHmQYtTYkEN9xE (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 05 Sep 2014 04:07:50 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s85B7ghk031989 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 5 Sep 2014 07:07:42 -0400 Received: from laptop.bfoster (vpn-61-160.rdu2.redhat.com [10.10.61.160]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s85B7eB1014567 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Fri, 5 Sep 2014 07:07:41 -0400 Date: Fri, 5 Sep 2014 07:02:12 -0400 From: Brian Foster To: Dave Chinner Cc: Eric Sandeen , xfs@oss.sgi.com Subject: Re: [PATCH] xfsrestore: use utimensat() to provide atime/mtime with ns resolution Message-ID: <20140905110211.GA3208@laptop.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfsrestore: use utimensat() to provide atime/mtime with ns resolution References: <1409848708-42666-1-git-send-email-bfoster@redhat.com> <20140905004501.GU20518@dastard> <54090C33.2060102@sandeen.net> <20140905012404.GV20518@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140905012404.GV20518@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1409915270 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Sep 05, 2014 at 11:24:04AM +1000, Dave Chinner wrote: > On Thu, Sep 04, 2014 at 08:04:51PM -0500, Eric Sandeen wrote: > > On 9/4/14, 7:45 PM, Dave Chinner wrote: > > >On Thu, Sep 04, 2014 at 12:38:28PM -0400, Brian Foster wrote: > > >>xfsdump encodes and stores the full atime and mtime for each file with > > >>nanosecond resolution. xfsrestore uses utime() to set the times of each > > >>file that is restored. The latter supports resolution of 1 second, thus > > >>sub-second timestamp data is lost on restore. > > > > > >That doesn't seem like a big deal. What sort of problems does this > > >actually cause? > > > > > >FYI, many linux filesystems only have second resolution timestamps > > >and hence applications can't rely on sub-second timestamp resolution > > >to actually mean anything useful.... > > > > But why not restore the same resolution as is actually stored in the dump? > > Throwing it away seems odd, and restoring it looks easy enough. > > Comes from a time when we couldn't restore what was in the dump. :/ > > > In any case, there was a user who noticed & complained. Seems like a > > very reasonable thing to fix, to me. > > Sure, but we don't make changes with the justification "just > because". xfsrestore has had this behaviour since dump/restore was > first introduced, so first we need to understand what the actual > problem is. Was the user complaining because they noticed they were > "different" in passing, or was it noticed because the difference is > the root cause of some other problem? > No problems that I'm aware of. As Eric mentioned, it was noticed during an evaluation of possible data transfer mechanisms for a glusterfs setup. The user had to evaluate whether it would lead to any issues (a geo-replication tracking thing I suspect) for a customer, but I hadn't heard anything that suggested it was. The utime() call appears to be obsolete as well, for whatever that's worth. Brian > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com From greg.freemyer@gmail.com Fri Sep 5 06:19:43 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id E206C7F3F for ; Fri, 5 Sep 2014 06:19:43 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id CF409304070 for ; Fri, 5 Sep 2014 04:19:40 -0700 (PDT) X-ASG-Debug-ID: 1409915975-04cb6c54fd7e46f0001-NocioJ Received: from mail-qg0-f42.google.com (mail-qg0-f42.google.com [209.85.192.42]) by cuda.sgi.com with ESMTP id HQ45p3JsZoJxDKjt (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Fri, 05 Sep 2014 04:19:36 -0700 (PDT) X-Barracuda-Envelope-From: greg.freemyer@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.192.42 X-Barracuda-IPDD: Level1 [gmail.com/209.85.192.42] Received: by mail-qg0-f42.google.com with SMTP id q107so2274894qgd.15 for ; Fri, 05 Sep 2014 04:19:35 -0700 (PDT) X-Barracuda-IPDD: Level1 [gmail.com/209.85.192.42] X-Barracuda-IPDD: Level1 [gmail.com/209.85.192.42] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=user-agent:in-reply-to:references:mime-version :content-transfer-encoding:content-type:subject:from:date:to:cc :message-id; bh=Nq5x1wX3+z4pJTTiM4O/97qq8Sf+wcjFUAFSO0Gsa1o=; b=X3T/bP67ljXIxMZINYG3oJp38f1HTCnF7MDRGtST9q4UTky/LGjH3EOszRA9WTXsc7 /xEjXGSqBs9S5pyHNGoD0q8Jx0imX0+3V2xfKiNuOKv7lHCkSSU1juYWMv1khUaiqedw U5j0m+q8uLvzstP83ISegu/qZr4RiOdccOL0JpchOSeLfO3QSXA1Y5CgijH/c/oktgvQ RxqKatKPUoeqqruLhISZPaGFjnyveGGKZYPjbUs2Bp3P/w7Tz8rFKxjvI/MGlW8EuFg6 EGDMFVgjkbcc+qIStkCLYvyg5azg9/FRISmNSbwyao/tdrUWTRQbCZh6/wzBZLKl0Onj gsug== X-Received: by 10.224.11.212 with SMTP id u20mr7940769qau.82.1409915975741; Fri, 05 Sep 2014 04:19:35 -0700 (PDT) Received: from [192.168.3.73] (c-98-251-114-210.hsd1.ga.comcast.net. [98.251.114.210]) by mx.google.com with ESMTPSA id 95sm567484qgm.18.2014.09.05.04.19.33 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 05 Sep 2014 04:19:34 -0700 (PDT) User-Agent: K-9 Mail for Android In-Reply-To: <20140905110211.GA3208@laptop.bfoster> References: <1409848708-42666-1-git-send-email-bfoster@redhat.com> <20140905004501.GU20518@dastard> <54090C33.2060102@sandeen.net> <20140905012404.GV20518@dastard> <20140905110211.GA3208@laptop.bfoster> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Subject: Re: [PATCH] xfsrestore: use utimensat() to provide atime/mtime with ns resolution From: Greg Freemyer X-ASG-Orig-Subj: Re: [PATCH] xfsrestore: use utimensat() to provide atime/mtime with ns resolution Date: Fri, 05 Sep 2014 07:19:29 -0400 To: Brian Foster ,Dave Chinner CC: Eric Sandeen ,xfs@oss.sgi.com Message-ID: <21bfe93e-aadc-47d9-a49d-ec5207a72d99@email.android.com> X-Barracuda-Connect: mail-qg0-f42.google.com[209.85.192.42] X-Barracuda-Start-Time: 1409915976 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9200 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On September 5, 2014 7:02:12 AM EDT, Brian Foster wrote: >On Fri, Sep 05, 2014 at 11:24:04AM +1000, Dave Chinner wrote: >> On Thu, Sep 04, 2014 at 08:04:51PM -0500, Eric Sandeen wrote: >> > On 9/4/14, 7:45 PM, Dave Chinner wrote: >> > >On Thu, Sep 04, 2014 at 12:38:28PM -0400, Brian Foster wrote: >> > >>xfsdump encodes and stores the full atime and mtime for each file >with >> > >>nanosecond resolution. xfsrestore uses utime() to set the times >of each >> > >>file that is restored. The latter supports resolution of 1 >second, thus >> > >>sub-second timestamp data is lost on restore. >> > > >> > >That doesn't seem like a big deal. What sort of problems does this >> > >actually cause? >> > > >> > >FYI, many linux filesystems only have second resolution timestamps >> > >and hence applications can't rely on sub-second timestamp >resolution >> > >to actually mean anything useful.... >> > >> > But why not restore the same resolution as is actually stored in >the dump? >> > Throwing it away seems odd, and restoring it looks easy enough. >> >> Comes from a time when we couldn't restore what was in the dump. :/ >> >> > In any case, there was a user who noticed & complained. Seems like >a >> > very reasonable thing to fix, to me. >> >> Sure, but we don't make changes with the justification "just >> because". xfsrestore has had this behaviour since dump/restore was >> first introduced, so first we need to understand what the actual >> problem is. Was the user complaining because they noticed they were >> "different" in passing, or was it noticed because the difference is >> the root cause of some other problem? >> > >No problems that I'm aware of. As Eric mentioned, it was noticed during >an evaluation of possible data transfer mechanisms for a glusterfs >setup. The user had to evaluate whether it would lead to any issues (a >geo-replication tracking thing I suspect) for a customer, but I hadn't >heard anything that suggested it was. The utime() call appears to be >obsolete as well, for whatever that's worth. > >Brian During forensic exams, detailed examination of timestamps can be useful. For instance I saw a report recently that timestamps with only milliseconds precision (xxx.yyy00000) are an indication that malware has overridden the timestamp. It seems that the Windows api in particular has a time set mechanism that supports millisecond precision only. Thus xfs backing a samba share would I assume share that same forensic detail. The average breach is not detected until months after the initial penetration, so a xfsrestore between the activity of interest and the time of the investigation is very much a possibility. I don't know if you care about that use case. Greg -- Sent from my Android phone with K-9 Mail. Please excuse my brevity. From stefanrin@gmail.com Fri Sep 5 07:15:13 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id CB8DC7F3F for ; Fri, 5 Sep 2014 07:15:13 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id B9BE58F8035 for ; Fri, 5 Sep 2014 05:15:10 -0700 (PDT) X-ASG-Debug-ID: 1409919308-04cb6c54ff7e6340001-NocioJ Received: from mail-we0-f171.google.com (mail-we0-f171.google.com [74.125.82.171]) by cuda.sgi.com with ESMTP id zphGMoXNNHppcrVq (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Fri, 05 Sep 2014 05:15:09 -0700 (PDT) X-Barracuda-Envelope-From: stefanrin@gmail.com X-Barracuda-Apparent-Source-IP: 74.125.82.171 Received: by mail-we0-f171.google.com with SMTP id u56so11804940wes.2 for ; Fri, 05 Sep 2014 05:15:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=6JCnedpCbsKucT31UmMHXCBUP9ZpxDVL9C2lLdYL1Jw=; b=HCp9D5vUtLOkdRs/eerHQfVkPbszgvPegJ5wzoBIKUT4ANqjd1jWXIRYaKDeRogqHr pSIo3M6sMyRZBXmzgEiptqgfH0oja4GR2UXcOEcFV1vOmrdwtWasSYLSvUNR3RQBPNFN 3kW5+czNyM95FhbahxgI9/I4KxbJE3RX+lBt9xjmoUxBAUUoCjqVZnL1NM07GKPdD/O2 ieX+s6Yh8D3QuB6fRix6paNt/AWz/OojgS3sK0i1sglkkBGvUXrPGusBQaBTc6WkPOuk qzePnFMCHVkTSU0ztcf9uGFVV+fESV86l6KRzqzIPekkOu/TMm35bdv+qT5Ny2fFVx0H VULQ== MIME-Version: 1.0 X-Received: by 10.194.176.68 with SMTP id cg4mr2855218wjc.132.1409919303488; Fri, 05 Sep 2014 05:15:03 -0700 (PDT) Received: by 10.194.80.161 with HTTP; Fri, 5 Sep 2014 05:15:03 -0700 (PDT) In-Reply-To: <20140829083738.GD20518@dastard> References: <3dc9caf6f9b415f6e4c0ebac1f1626d3@zbfmail.de> <20140827230732.GN20518@dastard> <20140829083738.GD20518@dastard> Date: Fri, 5 Sep 2014 14:15:03 +0200 Message-ID: Subject: Re: mount options question From: Stefan Ring X-ASG-Orig-Subj: Re: mount options question To: Xfs Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-we0-f171.google.com[74.125.82.171] X-Barracuda-Start-Time: 1409919309 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9201 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature >> Mostly agreed, but using "discard" would be a no-brainer for me. I >> suppose XFS does not automatically switch it on for non-rotational >> storage. > > Yup, you're not using your brain. :P > > mount -o discard *sucks* on so many levels it is not funny. I don't > recommend that anybody *ever* use it, on XFS, ext4 or btrfs. Just > use fstrim if you ever need to clean up a SSD. Good to know, thanks! From bfoster@redhat.com Fri Sep 5 07:31:07 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 9EEB17F3F for ; Fri, 5 Sep 2014 07:31:07 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2A366AC007 for ; Fri, 5 Sep 2014 05:31:03 -0700 (PDT) X-ASG-Debug-ID: 1409920262-04cbb05485a70990001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id SSw1fr7Xjcowx0ZP (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 05 Sep 2014 05:31:02 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s85CV16b010407 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 5 Sep 2014 08:31:01 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s85CV0RU029584; Fri, 5 Sep 2014 08:31:00 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 3F3F41256F8; Fri, 5 Sep 2014 08:30:59 -0400 (EDT) Date: Fri, 5 Sep 2014 08:30:59 -0400 From: Brian Foster To: Stefan Priebe - Profihost AG Cc: "xfs@oss.sgi.com" Subject: Re: Is XFS suitable for 350 million files on 20TB storage? Message-ID: <20140905123058.GA29710@bfoster.bfoster> X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? References: <540986B1.4080306@profihost.ag> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540986B1.4080306@profihost.ag> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1409920262 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Sep 05, 2014 at 11:47:29AM +0200, Stefan Priebe - Profihost AG wrote: > Hi, > > i have a backup system running 20TB of storage having 350 million files. > This was working fine for month. > > But now the free space is so heavily fragmented that i only see the > kworker with 4x 100% CPU and write speed beeing very slow. 15TB of the > 20TB are in use. > > Overall files are 350 Million - all in different directories. Max 5000 > per dir. > > Kernel is 3.10.53 and mount options are: > noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=256k,noquota > > # xfs_db -r -c freesp /dev/sda1 > from to extents blocks pct > 1 1 29484138 29484138 2,16 > 2 3 16930134 39834672 2,92 > 4 7 16169985 87877159 6,45 > 8 15 78202543 999838327 73,41 > 16 31 3562456 83746085 6,15 > 32 63 2370812 102124143 7,50 > 64 127 280885 18929867 1,39 > 256 511 2 827 0,00 > 512 1023 65 35092 0,00 > 2048 4095 2 6561 0,00 > 16384 32767 1 23951 0,00 > > Is there anything i can optimize? Or is it just a bad idea to do this > with XFS? Any other options? Maybe rsync options like --inplace / > --no-whole-file? > It's probably a good idea to include more information about your fs: http://xfs.org/index.php/XFS_FAQ#Q:_What_information_should_I_include_when_reporting_a_problem.3F ... as well as what your typical workflow/dataset is for this fs. It seems like you have relatively small files (15TB used across 350m files is around 46k per file), yes? If so, I wonder if something like the following commit introduced in 3.12 would help: 133eeb17 xfs: don't use speculative prealloc for small files Brian > Greets, > Stefan > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From s.priebe@profihost.ag Fri Sep 5 07:40:36 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 7EA827F3F for ; Fri, 5 Sep 2014 07:40:36 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id ED874AC001 for ; Fri, 5 Sep 2014 05:40:35 -0700 (PDT) X-ASG-Debug-ID: 1409920833-04cbb05487a70e00001-NocioJ Received: from mail-ph.de-nserver.de (mail-ph.de-nserver.de [85.158.179.214]) by cuda.sgi.com with ESMTP id 2YhsP0qR1jKU4a6O (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 05 Sep 2014 05:40:33 -0700 (PDT) X-Barracuda-Envelope-From: s.priebe@profihost.ag X-Barracuda-Apparent-Source-IP: 85.158.179.214 Received: (qmail 28501 invoked from network); 5 Sep 2014 14:40:32 +0200 X-Fcrdns: No Received: from phoffice.de-nserver.de (HELO [10.11.11.93]) (185.39.223.5) (smtp-auth username hostmaster@profihost.com, mechanism plain) by mail-ph.de-nserver.de (qpsmtpd/0.92) with (ECDHE-RSA-AES256-SHA encrypted) ESMTPSA; Fri, 05 Sep 2014 14:40:32 +0200 Message-ID: <5409AF40.10801@profihost.ag> Date: Fri, 05 Sep 2014 14:40:32 +0200 From: Stefan Priebe - Profihost AG User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.0 MIME-Version: 1.0 To: Brian Foster CC: "xfs@oss.sgi.com" Subject: Re: Is XFS suitable for 350 million files on 20TB storage? References: <540986B1.4080306@profihost.ag> <20140905123058.GA29710@bfoster.bfoster> X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? In-Reply-To: <20140905123058.GA29710@bfoster.bfoster> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-User-Auth: Auth by hostmaster@profihost.com through 185.39.223.5 X-Barracuda-Connect: mail-ph.de-nserver.de[85.158.179.214] X-Barracuda-Start-Time: 1409920833 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9202 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 BSF_SC0_SA085 Custom Rule SA085 Am 05.09.2014 um 14:30 schrieb Brian Foster: > On Fri, Sep 05, 2014 at 11:47:29AM +0200, Stefan Priebe - Profihost AG wrote: >> Hi, >> >> i have a backup system running 20TB of storage having 350 million files. >> This was working fine for month. >> >> But now the free space is so heavily fragmented that i only see the >> kworker with 4x 100% CPU and write speed beeing very slow. 15TB of the >> 20TB are in use. >> >> Overall files are 350 Million - all in different directories. Max 5000 >> per dir. >> >> Kernel is 3.10.53 and mount options are: >> noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=256k,noquota >> >> # xfs_db -r -c freesp /dev/sda1 >> from to extents blocks pct >> 1 1 29484138 29484138 2,16 >> 2 3 16930134 39834672 2,92 >> 4 7 16169985 87877159 6,45 >> 8 15 78202543 999838327 73,41 >> 16 31 3562456 83746085 6,15 >> 32 63 2370812 102124143 7,50 >> 64 127 280885 18929867 1,39 >> 256 511 2 827 0,00 >> 512 1023 65 35092 0,00 >> 2048 4095 2 6561 0,00 >> 16384 32767 1 23951 0,00 >> >> Is there anything i can optimize? Or is it just a bad idea to do this >> with XFS? Any other options? Maybe rsync options like --inplace / >> --no-whole-file? >> > > It's probably a good idea to include more information about your fs: > > http://xfs.org/index.php/XFS_FAQ#Q:_What_information_should_I_include_when_reporting_a_problem.3F Generally sure but the problem itself is clear. If you look at the free space allocation you see that free space is heavily fragmented. But here you go: - 3.10.53 vanilla - xfs_repair version 3.1.11 - 16 cores - /dev/sda1 /backup xfs rw,noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=256k,noquota 0 0 - Raid 10 with 1GB controller cache running in write back mode using 24 spinners - no lvm - no io waits - xfs_info /serverbackup/ meta-data=/dev/sda1 isize=256 agcount=21, agsize=268435455 blks = sectsz=512 attr=2 data = bsize=4096 blocks=5369232896, imaxpct=5 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 log =internal bsize=4096 blocks=521728, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 anything missing? > ... as well as what your typical workflow/dataset is for this fs. It > seems like you have relatively small files (15TB used across 350m files > is around 46k per file), yes? Yes - most fo them are even smaller. And some files are > 5GB. > If so, I wonder if something like the > following commit introduced in 3.12 would help: > > 133eeb17 xfs: don't use speculative prealloc for small files Looks interesting. Stefan From bfoster@redhat.com Fri Sep 5 08:48:18 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 23CFA7F3F for ; Fri, 5 Sep 2014 08:48:18 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id D996A304062 for ; Fri, 5 Sep 2014 06:48:14 -0700 (PDT) X-ASG-Debug-ID: 1409924893-04bdf01097787980001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id vmDv4oCnhJfZFSb8 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 05 Sep 2014 06:48:13 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s85DmDt7002023 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 5 Sep 2014 09:48:13 -0400 Received: from laptop.bfoster (vpn-61-160.rdu2.redhat.com [10.10.61.160]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s85DmAvd025385 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Fri, 5 Sep 2014 09:48:12 -0400 Date: Fri, 5 Sep 2014 09:48:10 -0400 From: Brian Foster To: Stefan Priebe - Profihost AG Cc: "xfs@oss.sgi.com" Subject: Re: Is XFS suitable for 350 million files on 20TB storage? Message-ID: <20140905134810.GA3965@laptop.bfoster> X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? References: <540986B1.4080306@profihost.ag> <20140905123058.GA29710@bfoster.bfoster> <5409AF40.10801@profihost.ag> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5409AF40.10801@profihost.ag> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1409924893 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Sep 05, 2014 at 02:40:32PM +0200, Stefan Priebe - Profihost AG wrote: > > Am 05.09.2014 um 14:30 schrieb Brian Foster: > > On Fri, Sep 05, 2014 at 11:47:29AM +0200, Stefan Priebe - Profihost AG wrote: > >> Hi, > >> > >> i have a backup system running 20TB of storage having 350 million files. > >> This was working fine for month. > >> > >> But now the free space is so heavily fragmented that i only see the > >> kworker with 4x 100% CPU and write speed beeing very slow. 15TB of the > >> 20TB are in use. > >> > >> Overall files are 350 Million - all in different directories. Max 5000 > >> per dir. > >> > >> Kernel is 3.10.53 and mount options are: > >> noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=256k,noquota > >> > >> # xfs_db -r -c freesp /dev/sda1 > >> from to extents blocks pct > >> 1 1 29484138 29484138 2,16 > >> 2 3 16930134 39834672 2,92 > >> 4 7 16169985 87877159 6,45 > >> 8 15 78202543 999838327 73,41 > >> 16 31 3562456 83746085 6,15 > >> 32 63 2370812 102124143 7,50 > >> 64 127 280885 18929867 1,39 > >> 256 511 2 827 0,00 > >> 512 1023 65 35092 0,00 > >> 2048 4095 2 6561 0,00 > >> 16384 32767 1 23951 0,00 > >> > >> Is there anything i can optimize? Or is it just a bad idea to do this > >> with XFS? Any other options? Maybe rsync options like --inplace / > >> --no-whole-file? > >> > > > > It's probably a good idea to include more information about your fs: > > > > http://xfs.org/index.php/XFS_FAQ#Q:_What_information_should_I_include_when_reporting_a_problem.3F > > Generally sure but the problem itself is clear. If you look at the free > space allocation you see that free space is heavily fragmented. > > But here you go: > - 3.10.53 vanilla > - xfs_repair version 3.1.11 > - 16 cores > - /dev/sda1 /backup xfs > rw,noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=256k,noquota 0 0 > - Raid 10 with 1GB controller cache running in write back mode using 24 > spinners > - no lvm > - no io waits > - xfs_info /serverbackup/ > meta-data=/dev/sda1 isize=256 agcount=21, > agsize=268435455 blks > = sectsz=512 attr=2 > data = bsize=4096 blocks=5369232896, imaxpct=5 > = sunit=0 swidth=0 blks > naming =version 2 bsize=4096 ascii-ci=0 > log =internal bsize=4096 blocks=521728, version=2 > = sectsz=512 sunit=0 blks, lazy-count=1 > realtime =none extsz=4096 blocks=0, rtextents=0 > > anything missing? > What's the workload to the fs? Is it repeated rsync's from a constantly changing dataset? Do the files change frequently or are they only ever added/removed? Also, what is the characterization of writes being "slow?" An rsync is slower than normal? Sustained writes to a single file? How significant a degradation? Something like the following might be interesting as well: for i in $(seq 0 20); do xfs_db -c "agi $i" -c "p freecount" ; done Brian > > ... as well as what your typical workflow/dataset is for this fs. It > > seems like you have relatively small files (15TB used across 350m files > > is around 46k per file), yes? > > Yes - most fo them are even smaller. And some files are > 5GB. > > > If so, I wonder if something like the > > following commit introduced in 3.12 would help: > > > > 133eeb17 xfs: don't use speculative prealloc for small files > > Looks interesting. > > Stefan From s.priebe@profihost.ag Fri Sep 5 13:07:40 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 82E5D7F3F for ; Fri, 5 Sep 2014 13:07:40 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1FB65AC001 for ; Fri, 5 Sep 2014 11:07:36 -0700 (PDT) X-ASG-Debug-ID: 1409940453-04bdf0109a793490001-NocioJ Received: from mail-ph.de-nserver.de (mail-ph.de-nserver.de [85.158.179.214]) by cuda.sgi.com with ESMTP id cxSA6aUlbHVtD5fC (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 05 Sep 2014 11:07:34 -0700 (PDT) X-Barracuda-Envelope-From: s.priebe@profihost.ag X-Barracuda-Apparent-Source-IP: 85.158.179.214 Received: (qmail 25751 invoked from network); 5 Sep 2014 20:07:32 +0200 X-Fcrdns: No Received: from phoffice.de-nserver.de (HELO [10.242.2.6]) (185.39.223.5) (smtp-auth username s.priebe@profihost.ag, mechanism plain) by mail-ph.de-nserver.de (qpsmtpd/0.92) with (ECDHE-RSA-AES256-SHA encrypted) ESMTPSA; Fri, 05 Sep 2014 20:07:32 +0200 Message-ID: <5409FBEA.9050708@profihost.ag> Date: Fri, 05 Sep 2014 20:07:38 +0200 From: Stefan Priebe User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: Brian Foster CC: "xfs@oss.sgi.com" Subject: Re: Is XFS suitable for 350 million files on 20TB storage? References: <540986B1.4080306@profihost.ag> <20140905123058.GA29710@bfoster.bfoster> <5409AF40.10801@profihost.ag> <20140905134810.GA3965@laptop.bfoster> X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? In-Reply-To: <20140905134810.GA3965@laptop.bfoster> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-User-Auth: Auth by s.priebe@profihost.ag through 185.39.223.5 X-Barracuda-Connect: mail-ph.de-nserver.de[85.158.179.214] X-Barracuda-Start-Time: 1409940454 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9209 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 BSF_SC0_SA085 Custom Rule SA085 Hi, Am 05.09.2014 15:48, schrieb Brian Foster: > On Fri, Sep 05, 2014 at 02:40:32PM +0200, Stefan Priebe - Profihost AG wrote: >> >> Am 05.09.2014 um 14:30 schrieb Brian Foster: >>> On Fri, Sep 05, 2014 at 11:47:29AM +0200, Stefan Priebe - Profihost AG wrote: >>>> Hi, >>>> >>>> i have a backup system running 20TB of storage having 350 million files. >>>> This was working fine for month. >>>> >>>> But now the free space is so heavily fragmented that i only see the >>>> kworker with 4x 100% CPU and write speed beeing very slow. 15TB of the >>>> 20TB are in use. >>>> >>>> Overall files are 350 Million - all in different directories. Max 5000 >>>> per dir. >>>> >>>> Kernel is 3.10.53 and mount options are: >>>> noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=256k,noquota >>>> >>>> # xfs_db -r -c freesp /dev/sda1 >>>> from to extents blocks pct >>>> 1 1 29484138 29484138 2,16 >>>> 2 3 16930134 39834672 2,92 >>>> 4 7 16169985 87877159 6,45 >>>> 8 15 78202543 999838327 73,41 >>>> 16 31 3562456 83746085 6,15 >>>> 32 63 2370812 102124143 7,50 >>>> 64 127 280885 18929867 1,39 >>>> 256 511 2 827 0,00 >>>> 512 1023 65 35092 0,00 >>>> 2048 4095 2 6561 0,00 >>>> 16384 32767 1 23951 0,00 >>>> >>>> Is there anything i can optimize? Or is it just a bad idea to do this >>>> with XFS? Any other options? Maybe rsync options like --inplace / >>>> --no-whole-file? >>>> >>> >>> It's probably a good idea to include more information about your fs: >>> >>> http://xfs.org/index.php/XFS_FAQ#Q:_What_information_should_I_include_when_reporting_a_problem.3F >> >> Generally sure but the problem itself is clear. If you look at the free >> space allocation you see that free space is heavily fragmented. >> >> But here you go: >> - 3.10.53 vanilla >> - xfs_repair version 3.1.11 >> - 16 cores >> - /dev/sda1 /backup xfs >> rw,noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=256k,noquota 0 0 >> - Raid 10 with 1GB controller cache running in write back mode using 24 >> spinners >> - no lvm >> - no io waits >> - xfs_info /serverbackup/ >> meta-data=/dev/sda1 isize=256 agcount=21, >> agsize=268435455 blks >> = sectsz=512 attr=2 >> data = bsize=4096 blocks=5369232896, imaxpct=5 >> = sunit=0 swidth=0 blks >> naming =version 2 bsize=4096 ascii-ci=0 >> log =internal bsize=4096 blocks=521728, version=2 >> = sectsz=512 sunit=0 blks, lazy-count=1 >> realtime =none extsz=4096 blocks=0, rtextents=0 >> >> anything missing? >> > > What's the workload to the fs? Is it repeated rsync's from a constantly > changing dataset? Do the files change frequently or are they only ever > added/removed? Yes it repeated rsync with constant changing files. About 10-20% of all files every week. A mixture of changing, removing / adding. > Also, what is the characterization of writes being "slow?" An rsync is > slower than normal? Sustained writes to a single file? How significant a > degradation? kworker is using all cpu while writing data to this xfs partition. rsync can just write at a rate of 32-128kb/s. > Something like the following might be interesting as well: > for i in $(seq 0 20); do xfs_db -c "agi $i" -c "p freecount" ; done freecount = 3189417 freecount = 1975726 freecount = 1309903 freecount = 1726846 freecount = 1271047 freecount = 1281956 freecount = 1571285 freecount = 1365473 freecount = 1238118 freecount = 1697011 freecount = 1000832 freecount = 1369791 freecount = 1706360 freecount = 1439165 freecount = 1656404 freecount = 1881762 freecount = 1593432 freecount = 1555909 freecount = 1197091 freecount = 1667467 freecount = 63 Thanks! Stefan > Brian > >>> ... as well as what your typical workflow/dataset is for this fs. It >>> seems like you have relatively small files (15TB used across 350m files >>> is around 46k per file), yes? >> >> Yes - most fo them are even smaller. And some files are > 5GB. >> >>> If so, I wonder if something like the >>> following commit introduced in 3.12 would help: >>> >>> 133eeb17 xfs: don't use speculative prealloc for small files >> >> Looks interesting. >> >> Stefan From bfoster@redhat.com Fri Sep 5 14:18:25 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 47BAA7F3F for ; Fri, 5 Sep 2014 14:18:25 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 0AF09304053 for ; Fri, 5 Sep 2014 12:18:21 -0700 (PDT) X-ASG-Debug-ID: 1409944700-04bdf01097795d80001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id WzXPihWq4e090QW7 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 05 Sep 2014 12:18:20 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s85JIJal017100 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 5 Sep 2014 15:18:19 -0400 Received: from laptop.bfoster (vpn-61-160.rdu2.redhat.com [10.10.61.160]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s85JIGeA014257 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Fri, 5 Sep 2014 15:18:18 -0400 Date: Fri, 5 Sep 2014 15:18:16 -0400 From: Brian Foster To: Stefan Priebe Cc: "xfs@oss.sgi.com" Subject: Re: Is XFS suitable for 350 million files on 20TB storage? Message-ID: <20140905191815.GB8400@laptop.bfoster> X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? References: <540986B1.4080306@profihost.ag> <20140905123058.GA29710@bfoster.bfoster> <5409AF40.10801@profihost.ag> <20140905134810.GA3965@laptop.bfoster> <5409FBEA.9050708@profihost.ag> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5409FBEA.9050708@profihost.ag> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1409944700 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Sep 05, 2014 at 08:07:38PM +0200, Stefan Priebe wrote: > Hi, > > Am 05.09.2014 15:48, schrieb Brian Foster: > >On Fri, Sep 05, 2014 at 02:40:32PM +0200, Stefan Priebe - Profihost AG wrote: > >> > >>Am 05.09.2014 um 14:30 schrieb Brian Foster: > >>>On Fri, Sep 05, 2014 at 11:47:29AM +0200, Stefan Priebe - Profihost AG wrote: > >>>>Hi, > >>>> > >>>>i have a backup system running 20TB of storage having 350 million files. > >>>>This was working fine for month. > >>>> > >>>>But now the free space is so heavily fragmented that i only see the > >>>>kworker with 4x 100% CPU and write speed beeing very slow. 15TB of the > >>>>20TB are in use. > >>>> > >>>>Overall files are 350 Million - all in different directories. Max 5000 > >>>>per dir. > >>>> > >>>>Kernel is 3.10.53 and mount options are: > >>>>noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=256k,noquota > >>>> > >>>># xfs_db -r -c freesp /dev/sda1 > >>>> from to extents blocks pct > >>>> 1 1 29484138 29484138 2,16 > >>>> 2 3 16930134 39834672 2,92 > >>>> 4 7 16169985 87877159 6,45 > >>>> 8 15 78202543 999838327 73,41 > >>>> 16 31 3562456 83746085 6,15 > >>>> 32 63 2370812 102124143 7,50 > >>>> 64 127 280885 18929867 1,39 > >>>> 256 511 2 827 0,00 > >>>> 512 1023 65 35092 0,00 > >>>> 2048 4095 2 6561 0,00 > >>>> 16384 32767 1 23951 0,00 > >>>> > >>>>Is there anything i can optimize? Or is it just a bad idea to do this > >>>>with XFS? Any other options? Maybe rsync options like --inplace / > >>>>--no-whole-file? > >>>> > >>> > >>>It's probably a good idea to include more information about your fs: > >>> > >>>http://xfs.org/index.php/XFS_FAQ#Q:_What_information_should_I_include_when_reporting_a_problem.3F > >> > >>Generally sure but the problem itself is clear. If you look at the free > >>space allocation you see that free space is heavily fragmented. > >> > >>But here you go: > >>- 3.10.53 vanilla > >>- xfs_repair version 3.1.11 > >>- 16 cores > >>- /dev/sda1 /backup xfs > >>rw,noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=256k,noquota 0 0 > >>- Raid 10 with 1GB controller cache running in write back mode using 24 > >>spinners > >>- no lvm > >>- no io waits > >>- xfs_info /serverbackup/ > >>meta-data=/dev/sda1 isize=256 agcount=21, > >>agsize=268435455 blks > >> = sectsz=512 attr=2 > >>data = bsize=4096 blocks=5369232896, imaxpct=5 > >> = sunit=0 swidth=0 blks > >>naming =version 2 bsize=4096 ascii-ci=0 > >>log =internal bsize=4096 blocks=521728, version=2 > >> = sectsz=512 sunit=0 blks, lazy-count=1 > >>realtime =none extsz=4096 blocks=0, rtextents=0 > >> > >>anything missing? > >> > > > >What's the workload to the fs? Is it repeated rsync's from a constantly > >changing dataset? Do the files change frequently or are they only ever > >added/removed? > > Yes it repeated rsync with constant changing files. About 10-20% of all > files every week. A mixture of changing, removing / adding. > Ok. > >Also, what is the characterization of writes being "slow?" An rsync is > >slower than normal? Sustained writes to a single file? How significant a > >degradation? > > kworker is using all cpu while writing data to this xfs partition. rsync can > just write at a rate of 32-128kb/s. > Do you have a baseline? This seems highly subjective. By that I mean this could be slower for copying a lot of little files, faster if you happen to copy a single large file, etc. > >Something like the following might be interesting as well: > >for i in $(seq 0 20); do xfs_db -c "agi $i" -c "p freecount" ; done > freecount = 3189417 > freecount = 1975726 > freecount = 1309903 > freecount = 1726846 > freecount = 1271047 > freecount = 1281956 > freecount = 1571285 > freecount = 1365473 > freecount = 1238118 > freecount = 1697011 > freecount = 1000832 > freecount = 1369791 > freecount = 1706360 > freecount = 1439165 > freecount = 1656404 > freecount = 1881762 > freecount = 1593432 > freecount = 1555909 > freecount = 1197091 > freecount = 1667467 > freecount = 63 > Interesting, that seems like a lot of free inodes. That's 1-2 million in each AG that we have to look around for each time we want to allocate an inode. I can't say for sure that's the source of the slowdown, but this certainly looks like the kind of workload that inspired the addition of the free inode btree (finobt) to more recent kernels. It appears that you still have quite a bit of space available in general. Could you run some local tests on this filesystem to try and quantify how much of this degradation manifests on sustained writes vs. file creation? For example, how is throughput when writing a few GB to a local test file? How about with that same amount of data broken up across a few thousand files? Brian P.S., Alternatively if you wanted to grab a metadump of this filesystem and compress/upload it somewhere, I'd be interested to take a look at it. > Thanks! > > Stefan > > > > >Brian > > > >>>... as well as what your typical workflow/dataset is for this fs. It > >>>seems like you have relatively small files (15TB used across 350m files > >>>is around 46k per file), yes? > >> > >>Yes - most fo them are even smaller. And some files are > 5GB. > >> > >>>If so, I wonder if something like the > >>>following commit introduced in 3.12 would help: > >>> > >>>133eeb17 xfs: don't use speculative prealloc for small files > >> > >>Looks interesting. > >> > >>Stefan From s.priebe@profihost.ag Fri Sep 5 15:14:52 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id DD5A57F3F for ; Fri, 5 Sep 2014 15:14:52 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id A13FF8F804C for ; Fri, 5 Sep 2014 13:14:52 -0700 (PDT) X-ASG-Debug-ID: 1409948086-04bdf01097798550001-NocioJ Received: from mail-ph.de-nserver.de (mail-ph.de-nserver.de [85.158.179.214]) by cuda.sgi.com with ESMTP id J1F1oyQZ28pPO99X (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 05 Sep 2014 13:14:47 -0700 (PDT) X-Barracuda-Envelope-From: s.priebe@profihost.ag X-Barracuda-Apparent-Source-IP: 85.158.179.214 Received: (qmail 9276 invoked from network); 5 Sep 2014 22:14:45 +0200 X-Fcrdns: No Received: from phoffice.de-nserver.de (HELO [10.242.2.10]) (185.39.223.5) (smtp-auth username s.priebe@profihost.ag, mechanism plain) by mail-ph.de-nserver.de (qpsmtpd/0.92) with (ECDHE-RSA-AES256-SHA encrypted) ESMTPSA; Fri, 05 Sep 2014 22:14:45 +0200 Message-ID: <540A19BB.8040404@profihost.ag> Date: Fri, 05 Sep 2014 22:14:51 +0200 From: Stefan Priebe User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: Brian Foster CC: "xfs@oss.sgi.com" Subject: Re: Is XFS suitable for 350 million files on 20TB storage? References: <540986B1.4080306@profihost.ag> <20140905123058.GA29710@bfoster.bfoster> <5409AF40.10801@profihost.ag> <20140905134810.GA3965@laptop.bfoster> <5409FBEA.9050708@profihost.ag> <20140905191815.GB8400@laptop.bfoster> X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? In-Reply-To: <20140905191815.GB8400@laptop.bfoster> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-User-Auth: Auth by s.priebe@profihost.ag through 185.39.223.5 X-Barracuda-Connect: mail-ph.de-nserver.de[85.158.179.214] X-Barracuda-Start-Time: 1409948087 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9212 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Am 05.09.2014 21:18, schrieb Brian Foster: ... > On Fri, Sep 05, 2014 at 08:07:38PM +0200, Stefan Priebe wrote: > Interesting, that seems like a lot of free inodes. That's 1-2 million in > each AG that we have to look around for each time we want to allocate an > inode. I can't say for sure that's the source of the slowdown, but this > certainly looks like the kind of workload that inspired the addition of > the free inode btree (finobt) to more recent kernels. > > It appears that you still have quite a bit of space available in > general. Could you run some local tests on this filesystem to try and > quantify how much of this degradation manifests on sustained writes vs. > file creation? For example, how is throughput when writing a few GB to a > local test file? Not sure if this is what you expect: # dd if=/dev/zero of=bigfile oflag=direct,sync bs=4M count=1000 1000+0 records in 1000+0 records out 4194304000 bytes (4,2 GB) copied, 125,809 s, 33,3 MB/s or without sync # dd if=/dev/zero of=bigfile oflag=direct bs=4M count=1000 1000+0 records in 1000+0 records out 4194304000 bytes (4,2 GB) copied, 32,5474 s, 129 MB/s > How about with that same amount of data broken up > across a few thousand files? This results in heavy kworker usage. 4GB in 32kb files # time (mkdir test; for i in $(seq 1 1 131072); do dd if=/dev/zero of=test/$i bs=32k count=1 oflag=direct,sync 2>/dev/null; done) ... 55 min > Brian > > P.S., Alternatively if you wanted to grab a metadump of this filesystem > and compress/upload it somewhere, I'd be interested to take a look at > it. I think there might be file and directory names in it. If this is the case i can't do it. Stefan > >> Thanks! >> >> Stefan >> >> >> >>> Brian >>> >>>>> ... as well as what your typical workflow/dataset is for this fs. It >>>>> seems like you have relatively small files (15TB used across 350m files >>>>> is around 46k per file), yes? >>>> >>>> Yes - most fo them are even smaller. And some files are > 5GB. >>>> >>>>> If so, I wonder if something like the >>>>> following commit introduced in 3.12 would help: >>>>> >>>>> 133eeb17 xfs: don't use speculative prealloc for small files >>>> >>>> Looks interesting. >>>> >>>> Stefan From bfoster@redhat.com Fri Sep 5 16:24:13 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 6CC777F3F for ; Fri, 5 Sep 2014 16:24:13 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 5C0B08F8049 for ; Fri, 5 Sep 2014 14:24:10 -0700 (PDT) X-ASG-Debug-ID: 1409952245-04cb6c55007fac90001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id rPvCvGQrKUvnlDCB (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 05 Sep 2014 14:24:06 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s85LO38f028319 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 5 Sep 2014 17:24:04 -0400 Received: from laptop.bfoster (vpn-61-160.rdu2.redhat.com [10.10.61.160]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s85LO1JI012511 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Fri, 5 Sep 2014 17:24:03 -0400 Date: Fri, 5 Sep 2014 17:24:01 -0400 From: Brian Foster To: Stefan Priebe Cc: "xfs@oss.sgi.com" Subject: Re: Is XFS suitable for 350 million files on 20TB storage? Message-ID: <20140905212400.GA8904@laptop.bfoster> X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? References: <540986B1.4080306@profihost.ag> <20140905123058.GA29710@bfoster.bfoster> <5409AF40.10801@profihost.ag> <20140905134810.GA3965@laptop.bfoster> <5409FBEA.9050708@profihost.ag> <20140905191815.GB8400@laptop.bfoster> <540A19BB.8040404@profihost.ag> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540A19BB.8040404@profihost.ag> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1409952246 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Sep 05, 2014 at 10:14:51PM +0200, Stefan Priebe wrote: > > Am 05.09.2014 21:18, schrieb Brian Foster: > ... > > >On Fri, Sep 05, 2014 at 08:07:38PM +0200, Stefan Priebe wrote: > >Interesting, that seems like a lot of free inodes. That's 1-2 million in > >each AG that we have to look around for each time we want to allocate an > >inode. I can't say for sure that's the source of the slowdown, but this > >certainly looks like the kind of workload that inspired the addition of > >the free inode btree (finobt) to more recent kernels. > > > >It appears that you still have quite a bit of space available in > >general. Could you run some local tests on this filesystem to try and > >quantify how much of this degradation manifests on sustained writes vs. > >file creation? For example, how is throughput when writing a few GB to a > >local test file? > > Not sure if this is what you expect: > > # dd if=/dev/zero of=bigfile oflag=direct,sync bs=4M count=1000 > 1000+0 records in > 1000+0 records out > 4194304000 bytes (4,2 GB) copied, 125,809 s, 33,3 MB/s > > or without sync > # dd if=/dev/zero of=bigfile oflag=direct bs=4M count=1000 > 1000+0 records in > 1000+0 records out > 4194304000 bytes (4,2 GB) copied, 32,5474 s, 129 MB/s > > > How about with that same amount of data broken up > >across a few thousand files? > > This results in heavy kworker usage. > > 4GB in 32kb files > # time (mkdir test; for i in $(seq 1 1 131072); do dd if=/dev/zero > of=test/$i bs=32k count=1 oflag=direct,sync 2>/dev/null; done) > > ... > > 55 min > Both seem pretty slow in general. Any way you can establish a baseline for these tests on this storage? If not, the only other suggestion I could make is to allocate inodes until all of those freecount numbers are accounted for and see if anything changes. That could certainly take some time and it's not clear it will actually help. > >Brian > > > >P.S., Alternatively if you wanted to grab a metadump of this filesystem > >and compress/upload it somewhere, I'd be interested to take a look at > >it. > > I think there might be file and directory names in it. If this is the case i > can't do it. > It should enable obfuscation by default, but I would suggest to restore it yourself and verify it meets your expectations. Brian > Stefan > > > > > >>Thanks! > >> > >>Stefan > >> > >> > >> > >>>Brian > >>> > >>>>>... as well as what your typical workflow/dataset is for this fs. It > >>>>>seems like you have relatively small files (15TB used across 350m files > >>>>>is around 46k per file), yes? > >>>> > >>>>Yes - most fo them are even smaller. And some files are > 5GB. > >>>> > >>>>>If so, I wonder if something like the > >>>>>following commit introduced in 3.12 would help: > >>>>> > >>>>>133eeb17 xfs: don't use speculative prealloc for small files > >>>> > >>>>Looks interesting. > >>>> > >>>>Stefan > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From scaron@umich.edu Fri Sep 5 17:39:45 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id EEC9A7F3F for ; Fri, 5 Sep 2014 17:39:45 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id B05DA30406A for ; Fri, 5 Sep 2014 15:39:45 -0700 (PDT) X-ASG-Debug-ID: 1409956782-04bdf010a179d6d0001-NocioJ Received: from mail-qc0-f175.google.com (mail-qc0-f175.google.com [209.85.216.175]) by cuda.sgi.com with ESMTP id B5tQk8OUzx1NzM6y (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Fri, 05 Sep 2014 15:39:43 -0700 (PDT) X-Barracuda-Envelope-From: scaron@umich.edu X-Barracuda-Apparent-Source-IP: 209.85.216.175 Received: by mail-qc0-f175.google.com with SMTP id c9so13004326qcz.20 for ; Fri, 05 Sep 2014 15:39:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=CNlyq4CAgIxpermYifourtgtMIjk1FgmHrZy1YJRLQw=; b=m+SqFVMfCTDo3c18FnzClL7RxBK+RQy55+kMG7QHjg78+ZfQqJd9h15fSSh0MNxj/2 2YhrkTIjIFROqL/DobiVlFh7fgweGAVTiiK7PR9xMmlurotY0d1R4nI2ZTPq0TwGogLO +PLGKOmAz9D/wZdAQAiqJTR1qVitj8Zb0q96J5d9Jx1WwI9fmHOBAuzactWv1Q5/Vo4G IHWxgJAaQ2YTVqENII6pTT6u8BaFxlvzP6zfl8H94B1aGDXRu6L7dytJWVuPMJmc4W7t 7zXH7eRK0UL01vjyW4UxhShULr0gFj8BQ2zIObPfrs334QUDmJlg0RJ9BMnNMy8PsNeW DFOQ== X-Gm-Message-State: ALoCoQkPKGckVUd6lR7/Z4Wcqz54fhy0Cwk09lbNGiesWi/MMX9r5MoOmN8OO8l5iAECImcrm0g2 MIME-Version: 1.0 X-Received: by 10.224.46.138 with SMTP id j10mr22738202qaf.85.1409956782408; Fri, 05 Sep 2014 15:39:42 -0700 (PDT) Received: by 10.224.8.132 with HTTP; Fri, 5 Sep 2014 15:39:42 -0700 (PDT) In-Reply-To: <20140905212400.GA8904@laptop.bfoster> References: <540986B1.4080306@profihost.ag> <20140905123058.GA29710@bfoster.bfoster> <5409AF40.10801@profihost.ag> <20140905134810.GA3965@laptop.bfoster> <5409FBEA.9050708@profihost.ag> <20140905191815.GB8400@laptop.bfoster> <540A19BB.8040404@profihost.ag> <20140905212400.GA8904@laptop.bfoster> Date: Fri, 5 Sep 2014 18:39:42 -0400 Message-ID: Subject: Re: Is XFS suitable for 350 million files on 20TB storage? From: Sean Caron X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? To: Brian Foster , Sean Caron Cc: Stefan Priebe , "xfs@oss.sgi.com" Content-Type: multipart/alternative; boundary=001a11c1f0da2a1c3e05025925d2 X-Barracuda-Connect: mail-qc0-f175.google.com[209.85.216.175] X-Barracuda-Start-Time: 1409956782 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9215 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message --001a11c1f0da2a1c3e05025925d2 Content-Type: text/plain; charset=UTF-8 Hi Stefan, Generally speaking, this is a situation that you want to avoid. At 350 million files and 20 TB, you're looking at around 17-18 MB per file at minimum? That's pretty small. And with 350M files, a fair number of those 350M must be on the smaller side of things. Memory is cheap these days... people can make 50 GB, 100 GB, ... files, go ahead and read those things directly into memory, 100%. And CPU cycles are pretty cheap, too. Certainly you get more bang per buck there, than in IOPS on your storage system!! Empirically, I have found from experience (currently running Linux 3.4.61; many historical revs previous) in a reasonably large-scale (up to ~0.5 PB in single file system, up to 270 JBOD spindles on one machine) high-I/O (jobs running on a few-hundred-node compute cluster, or a few hundred threads running locally on the server) environment, that XFS (and things running on top of it, ESPECIALLY rsync) will perform MUCH better on smaller numbers of very large files, then they will on very large numbers of small files (I'm always trying to reinforce this to our end users). I'm not really even saying XFS is to really blame here... in fact in 3.4.61 it has been very well-behaved; but Linux has many warts: poor implementation of I/O and CPU scheduling algorithms; kernel does not degrade gracefully in resource-constrained settings; if you are ultimately using this data store as a file share, the protocol implementations have their own issues... NFS, CIFS, etc... Not trying to dog all the hardworking free software devs out there but clearly much work remains to be done in many areas, to make Linux really ready to play in the "big big leagues" of computing (unless you have a local staff of good systems programmers with some free time on their hands...). XFS is just one piece of the puzzle we have to work with in trying to integrate a Linux system as a good high-throughput storage machine. If there is any way that you can use simple catenation or some kind of archiver... even things as simple as shar, tar, zip... to get the file sizes up and the absolute number of files down, you should notice some big performance gains when trying to process your 20 TB worth of stuff. If you can't dramatically increase individual file size while dramatically reducing the absolute number of files for whatever reason in your environment, I think you can still win by trying to reduce the number of files in any one directory. You want to look out for directories that have five or six figures worth of files in them, those can be real performance killers. If your claim of no more than 5,000 files per any directory is accurate, that shouldn't be a big deal for XFS at all, I don't think you're in bad shape there. Rsync can be just the worst in this kind of scenario. It runs so slow, you feel sometimes like you might as well be on 10 Meg Ethernet (or worse). I'm not sure exactly what your application is here... It sounds backup related. If you're doing rsync, you can win a little bit by dropping down a level or two in your directory hierarchy from the top of the tree where XFS is mounted, and running a number of rsync threads in parallel, per-directory, instead of just one top-level rsync thread for an entire filesystem. Experiment to find the best number of threads; run too many and they can deadlock, or just step all over one another. Also, I have a suspicion (sorry can't back this up quantitatively) that if you are just trying to a straight copy from here to there, a 'cp -Rp' will be faster than an rsync. You might be better off doing an initial copy with 'cp -Rp' and then just synchronizing diffs at the end with an rsync pass, rather than trying to do the whole thing with rsync. Hope some of this might help... just casual thoughts from a daily XFS-wrangler ;) Best, Sean On Fri, Sep 5, 2014 at 5:24 PM, Brian Foster wrote: > On Fri, Sep 05, 2014 at 10:14:51PM +0200, Stefan Priebe wrote: > > > > Am 05.09.2014 21:18, schrieb Brian Foster: > > ... > > > > >On Fri, Sep 05, 2014 at 08:07:38PM +0200, Stefan Priebe wrote: > > >Interesting, that seems like a lot of free inodes. That's 1-2 million in > > >each AG that we have to look around for each time we want to allocate an > > >inode. I can't say for sure that's the source of the slowdown, but this > > >certainly looks like the kind of workload that inspired the addition of > > >the free inode btree (finobt) to more recent kernels. > > > > > >It appears that you still have quite a bit of space available in > > >general. Could you run some local tests on this filesystem to try and > > >quantify how much of this degradation manifests on sustained writes vs. > > >file creation? For example, how is throughput when writing a few GB to a > > >local test file? > > > > Not sure if this is what you expect: > > > > # dd if=/dev/zero of=bigfile oflag=direct,sync bs=4M count=1000 > > 1000+0 records in > > 1000+0 records out > > 4194304000 bytes (4,2 GB) copied, 125,809 s, 33,3 MB/s > > > > or without sync > > # dd if=/dev/zero of=bigfile oflag=direct bs=4M count=1000 > > 1000+0 records in > > 1000+0 records out > > 4194304000 bytes (4,2 GB) copied, 32,5474 s, 129 MB/s > > > > > How about with that same amount of data broken up > > >across a few thousand files? > > > > This results in heavy kworker usage. > > > > 4GB in 32kb files > > # time (mkdir test; for i in $(seq 1 1 131072); do dd if=/dev/zero > > of=test/$i bs=32k count=1 oflag=direct,sync 2>/dev/null; done) > > > > ... > > > > 55 min > > > > Both seem pretty slow in general. Any way you can establish a baseline > for these tests on this storage? If not, the only other suggestion I > could make is to allocate inodes until all of those freecount numbers > are accounted for and see if anything changes. That could certainly take > some time and it's not clear it will actually help. > > > >Brian > > > > > >P.S., Alternatively if you wanted to grab a metadump of this filesystem > > >and compress/upload it somewhere, I'd be interested to take a look at > > >it. > > > > I think there might be file and directory names in it. If this is the > case i > > can't do it. > > > > It should enable obfuscation by default, but I would suggest to restore > it yourself and verify it meets your expectations. > > Brian > > > Stefan > > > > > > > > > >>Thanks! > > >> > > >>Stefan > > >> > > >> > > >> > > >>>Brian > > >>> > > >>>>>... as well as what your typical workflow/dataset is for this fs. It > > >>>>>seems like you have relatively small files (15TB used across 350m > files > > >>>>>is around 46k per file), yes? > > >>>> > > >>>>Yes - most fo them are even smaller. And some files are > 5GB. > > >>>> > > >>>>>If so, I wonder if something like the > > >>>>>following commit introduced in 3.12 would help: > > >>>>> > > >>>>>133eeb17 xfs: don't use speculative prealloc for small files > > >>>> > > >>>>Looks interesting. > > >>>> > > >>>>Stefan > > > > _______________________________________________ > > xfs mailing list > > xfs@oss.sgi.com > > http://oss.sgi.com/mailman/listinfo/xfs > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs > --001a11c1f0da2a1c3e05025925d2 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi Stefan,

Generally speaking, th= is is a situation that you want to avoid. At 350 million files and 20 TB, y= ou're looking at around 17-18 MB per file at minimum? That's pretty= small. And with 350M files, a fair number of those 350M must be on the sma= ller side of things.

Memory is cheap these days... peopl= e can make 50 GB, 100 GB, ... files, go ahead and read those things directl= y into memory, 100%. And CPU cycles are pretty cheap, too. Certainly you ge= t more bang per buck there, than in IOPS on your storage system!!

Empirically, I have found from experience (currently runnin= g Linux 3.4.61; many historical revs previous) in a reasonably large-scale = (up to ~0.5 PB in single file system, up to 270 JBOD spindles on one machin= e) high-I/O (jobs running on a few-hundred-node compute cluster, or a few h= undred threads running locally on the server) environment, that XFS (and th= ings running on top of it, ESPECIALLY rsync) will perform MUCH better on sm= aller numbers of very large files, then they will on very large numbers of = small files (I'm always trying to reinforce this to our end users).

I'm not really even saying XFS is to really blame= here... in fact in 3.4.61 it has been very well-behaved; but Linux has man= y warts: poor implementation of I/O and CPU scheduling algorithms; kernel d= oes not degrade gracefully in resource-constrained settings; if you are ult= imately using this data store as a file share, the protocol implementations= have their own issues... NFS, CIFS, etc... Not trying to dog all the hardw= orking free software devs out there but clearly much work remains to be don= e in many areas, to make Linux really ready to play in the "big big le= agues" of computing (unless you have a local staff of good systems pro= grammers with some free time on their hands...). XFS is just one piece of t= he puzzle we have to work with in trying to integrate a Linux system as a g= ood high-throughput storage machine.

If there is a= ny way that you can use simple catenation or some kind of archiver... even = things as simple as shar, tar, zip... to get the file sizes up and the abso= lute number of files down, you should notice some big performance gains whe= n trying to process your 20 TB worth of stuff.

If = you can't dramatically increase individual file size while dramatically= reducing the absolute number of files for whatever reason in your environm= ent, I think you can still win by trying to reduce the number of files in a= ny one directory. You want to look out for directories that have five or si= x figures worth of files in them, those can be real performance killers. If= your claim of no more than 5,000 files per any directory is accurate, that= shouldn't be a big deal for XFS at all, I don't think you're i= n bad shape there.

Rsync can be just the worst in = this kind of scenario. It runs so slow, you feel sometimes like you might a= s well be on 10 Meg Ethernet (or worse).

I'm n= ot sure exactly what your application is here... It sounds backup related. = If you're doing rsync, you can win a little bit by dropping down a leve= l or two in your directory hierarchy from the top of the tree where XFS is = mounted, and running a number of rsync threads in parallel, per-directory, = instead of just one top-level rsync thread for an entire filesystem. Experi= ment to find the best number of threads; run too many and they can deadlock= , or just step all over one another.

Also, I have = a suspicion (sorry can't back this up quantitatively) that if you are j= ust trying to a straight copy from here to there, a 'cp -Rp' will b= e faster than an rsync. You might be better off doing an initial copy with = 'cp -Rp' and then just synchronizing diffs at the end with an rsync= pass, rather than trying to do the whole thing with rsync.

<= /div>
Hope some of this might help... just casual thoughts from a daily= XFS-wrangler ;)

Best,

Se= an



=
On Fri, Sep 5, 2014 at 5:24 PM, Brian Foster= <bfoster@redhat.com> wrote:
On Fri, Sep 05, 2014 at 10:14:5= 1PM +0200, Stefan Priebe wrote:
>
> Am 05.09.2014 21:18, schrieb Brian Foster:
> ...
>
> >On Fri, Sep 05, 2014 at 08:07:38PM +0200, Stefan Priebe wrote:
> >Interesting, that seems like a lot of free inodes. That's 1-2 = million in
> >each AG that we have to look around for each time we want to alloc= ate an
> >inode. I can't say for sure that's the source of the slowd= own, but this
> >certainly looks like the kind of workload that inspired the additi= on of
> >the free inode btree (finobt) to more recent kernels.
> >
> >It appears that you still have quite a bit of space available in > >general. Could you run some local tests on this filesystem to try = and
> >quantify how much of this degradation manifests on sustained write= s vs.
> >file creation? For example, how is throughput when writing a few G= B to a
> >local test file?
>
> Not sure if this is what you expect:
>
> # dd if=3D/dev/zero of=3Dbigfile oflag=3Ddirect,sync bs=3D4M count=3D1= 000
> 1000+0 records in
> 1000+0 records out
> 4194304000 bytes (4,2 GB) copied, 125,809 s, 33,3 MB/s
>
> or without sync
> # dd if=3D/dev/zero of=3Dbigfile oflag=3Ddirect bs=3D4M count=3D1000 > 1000+0 records in
> 1000+0 records out
> 4194304000 bytes (4,2 GB) copied, 32,5474 s, 129 MB/s
>
> > How about with that same amount of data broken up
> >across a few thousand files?
>
> This results in heavy kworker usage.
>
> 4GB in 32kb files
> # time (mkdir test; for i in $(seq 1 1 131072); do dd if=3D/dev/zero > of=3Dtest/$i bs=3D32k count=3D1 oflag=3Ddirect,sync 2>/dev/null; do= ne)
>
> ...
>
> 55 min
>

Both seem pretty slow in general. Any way you can establish a b= aseline
for these tests on this storage? If not, the only other suggestion I
could make is to allocate inodes until all of those freecount numbers
are accounted for and see if anything changes. That could certainly take some time and it's not clear it will actually help.

> >Brian
> >
> >P.S., Alternatively if you wanted to grab a metadump of this files= ystem
> >and compress/upload it somewhere, I'd be interested to take a = look at
> >it.
>
> I think there might be file and directory names in it. If this is the = case i
> can't do it.
>

It should enable obfuscation by default, but I would suggest to rest= ore
it yourself and verify it meets your expectations.

Brian

> Stefan
>
>
> >
> >>Thanks!
> >>
> >>Stefan
> >>
> >>
> >>
> >>>Brian
> >>>
> >>>>>... as well as what your typical workflow/dataset = is for this fs. It
> >>>>>seems like you have relatively small files (15TB u= sed across 350m files
> >>>>>is around 46k per file), yes?
> >>>>
> >>>>Yes - most fo them are even smaller. And some files ar= e > 5GB.
> >>>>
> >>>>>If so, I wonder if something like the
> >>>>>following commit introduced in 3.12 would help: > >>>>>
> >>>>>133eeb17 xfs: don't use speculative prealloc f= or small files
> >>>>
> >>>>Looks interesting.
> >>>>
> >>>>Stefan
>
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> = http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http:= //oss.sgi.com/mailman/listinfo/xfs

--001a11c1f0da2a1c3e05025925d2-- From david@fromorbit.com Fri Sep 5 18:05:37 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 0EE2D7F3F for ; Fri, 5 Sep 2014 18:05:37 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id D52CD30406A for ; Fri, 5 Sep 2014 16:05:33 -0700 (PDT) X-ASG-Debug-ID: 1409958330-04bdf0109a79e120001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id 4hMWMkGbO6q7jBJJ for ; Fri, 05 Sep 2014 16:05:31 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AixAANZAClR5LKYhPGdsb2JhbABagw2BKoIsrVcBAQEBAQEGmm+FaQEDAQEBgQMXBQEBAQE4NoQDAQEEATocIxAIAxgJJQ8FJQMHGhMbiB8Hvz8BFxiFZIhmIkkHhEwFnGuXDh6BbisvgQeBSAEBAQ Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 06 Sep 2014 08:35:29 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XQ2ZM-0002aT-8B; Sat, 06 Sep 2014 09:05:28 +1000 Date: Sat, 6 Sep 2014 09:05:28 +1000 From: Dave Chinner To: Stefan Priebe - Profihost AG Cc: Brian Foster , "xfs@oss.sgi.com" Subject: Re: Is XFS suitable for 350 million files on 20TB storage? Message-ID: <20140905230528.GO20473@dastard> X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? References: <540986B1.4080306@profihost.ag> <20140905123058.GA29710@bfoster.bfoster> <5409AF40.10801@profihost.ag> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5409AF40.10801@profihost.ag> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1409958331 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9216 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 05, 2014 at 02:40:32PM +0200, Stefan Priebe - Profihost AG wrote: > > Am 05.09.2014 um 14:30 schrieb Brian Foster: > > On Fri, Sep 05, 2014 at 11:47:29AM +0200, Stefan Priebe - Profihost AG wrote: > >> Hi, > >> > >> i have a backup system running 20TB of storage having 350 million files. > >> This was working fine for month. > >> > >> But now the free space is so heavily fragmented that i only see the > >> kworker with 4x 100% CPU and write speed beeing very slow. 15TB of the > >> 20TB are in use. What does perf tell you about the CPU being burnt? (i.e run perf top for 10-20s while that CPU burn is happening and paste the top 10 CPU consuming functions). > >> > >> Overall files are 350 Million - all in different directories. Max 5000 > >> per dir. > >> > >> Kernel is 3.10.53 and mount options are: > >> noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=256k,noquota > >> > >> # xfs_db -r -c freesp /dev/sda1 > >> from to extents blocks pct > >> 1 1 29484138 29484138 2,16 > >> 2 3 16930134 39834672 2,92 > >> 4 7 16169985 87877159 6,45 > >> 8 15 78202543 999838327 73,41 With an inode size of 256 bytes, this is going to be your real problem soon - most of the free space is smaller than an inode chunk so soon you won't be able to allocate new inodes, even though there is free space on disk. Unfortunately, there's not much we can do about this right now - we need development in both user and kernel space to mitigate this issue: spare inode chunk allocation in kernel space, and free space defragmentation in userspace. Both are on the near term development list.... Also, the fact that there are almost 80 million 8-15 block extents indicates that the CPU burn is likely coming from the by-size free space search. We look up the first extent of the correct size, and then do a linear search for a nearest extent of that size to the target. Hence we could be searching millions of extents to find the "nearest".... > >> 16 31 3562456 83746085 6,15 > >> 32 63 2370812 102124143 7,50 > >> 64 127 280885 18929867 1,39 > >> 256 511 2 827 0,00 > >> 512 1023 65 35092 0,00 > >> 2048 4095 2 6561 0,00 > >> 16384 32767 1 23951 0,00 > >> > >> Is there anything i can optimize? Or is it just a bad idea to do this > >> with XFS? No, it's not a bad idea. In fact, if you have this sort of use case, XFS is really your only choice. In terms of optimisation, the only thing that will really help performance is the new finobt structure. That's a mkfs option andnot an in-place change, though, so it's unlikely to help. FWIW, it may also help aging characteristics of this sort of workload by improving inode allocation layout. That would be a side effect of being able to search the entire free inode tree extremely quickly rather than allocating new chunks to keep CPU time searching the allocate inode tree for free inodes down. Hence it would tend to more tightly pack inode chunks when they are allocated on disk as it will fill full chunks before allocating new ones elsewhere. > >> Any other options? Maybe rsync options like --inplace / > >> --no-whole-file? For 350M files? I doubt there's much you can really do. Any sort of large scale re-organisation is going to take a long, long time and require lots of IO. If you are goign to take that route, you'd do better to upgrade kernel and xfsprogs, then dump/mkfs.xfs -m crc=1,finobt=1/restore. And you'd probably want to use a multi-stream dump/restore so it can run operations concurrently and hence at storage speed rather than being CPU bound.... Also, if the problem really is the number of indentically sized free space fragments in the freespace btrees, then the initial solution is, again, a mkfs one. i.e. remake the filesystem with more, smaller AGs to keep the number of extents the btrees need to index down to a reasonable level. Say a couple of hundred AGs rather than 21? > > If so, I wonder if something like the > > following commit introduced in 3.12 would help: > > > > 133eeb17 xfs: don't use speculative prealloc for small files > > Looks interesting. Probably won't make any difference because backups via rsync do open/write/close and don't touch the file data again, so the close will be removing speculative preallocation before the data is written and extents are allocated by background writeback.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Fri Sep 5 19:07:20 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B5E5C7F3F for ; Fri, 5 Sep 2014 19:07:20 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 94F168F8049 for ; Fri, 5 Sep 2014 17:07:17 -0700 (PDT) X-ASG-Debug-ID: 1409962034-04cb6c55007ff490001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id QtFNWSZtAdCndWir for ; Fri, 05 Sep 2014 17:07:15 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AmZAAAlPClR5LKYhPGdsb2JhbABagw0gM1eCLK1XAQEBAQEBBgWZAwKBZYVpAQMBAYEEFwUBAQEBODaERBwjGCQ0BSUDBy2IQb9bGIVkiVEdgiIPRIFBBYUKgRCOd12GfZkaKy+CTwEBAQ Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 06 Sep 2014 09:37:14 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XQ3X5-0002oD-JK; Sat, 06 Sep 2014 10:07:11 +1000 Date: Sat, 6 Sep 2014 10:07:11 +1000 From: Dave Chinner To: torvalds@linux-foundation.org Cc: akpm@linux-foundation.org, linux-kernel@vger.kernel.org, xfs@oss.sgi.com Subject: [GIT PULL] xfs: fixes for 3.17-rc3 Message-ID: <20140906000711.GX20518@dastard> X-ASG-Orig-Subj: [GIT PULL] xfs: fixes for 3.17-rc3 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1409962034 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9217 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Hi Linus, Can you please pull the following XFS fixes? The fixes all address recently discovered data corruption issues. The original Direct IO issue was discovered by Chris Mason @ Facebook on a production workload which mixed buffered reads with direct reads and writes IO to the same file. The fix for that exposed other issues with page invalidation (exposed by millions of fsx operations) failing due to dirty buffers beyond EOF. Finally, the collapse_range code could also cause problems due to racing writeback changing the extent map while it was being shifted around. The commits for that problem are simple mitigation fixes that prevent the problem from occuring. A more robust fix for 3.18 that addresses the underlying problem is currently being worked on by Brian. -Dave. The following changes since commit 52addcf9d6669fa439387610bc65c92fa0980cef: Linux 3.17-rc2 (2014-08-25 15:36:20 -0700) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs tags/xfs-for-linus-3.17-rc3 for you to fetch changes up to 41b9d7263ea1e270019c5d04fa0ab15db50b9725: xfs: trim eofblocks before collapse range (2014-09-02 12:12:53 +1000) ---------------------------------------------------------------- xfs: fixes for v3.17-rc3 Fix: - a direct IO read/buffered read data corruption - the associated fallout from the DIO data corruption fix - collapse range bugs that are potential data corruption issues. ---------------------------------------------------------------- Brian Foster (2): xfs: don't log inode unless extent shift makes extent modifications xfs: trim eofblocks before collapse range Chris Mason (1): xfs: don't zero partial page cache pages during O_DIRECT writes Dave Chinner (4): xfs: don't dirty buffers beyond EOF xfs: don't zero partial page cache pages during O_DIRECT writes xfs: use ranged writeback and invalidation for direct IO xfs: xfs_file_collapse_range is delalloc challenged fs/xfs/libxfs/xfs_bmap.c | 18 ++++++++------ fs/xfs/xfs_aops.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_bmap_util.c | 20 +++++++++++++++ fs/xfs/xfs_file.c | 27 +++++++++++++++++--- 4 files changed, 114 insertions(+), 12 deletions(-) -- Dave Chinner david@fromorbit.com From s.priebe@profihost.ag Sat Sep 6 02:35:17 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 03F4F7F3F for ; Sat, 6 Sep 2014 02:35:17 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id A2564AC002 for ; Sat, 6 Sep 2014 00:35:13 -0700 (PDT) X-ASG-Debug-ID: 1409988910-04bdf010a17ab910001-NocioJ Received: from mail-ph.de-nserver.de (mail-ph.de-nserver.de [85.158.179.214]) by cuda.sgi.com with ESMTP id 2jqSs9RxSdVN8xfq (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sat, 06 Sep 2014 00:35:11 -0700 (PDT) X-Barracuda-Envelope-From: s.priebe@profihost.ag X-Barracuda-Apparent-Source-IP: 85.158.179.214 Received: (qmail 29820 invoked from network); 6 Sep 2014 09:35:09 +0200 X-Fcrdns: No Received: from phoffice.de-nserver.de (HELO [10.242.2.6]) (185.39.223.5) (smtp-auth username s.priebe@profihost.ag, mechanism plain) by mail-ph.de-nserver.de (qpsmtpd/0.92) with (ECDHE-RSA-AES256-SHA encrypted) ESMTPSA; Sat, 06 Sep 2014 09:35:09 +0200 Message-ID: <540AB933.4030707@profihost.ag> Date: Sat, 06 Sep 2014 09:35:15 +0200 From: Stefan Priebe User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: Dave Chinner CC: Brian Foster , "xfs@oss.sgi.com" Subject: Re: Is XFS suitable for 350 million files on 20TB storage? References: <540986B1.4080306@profihost.ag> <20140905123058.GA29710@bfoster.bfoster> <5409AF40.10801@profihost.ag> <20140905230528.GO20473@dastard> X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? In-Reply-To: <20140905230528.GO20473@dastard> Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit X-User-Auth: Auth by s.priebe@profihost.ag through 185.39.223.5 X-Barracuda-Connect: mail-ph.de-nserver.de[85.158.179.214] X-Barracuda-Start-Time: 1409988910 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9225 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi Dave, Am 06.09.2014 01:05, schrieb Dave Chinner: > On Fri, Sep 05, 2014 at 02:40:32PM +0200, Stefan Priebe - Profihost AG wrote: >> >> Am 05.09.2014 um 14:30 schrieb Brian Foster: >>> On Fri, Sep 05, 2014 at 11:47:29AM +0200, Stefan Priebe - Profihost AG wrote: >>>> Hi, >>>> >>>> i have a backup system running 20TB of storage having 350 million files. >>>> This was working fine for month. >>>> >>>> But now the free space is so heavily fragmented that i only see the >>>> kworker with 4x 100% CPU and write speed beeing very slow. 15TB of the >>>> 20TB are in use. > > What does perf tell you about the CPU being burnt? (i.e run perf top > for 10-20s while that CPU burn is happening and paste the top 10 CPU > consuming functions). here we go: 15,79% [kernel] [k] xfs_inobt_get_rec 14,57% [kernel] [k] xfs_btree_get_rec 10,37% [kernel] [k] xfs_btree_increment 7,20% [kernel] [k] xfs_btree_get_block 6,13% [kernel] [k] xfs_btree_rec_offset 4,90% [kernel] [k] xfs_dialloc_ag 3,53% [kernel] [k] xfs_btree_readahead 2,87% [kernel] [k] xfs_btree_rec_addr 2,80% [kernel] [k] _xfs_buf_find 1,94% [kernel] [k] intel_idle 1,49% [kernel] [k] _raw_spin_lock 1,13% [kernel] [k] copy_pte_range 1,10% [kernel] [k] unmap_single_vma >>>> >>>> Overall files are 350 Million - all in different directories. Max 5000 >>>> per dir. >>>> >>>> Kernel is 3.10.53 and mount options are: >>>> noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=256k,noquota >>>> >>>> # xfs_db -r -c freesp /dev/sda1 >>>> from to extents blocks pct >>>> 1 1 29484138 29484138 2,16 >>>> 2 3 16930134 39834672 2,92 >>>> 4 7 16169985 87877159 6,45 >>>> 8 15 78202543 999838327 73,41 > > With an inode size of 256 bytes, this is going to be your real > problem soon - most of the free space is smaller than an inode > chunk so soon you won't be able to allocate new inodes, even though > there is free space on disk. > > Unfortunately, there's not much we can do about this right now - we > need development in both user and kernel space to mitigate this > issue: spare inode chunk allocation in kernel space, and free space > defragmentation in userspace. Both are on the near term development > list.... > > Also, the fact that there are almost 80 million 8-15 block extents > indicates that the CPU burn is likely coming from the by-size free > space search. We look up the first extent of the correct size, and > then do a linear search for a nearest extent of that size to the > target. Hence we could be searching millions of extents to find the > "nearest".... > >>>> 16 31 3562456 83746085 6,15 >>>> 32 63 2370812 102124143 7,50 >>>> 64 127 280885 18929867 1,39 >>>> 256 511 2 827 0,00 >>>> 512 1023 65 35092 0,00 >>>> 2048 4095 2 6561 0,00 >>>> 16384 32767 1 23951 0,00 >>>> >>>> Is there anything i can optimize? Or is it just a bad idea to do this >>>> with XFS? > > No, it's not a bad idea. In fact, if you have this sort of use case, > XFS is really your only choice. In terms of optimisation, the only > thing that will really help performance is the new finobt structure. > That's a mkfs option andnot an in-place change, though, so it's > unlikely to help. I've no problem with reformatting the array. I've more backups. > FWIW, it may also help aging characteristics of this sort of > workload by improving inode allocation layout. That would be > a side effect of being able to search the entire free inode tree > extremely quickly rather than allocating new chunks to keep CPU time > searching the allocate inode tree for free inodes down. Hence it > would tend to more tightly pack inode chunks when they are allocated > on disk as it will fill full chunks before allocating new ones > elsewhere. > >>>> Any other options? Maybe rsync options like --inplace / >>>> --no-whole-file? > > For 350M files? I doubt there's much you can really do. Any sort of > large scale re-organisation is going to take a long, long time and > require lots of IO. If you are goign to take that route, you'd do > better to upgrade kernel and xfsprogs, then dump/mkfs.xfs -m > crc=1,finobt=1/restore. And you'd probably want to use a > multi-stream dump/restore so it can run operations concurrently and > hence at storage speed rather than being CPU bound.... I don't need a backup reformatting is possible but i really would like to stay at 3.10. Is there anything i can backport or do i really need to upgrade? Which version at least? > Also, if the problem really is the number of indentically sized free > space fragments in the freespace btrees, then the initial solution > is, again, a mkfs one. i.e. remake the filesystem with more, smaller > AGs to keep the number of extents the btrees need to index down to a > reasonable level. Say a couple of hundred AGs rather than 21? mkfs has chosen 21 automagically - it's nothing i've set. Is this a bug or do i just need it cause of my special use case. Thanks! Stefan >>> If so, I wonder if something like the >>> following commit introduced in 3.12 would help: >>> >>> 133eeb17 xfs: don't use speculative prealloc for small files >> >> Looks interesting. > > Probably won't make any difference because backups via rsync do > open/write/close and don't touch the file data again, so the close > will be removing speculative preallocation before the data is > written and extents are allocated by background writeback.... > > Cheers, > > Dave. > From shenjqb@online.sh.cn Sat Sep 6 09:01:25 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: * X-Spam-Status: No, score=1.7 required=5.0 tests=DATE_IN_PAST_06_12, HTML_MESSAGE,MIME_QP_LONG_LINE,TVD_SPACE_RATIO,T_TVD_MIME_EPI autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 1CD0C7F3F for ; Sat, 6 Sep 2014 09:01:25 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id F0BC38F8049 for ; Sat, 6 Sep 2014 07:01:21 -0700 (PDT) X-ASG-Debug-ID: 1410012077-04cb6c54fd8103b0001-NocioJ Received: from mail.online.sh.cn (wg1.online.sh.cn [61.152.74.17]) by cuda.sgi.com with SMTP id 5g0eCEkxGCNo1Idl for ; Sat, 06 Sep 2014 07:01:17 -0700 (PDT) X-Barracuda-Envelope-From: shenjqb@online.sh.cn X-Barracuda-Apparent-Source-IP: 61.152.74.17 Received: from [95.180.42.194] by mail.online.sh.cn with messagesec esmtp id 6112319180464484; Sat, 6 Sep 2014 22:01:13 +0800 (CST) Message-ID: From: info To: "weblog" , "webshep2" , "welchm" , "WENDY" , "WENDY GONZALEZ" , "wendy" , "wgarrow" , "whanright" , "Whittier School" , "wigt" , "william" , "winona autry" , "wmillimen" , "wmson" , "wppresby church" , "wrwest" , "wsa24" , "wunbusymom" , "xfs" , "yangsha460" Subject: from info@recycleforschools.com Date: Fri, 6 Sep 2014 03:01:08 +0000 X-ASG-Orig-Subj: from info@recycleforschools.com MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_13AF_AF5BAACD.72CA8743" X-Mailer: iPhone Mail (11D201) X-Barracuda-Connect: wg1.online.sh.cn[61.152.74.17] X-Barracuda-Start-Time: 1410012077 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 2.13 X-Barracuda-Spam-Status: No, SCORE=2.13 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, DATE_IN_PAST_06_12, DATE_IN_PAST_06_12_2, HTML_MESSAGE, MIME_QP_LONG_LINE, MIME_QP_LONG_LINE_2, PR0N_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9231 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.01 DATE_IN_PAST_06_12 Date: is 6 to 12 hours before Received: date 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 MIME_QP_LONG_LINE RAW: Quoted-printable line longer than 76 chars 0.82 MIME_QP_LONG_LINE_2 RAW: Quoted-printable line longer than 76 chars 0.20 PR0N_SUBJECT Subject has letters around special characters (pr0n) 1.10 DATE_IN_PAST_06_12_2 DATE_IN_PAST_06_12_2 This is a multi-part message in MIME format. ------=_NextPart_000_13AF_AF5BAACD.72CA8743 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hi! News: http://latintour.pl/x/would.php?gls info@recycleforschools.com ------=_NextPart_000_13AF_AF5BAACD.72CA8743 Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable Hi!

News: http://latintour.pl/x/would.php?gls

info@recycleforschools.com
------=_NextPart_000_13AF_AF5BAACD.72CA8743-- Thread-Index: AUhyRRAY7WJ0aGo1c3BkaHk2OXBtMg== From bfoster@redhat.com Sat Sep 6 09:51:21 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 2ED9C7F3F for ; Sat, 6 Sep 2014 09:51:21 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id A2C59AC004 for ; Sat, 6 Sep 2014 07:51:17 -0700 (PDT) X-ASG-Debug-ID: 1410015075-04cb6c54fd8114e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ZyBtBGZbXqtNNTwJ (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sat, 06 Sep 2014 07:51:16 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s86Ep79N027962 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Sat, 6 Sep 2014 10:51:07 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s86Ep6Yv007460; Sat, 6 Sep 2014 10:51:07 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id B21951256F8; Sat, 6 Sep 2014 10:51:05 -0400 (EDT) Date: Sat, 6 Sep 2014 10:51:05 -0400 From: Brian Foster To: Dave Chinner Cc: Stefan Priebe - Profihost AG , "xfs@oss.sgi.com" Subject: Re: Is XFS suitable for 350 million files on 20TB storage? Message-ID: <20140906145105.GA23506@bfoster.bfoster> X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? References: <540986B1.4080306@profihost.ag> <20140905123058.GA29710@bfoster.bfoster> <5409AF40.10801@profihost.ag> <20140905230528.GO20473@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140905230528.GO20473@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410015075 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Sat, Sep 06, 2014 at 09:05:28AM +1000, Dave Chinner wrote: > On Fri, Sep 05, 2014 at 02:40:32PM +0200, Stefan Priebe - Profihost AG wrote: > > > > Am 05.09.2014 um 14:30 schrieb Brian Foster: > > > On Fri, Sep 05, 2014 at 11:47:29AM +0200, Stefan Priebe - Profihost AG wrote: > > >> Hi, > > >> > > >> i have a backup system running 20TB of storage having 350 million files. > > >> This was working fine for month. > > >> > > >> But now the free space is so heavily fragmented that i only see the > > >> kworker with 4x 100% CPU and write speed beeing very slow. 15TB of the > > >> 20TB are in use. > > What does perf tell you about the CPU being burnt? (i.e run perf top > for 10-20s while that CPU burn is happening and paste the top 10 CPU > consuming functions). > > > >> > > >> Overall files are 350 Million - all in different directories. Max 5000 > > >> per dir. > > >> > > >> Kernel is 3.10.53 and mount options are: > > >> noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=256k,noquota > > >> > > >> # xfs_db -r -c freesp /dev/sda1 > > >> from to extents blocks pct > > >> 1 1 29484138 29484138 2,16 > > >> 2 3 16930134 39834672 2,92 > > >> 4 7 16169985 87877159 6,45 > > >> 8 15 78202543 999838327 73,41 > > With an inode size of 256 bytes, this is going to be your real > problem soon - most of the free space is smaller than an inode > chunk so soon you won't be able to allocate new inodes, even though > there is free space on disk. > The extent list here is in fsb units, right? 256b inodes means 16k inode chunks, in which case it seems like there's still plenty of room for inode chunks (e.g., 8-15 blocks -> 32k-64k). If you're at 350m inodes for 15T with 5T to go, that's 23.3m inodes per TB and extrapolates to ~117m more to enospc. That's 1.8m inode chunks out of the ~80m 8-15 block records currently free, and doesn't count the 20+ million inodes that seem to be scattered about the existing records as well. I certainly could be missing something here, but it seems like premature enospc due to inode chunk allocation failure might not be an impending problem here (likely due to using the smallest inode size, the risk seems to increase much more using the larger inode sizes)... > Unfortunately, there's not much we can do about this right now - we > need development in both user and kernel space to mitigate this > issue: spare inode chunk allocation in kernel space, and free space > defragmentation in userspace. Both are on the near term development > list.... > > Also, the fact that there are almost 80 million 8-15 block extents > indicates that the CPU burn is likely coming from the by-size free > space search. We look up the first extent of the correct size, and > then do a linear search for a nearest extent of that size to the > target. Hence we could be searching millions of extents to find the > "nearest".... > > > >> 16 31 3562456 83746085 6,15 > > >> 32 63 2370812 102124143 7,50 > > >> 64 127 280885 18929867 1,39 > > >> 256 511 2 827 0,00 > > >> 512 1023 65 35092 0,00 > > >> 2048 4095 2 6561 0,00 > > >> 16384 32767 1 23951 0,00 > > >> > > >> Is there anything i can optimize? Or is it just a bad idea to do this > > >> with XFS? > > No, it's not a bad idea. In fact, if you have this sort of use case, > XFS is really your only choice. In terms of optimisation, the only > thing that will really help performance is the new finobt structure. > That's a mkfs option andnot an in-place change, though, so it's > unlikely to help. > > FWIW, it may also help aging characteristics of this sort of > workload by improving inode allocation layout. That would be > a side effect of being able to search the entire free inode tree > extremely quickly rather than allocating new chunks to keep CPU time > searching the allocate inode tree for free inodes down. Hence it > would tend to more tightly pack inode chunks when they are allocated > on disk as it will fill full chunks before allocating new ones > elsewhere. > > > >> Any other options? Maybe rsync options like --inplace / > > >> --no-whole-file? > > For 350M files? I doubt there's much you can really do. Any sort of > large scale re-organisation is going to take a long, long time and > require lots of IO. If you are goign to take that route, you'd do > better to upgrade kernel and xfsprogs, then dump/mkfs.xfs -m > crc=1,finobt=1/restore. And you'd probably want to use a > multi-stream dump/restore so it can run operations concurrently and > hence at storage speed rather than being CPU bound.... > > Also, if the problem really is the number of indentically sized free > space fragments in the freespace btrees, then the initial solution > is, again, a mkfs one. i.e. remake the filesystem with more, smaller > AGs to keep the number of extents the btrees need to index down to a > reasonable level. Say a couple of hundred AGs rather than 21? > > > > If so, I wonder if something like the > > > following commit introduced in 3.12 would help: > > > > > > 133eeb17 xfs: don't use speculative prealloc for small files > > > > Looks interesting. > > Probably won't make any difference because backups via rsync do > open/write/close and don't touch the file data again, so the close > will be removing speculative preallocation before the data is > written and extents are allocated by background writeback.... > Yeah, good point. I was curious if there was an fsync involved somewhere in the sequence here, but I didn't see rsync doing that anywhere. I think we've seen that contribute to the aforementioned inode chunk allocation problem when mixed with aggressive prealloc, but that was a different application (openstack related, iirc). That said, Stefan did mention that rsync can do file updates here. So perhaps there exists the possibility to see multiple file extensions and writeback causing a similar kind of prealloc->convert->trim eofblocks pattern across multiple backups..? Either way I agree that seems much less likely to be a prominent contributer to the problem here. Brian > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Sat Sep 6 10:04:21 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6310F7F3F for ; Sat, 6 Sep 2014 10:04:21 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 261A9304043 for ; Sat, 6 Sep 2014 08:04:17 -0700 (PDT) X-ASG-Debug-ID: 1410015856-04bdf010977b4fb0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id yNJraELWVh2nXu45 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sat, 06 Sep 2014 08:04:16 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s86F4Ej9016132 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Sat, 6 Sep 2014 11:04:14 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s86F4Eip010115; Sat, 6 Sep 2014 11:04:14 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 3E59C1256F8; Sat, 6 Sep 2014 11:04:13 -0400 (EDT) Date: Sat, 6 Sep 2014 11:04:13 -0400 From: Brian Foster To: Stefan Priebe Cc: Dave Chinner , "xfs@oss.sgi.com" Subject: Re: Is XFS suitable for 350 million files on 20TB storage? Message-ID: <20140906150412.GB23506@bfoster.bfoster> X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? References: <540986B1.4080306@profihost.ag> <20140905123058.GA29710@bfoster.bfoster> <5409AF40.10801@profihost.ag> <20140905230528.GO20473@dastard> <540AB933.4030707@profihost.ag> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540AB933.4030707@profihost.ag> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410015856 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Sat, Sep 06, 2014 at 09:35:15AM +0200, Stefan Priebe wrote: > Hi Dave, > > Am 06.09.2014 01:05, schrieb Dave Chinner: > >On Fri, Sep 05, 2014 at 02:40:32PM +0200, Stefan Priebe - Profihost AG wrote: > >> > >>Am 05.09.2014 um 14:30 schrieb Brian Foster: > >>>On Fri, Sep 05, 2014 at 11:47:29AM +0200, Stefan Priebe - Profihost AG wrote: > >>>>Hi, > >>>> > >>>>i have a backup system running 20TB of storage having 350 million files. > >>>>This was working fine for month. > >>>> > >>>>But now the free space is so heavily fragmented that i only see the > >>>>kworker with 4x 100% CPU and write speed beeing very slow. 15TB of the > >>>>20TB are in use. > > > >What does perf tell you about the CPU being burnt? (i.e run perf top > >for 10-20s while that CPU burn is happening and paste the top 10 CPU > >consuming functions). > > here we go: > 15,79% [kernel] [k] xfs_inobt_get_rec > 14,57% [kernel] [k] xfs_btree_get_rec > 10,37% [kernel] [k] xfs_btree_increment > 7,20% [kernel] [k] xfs_btree_get_block > 6,13% [kernel] [k] xfs_btree_rec_offset > 4,90% [kernel] [k] xfs_dialloc_ag > 3,53% [kernel] [k] xfs_btree_readahead > 2,87% [kernel] [k] xfs_btree_rec_addr > 2,80% [kernel] [k] _xfs_buf_find > 1,94% [kernel] [k] intel_idle > 1,49% [kernel] [k] _raw_spin_lock > 1,13% [kernel] [k] copy_pte_range > 1,10% [kernel] [k] unmap_single_vma > The top 6 or so items look related to inode allocation, so that probably confirms the primary bottleneck as searching around for free inodes out of the existing inode chunks, precisely what the finobt is intended to resolve. That was introduced in 3.16 kernels, so unfortunately it is not available in 3.10. Brian > >>>> > >>>>Overall files are 350 Million - all in different directories. Max 5000 > >>>>per dir. > >>>> > >>>>Kernel is 3.10.53 and mount options are: > >>>>noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=256k,noquota > >>>> > >>>># xfs_db -r -c freesp /dev/sda1 > >>>> from to extents blocks pct > >>>> 1 1 29484138 29484138 2,16 > >>>> 2 3 16930134 39834672 2,92 > >>>> 4 7 16169985 87877159 6,45 > >>>> 8 15 78202543 999838327 73,41 > > > >With an inode size of 256 bytes, this is going to be your real > >problem soon - most of the free space is smaller than an inode > >chunk so soon you won't be able to allocate new inodes, even though > >there is free space on disk. > > > >Unfortunately, there's not much we can do about this right now - we > >need development in both user and kernel space to mitigate this > >issue: spare inode chunk allocation in kernel space, and free space > >defragmentation in userspace. Both are on the near term development > >list.... > > > >Also, the fact that there are almost 80 million 8-15 block extents > >indicates that the CPU burn is likely coming from the by-size free > >space search. We look up the first extent of the correct size, and > >then do a linear search for a nearest extent of that size to the > >target. Hence we could be searching millions of extents to find the > >"nearest".... > > > >>>> 16 31 3562456 83746085 6,15 > >>>> 32 63 2370812 102124143 7,50 > >>>> 64 127 280885 18929867 1,39 > >>>> 256 511 2 827 0,00 > >>>> 512 1023 65 35092 0,00 > >>>> 2048 4095 2 6561 0,00 > >>>> 16384 32767 1 23951 0,00 > >>>> > >>>>Is there anything i can optimize? Or is it just a bad idea to do this > >>>>with XFS? > > > >No, it's not a bad idea. In fact, if you have this sort of use case, > >XFS is really your only choice. In terms of optimisation, the only > >thing that will really help performance is the new finobt structure. > >That's a mkfs option andnot an in-place change, though, so it's > >unlikely to help. > > I've no problem with reformatting the array. I've more backups. > > >FWIW, it may also help aging characteristics of this sort of > >workload by improving inode allocation layout. That would be > >a side effect of being able to search the entire free inode tree > >extremely quickly rather than allocating new chunks to keep CPU time > >searching the allocate inode tree for free inodes down. Hence it > >would tend to more tightly pack inode chunks when they are allocated > >on disk as it will fill full chunks before allocating new ones > >elsewhere. > > > >>>>Any other options? Maybe rsync options like --inplace / > >>>>--no-whole-file? > > > >For 350M files? I doubt there's much you can really do. Any sort of > >large scale re-organisation is going to take a long, long time and > >require lots of IO. If you are goign to take that route, you'd do > >better to upgrade kernel and xfsprogs, then dump/mkfs.xfs -m > >crc=1,finobt=1/restore. And you'd probably want to use a > >multi-stream dump/restore so it can run operations concurrently and > >hence at storage speed rather than being CPU bound.... > > I don't need a backup reformatting is possible but i really would like to > stay at 3.10. Is there anything i can backport or do i really need to > upgrade? Which version at least? > > >Also, if the problem really is the number of indentically sized free > >space fragments in the freespace btrees, then the initial solution > >is, again, a mkfs one. i.e. remake the filesystem with more, smaller > >AGs to keep the number of extents the btrees need to index down to a > >reasonable level. Say a couple of hundred AGs rather than 21? > > mkfs has chosen 21 automagically - it's nothing i've set. Is this a bug or > do i just need it cause of my special use case. > > Thanks! > > Stefan > > >>>If so, I wonder if something like the > >>>following commit introduced in 3.12 would help: > >>> > >>>133eeb17 xfs: don't use speculative prealloc for small files > >> > >>Looks interesting. > > > >Probably won't make any difference because backups via rsync do > >open/write/close and don't touch the file data again, so the close > >will be removing speculative preallocation before the data is > >written and extents are allocated by background writeback.... > > > >Cheers, > > > >Dave. > > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From sandeen@sandeen.net Sat Sep 6 12:25:48 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E78717F3F for ; Sat, 6 Sep 2014 12:25:48 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id C70DE8F8035 for ; Sat, 6 Sep 2014 10:25:45 -0700 (PDT) X-ASG-Debug-ID: 1410024343-04bdf010a07b7fa0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id oxJxtMyqqhALA54o for ; Sat, 06 Sep 2014 10:25:43 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 39C8760FCA5C for ; Sat, 6 Sep 2014 12:25:43 -0500 (CDT) Message-ID: <540B4399.4020804@sandeen.net> Date: Sat, 06 Sep 2014 12:25:45 -0500 From: Eric Sandeen MIME-Version: 1.0 To: xfs-oss Subject: [PATCH 0/2] xfsprogs: xfs_db crc fixes/changes Content-Type: text/plain; charset=ISO-8859-1; format=flowed X-ASG-Orig-Subj: [PATCH 0/2] xfsprogs: xfs_db crc fixes/changes Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410024343 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9235 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 2 patches related to crcs in xfs_db, 1) display inode CRC status when read, and revalidate it when written 2) add a new "crc" command to validate, invalidate, or revalidate the CRC on a disk structure thanks, -Eric From sandeen@sandeen.net Sat Sep 6 12:46:10 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 7FFF77F3F for ; Sat, 6 Sep 2014 12:46:10 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6EDF28F8039 for ; Sat, 6 Sep 2014 10:46:10 -0700 (PDT) X-ASG-Debug-ID: 1410025565-04cbb05486a9fbb0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id kypjftlLYLYIsGx3 for ; Sat, 06 Sep 2014 10:46:06 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 3974A60FCA5B for ; Sat, 6 Sep 2014 12:46:05 -0500 (CDT) Message-ID: <540B485F.8070502@sandeen.net> Date: Sat, 06 Sep 2014 12:46:07 -0500 From: Eric Sandeen MIME-Version: 1.0 To: xfs-oss Subject: [PATCH 1/2] xfs_db: fix inode CRC validity state, and warn on read if invalid References: <540B4399.4020804@sandeen.net> X-ASG-Orig-Subj: [PATCH 1/2] xfs_db: fix inode CRC validity state, and warn on read if invalid In-Reply-To: <540B4399.4020804@sandeen.net> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410025565 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9235 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Currently, the "ino_crc_ok" field on the io cursor reflects overall inode validity, not CRC correctness. Because it is only used when printing CRC validity, change it to reflect only that. In addition, when reading an inode, print the current CRC state. Note, if specifying an inode which doesn't actually exist, this will claim corruption; I'm not sure if that's good or bad. Today, it already issues corruption errors on the way; this adds a new message as well ;) xfs_db> inode 129 Metadata corruption detected at block 0x80/0x2000 Metadata corruption detected at block 0x80/0x2000 ... Metadata CRC error detected for ino 129 Signed-off-by: Eric Sandeen --- diff --git a/db/inode.c b/db/inode.c index 24170ba..244d03b 100644 --- a/db/inode.c +++ b/db/inode.c @@ -684,13 +684,18 @@ set_cur_inode( numblks, DB_RING_IGN, NULL); off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize); dip = iocur_top->data; - iocur_top->ino_crc_ok = libxfs_dinode_verify(mp, ino, dip); + iocur_top->ino_crc_ok = xfs_verify_cksum((char *)dip, + mp->m_sb.sb_inodesize, + XFS_DINODE_CRC_OFF); iocur_top->ino_buf = 1; iocur_top->ino = ino; iocur_top->mode = be16_to_cpu(dip->di_mode); if ((iocur_top->mode & S_IFMT) == S_IFDIR) iocur_top->dirino = ino; + if (xfs_sb_version_hascrc(&mp->m_sb) && !iocur_top->ino_crc_ok) + dbprintf(_("Metadata CRC error detected for ino %lld\n"), ino); + /* track updated info in ring */ ring_add(); } diff --git a/db/io.c b/db/io.c index 7f1b76a..93ebf5c 100644 --- a/db/io.c +++ b/db/io.c @@ -473,6 +473,17 @@ write_cur(void) write_cur_bbs(); else write_cur_buf(); + + if (iocur_top->ino_buf) { + xfs_dinode_t *dip; + xfs_ino_t ino; + + dip = iocur_top->data; + ino = iocur_top->ino; + iocur_top->ino_crc_ok = xfs_verify_cksum((char *)dip, + mp->m_sb.sb_inodesize, + XFS_DINODE_CRC_OFF); + } } void From sandeen@sandeen.net Sat Sep 6 12:52:35 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 32ACC7F3F for ; Sat, 6 Sep 2014 12:52:35 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id A1032AC001 for ; Sat, 6 Sep 2014 10:52:31 -0700 (PDT) X-ASG-Debug-ID: 1410025949-04cb6c54fd8154b0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id 6D0aGRqNlwKuLoUt for ; Sat, 06 Sep 2014 10:52:29 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 0772D60FCA5C for ; Sat, 6 Sep 2014 12:52:28 -0500 (CDT) Message-ID: <540B49DF.8000404@sandeen.net> Date: Sat, 06 Sep 2014 12:52:31 -0500 From: Eric Sandeen MIME-Version: 1.0 To: xfs-oss Subject: [PATCH 2/2] xfsprogs: xfs_db: add crc manipulation commands References: <540B4399.4020804@sandeen.net> X-ASG-Orig-Subj: [PATCH 2/2] xfsprogs: xfs_db: add crc manipulation commands In-Reply-To: <540B4399.4020804@sandeen.net> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410025949 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9235 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This adds a new "crc" command to xfs_db for CRC-enabled filesystems. If a structure has a CRC field, we can validate it, invalidate/corrupt it, or revalidate/rewrite it: xfs_db> sb 0 xfs_db> crc -v crc = 0x796c814f (correct) xfs_db> crc -i Metadata CRC error detected at block 0x0/0x200 crc = 0x796c8150 (bad) xfs_db> crc -r crc = 0x796c814f (correct) This requires temporarily replacing the write verifier with a dummy which won't recalculate the CRC on the way to disk. It also required me to write a new flist function, which is totally foreign to me, so hopefully done right - but it seems to work here. Signed-off-by: Eric Sandeen --- diff --git a/db/Makefile b/db/Makefile index bae6154..f0175cc 100644 --- a/db/Makefile +++ b/db/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_db HFILES = addr.h agf.h agfl.h agi.h attr.h attrshort.h bit.h block.h bmap.h \ - btblock.h bmroot.h check.h command.h convert.h debug.h \ + btblock.h bmroot.h check.h command.h convert.h crc.h debug.h \ dir2.h dir2sf.h dquot.h echo.h faddr.h field.h \ flist.h fprint.h frag.h freesp.h hash.h help.h init.h inode.h input.h \ io.h malloc.h metadump.h output.h print.h quit.h sb.h sig.h strvec.h \ diff --git a/db/command.c b/db/command.c index b7e3165..d44e0a5 100644 --- a/db/command.c +++ b/db/command.c @@ -48,6 +48,7 @@ #include "write.h" #include "malloc.h" #include "dquot.h" +#include "crc.h" cmdinfo_t *cmdtab; int ncmds; @@ -123,6 +124,7 @@ init_commands(void) bmap_init(); check_init(); convert_init(); + crc_init(); debug_init(); echo_init(); frag_init(); diff --git a/db/crc.c b/db/crc.c new file mode 100644 index 0000000..73dffcc --- /dev/null +++ b/db/crc.c @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2014 Red Hat, Inc. + * All Rights Reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "addr.h" +#include "command.h" +#include "type.h" +#include "faddr.h" +#include "fprint.h" +#include "field.h" +#include "flist.h" +#include "io.h" +#include "init.h" +#include "output.h" +#include "bit.h" +#include "print.h" + +static int crc_f(int argc, char **argv); +static void crc_help(void); + +static const cmdinfo_t crc_cmd = + { "crc", NULL, crc_f, 0, 1, 0, "[-i|-r|-v]", + N_("manipulate crc values for V5 filesystem structures"), crc_help }; + +void +crc_init(void) +{ + if (xfs_sb_version_hascrc(&mp->m_sb)) + add_command(&crc_cmd); +} + +static void +crc_help(void) +{ + dbprintf(_( +"\n" +" 'crc' validates, invalidates, or recalculates the crc value for\n" +" the current on-disk metadata structures in Version 5 filesystems.\n" +"\n" +" Usage: \"crc [-i|-r|-v]\"\n" +"\n" +)); + +} + +void +xfs_dummy_write_verify( + struct xfs_buf *bp) +{ + return; +} + +static int +crc_f( + int argc, + char **argv) +{ + const struct xfs_buf_ops *stashed_ops = NULL; + extern char *progname; + const field_t *fields; + const ftattr_t *fa; + flist_t *fl; + int invalidate = 0; + int recalculate = 0; + int validate = 0; + int c; + + if (cur_typ == NULL) { + dbprintf(_("no current type\n")); + return 0; + } + + if (cur_typ->fields == NULL) { + dbprintf(_("current type (%s) is not a structure\n"), + cur_typ->name); + return 0; + } + + if (argc) while ((c = getopt(argc, argv, "irv")) != EOF) { + switch (c) { + case 'i': + invalidate = 1; + break; + case 'r': + recalculate = 1; + break; + case 'v': + validate = 1; + break; + default: + dbprintf(_("bad option for crc command\n")); + return 0; + } + } else + validate = 1; + + if (invalidate + recalculate + validate > 1) { + dbprintf(_("crc command accepts only one option\n")); + return 0; + } + + if ((invalidate || recalculate) && + (x.isreadonly & LIBXFS_ISREADONLY || !expert_mode)) { + dbprintf(_("%s not in expert mode, writing disabled\n"), + progname); + return 0; + } + + fields = cur_typ->fields; + + /* if we're a root field type, go down 1 layer to get field list */ + if (fields->name[0] == '\0') { + fa = &ftattrtab[fields->ftyp]; + ASSERT(fa->ftyp == fields->ftyp); + fields = fa->subfld; + } + + /* Search for a CRC field */ + fl = flist_find_ftyp(fields, FLDT_CRC); + if (!fl) { + dbprintf(_("No CRC field found for type %s\n"), cur_typ->name); + return 0; + } + + /* run down the field list and set offsets into the data */ + if (!flist_parse(fields, fl, iocur_top->data, 0)) { + flist_free(fl); + dbprintf(_("parsing error\n")); + return 0; + } + + if (invalidate) { + struct xfs_buf_ops nowrite_ops; + flist_t *sfl; + int bit_length; + int parentoffset; + int crc; + + sfl = fl; + parentoffset = 0; + while (sfl->child) { + parentoffset = sfl->offset; + sfl = sfl->child; + } + ASSERT(sfl->fld->ftyp == FLDT_CRC); + + bit_length = fsize(sfl->fld, iocur_top->data, parentoffset, 0); + bit_length *= fcount(sfl->fld, iocur_top->data, parentoffset); + crc = getbitval(iocur_top->data, sfl->offset, bit_length, BVUNSIGNED); + /* Off by one.. */ + crc = cpu_to_be32(crc + 1); + setbitval(iocur_top->data, sfl->offset, bit_length, &crc); + + /* Temporarily remove write verifier so we can write a bad CRC */ + stashed_ops = iocur_top->bp->b_ops; + nowrite_ops.verify_read = stashed_ops->verify_read; + nowrite_ops.verify_write = xfs_dummy_write_verify; + iocur_top->bp->b_ops = &nowrite_ops; + } + + if (invalidate || recalculate) { + write_cur(); + if (stashed_ops) + iocur_top->bp->b_ops = stashed_ops; + /* re-verify to get proper b_error state */ + iocur_top->bp->b_ops->verify_read(iocur_top->bp); + } + + /* And show us what we've got! */ + flist_print(fl); + print_flist(fl); + flist_free(fl); + return 0; +} diff --git a/db/crc.h b/db/crc.h new file mode 100644 index 0000000..ec1ab8c --- /dev/null +++ b/db/crc.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014 Red Hat, Inc. + * All Rights Reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +struct field; + +extern void crc_init(void); +extern void crc_struct(const field_t *fields, int argc, char **argv); +extern void xfs_dummy_write_verify(struct xfs_buf *bp); diff --git a/db/flist.c b/db/flist.c index 33f7da7..fa19f70 100644 --- a/db/flist.c +++ b/db/flist.c @@ -411,6 +411,40 @@ flist_split( return v; } +/* + * Given a set of fields, scan for a field of the given type. + * Return an flist leading to the first found field + * of that type. + * Return NULL if no field of the given type is found. + */ +flist_t * +flist_find_ftyp( + const field_t *fields, + fldt_t type) +{ + flist_t *fl; + const field_t *f; + const ftattr_t *fa; + + for (f = fields; f->name; f++) { + fl = flist_make(f->name); + fl->fld = f; + if (f->ftyp == type) + return fl; + fa = &ftattrtab[f->ftyp]; + if (fa->subfld) { + flist_t *nfl; + nfl = flist_find_ftyp(fa->subfld, type); + if (nfl) { + fl->child = nfl; + return fl; + } + } + flist_free(fl); + } + return NULL; +} + static void ftok_free( ftok_t *ft) diff --git a/db/flist.h b/db/flist.h index 5c9fba0..3f4b312 100644 --- a/db/flist.h +++ b/db/flist.h @@ -37,3 +37,4 @@ extern int flist_parse(const struct field *fields, flist_t *fl, void *obj, int startoff); extern void flist_print(flist_t *fl); extern flist_t *flist_scan(char *name); +extern flist_t *flist_find_ftyp(const field_t *fields, fldt_t type); diff --git a/db/io.c b/db/io.c index 5bf40aa..1ba1f90 100644 --- a/db/io.c +++ b/db/io.c @@ -27,6 +27,7 @@ #include "output.h" #include "init.h" #include "malloc.h" +#include "crc.h" static int pop_f(int argc, char **argv); static void pop_help(void); @@ -464,9 +465,11 @@ write_cur(void) return; } - if (iocur_top->ino_buf) + if (iocur_top->ino_buf && + iocur_top->bp->b_ops->verify_write != xfs_dummy_write_verify) libxfs_dinode_calc_crc(mp, iocur_top->data); - if (iocur_top->dquot_buf) + if (iocur_top->dquot_buf && + iocur_top->bp->b_ops->verify_write != xfs_dummy_write_verify) xfs_update_cksum(iocur_top->data, sizeof(struct xfs_dqblk), XFS_DQUOT_CRC_OFF); if (iocur_top->bbmap) diff --git a/db/write.h b/db/write.h index 31e2665..664ddcc 100644 --- a/db/write.h +++ b/db/write.h @@ -20,5 +20,5 @@ struct field; extern void write_init(void); extern void write_block(const field_t *fields, int argc, char **argv); -extern void write_string(const field_t *fields, int argc, char **argv); extern void write_struct(const field_t *fields, int argc, char **argv); +extern void write_string(const field_t *fields, int argc, char **argv); diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8 index 4d8d4ff..0764832 100644 --- a/man/man8/xfs_db.8 +++ b/man/man8/xfs_db.8 @@ -87,16 +87,14 @@ or .I filename read-only. This option is required if the filesystem is mounted. It is only necessary to omit this flag if a command that changes data -.RB ( write ", " blocktrash ) +.RB ( write ", " blocktrash ", " crc ) is to be used. .TP .B \-x Specifies expert mode. This enables the -.B write -and -.B blocktrash -commands. +.RB ( write ", " blocktrash ", " crc +invalidate/revalidate) commands. .TP .B \-V Prints the version number and exits. @@ -409,6 +407,25 @@ conversions such as .I agb .BR fsblock . .TP +.B crc [\-i|\-r|\-v] +Invalidates, revalidates, or validates the CRC (checksum) +field of the current structure, if it has one. +This command is available only on CRC-enabled filesystems. +With no argument, validation is performed. +Each command will display the resulting CRC value and state. +.RS 1.0i +.TP 0.4i +.B \-i +Invalidate the structure's CRC value (incrementing it by one), +and write it to disk. +.TP +.B \-r +Recalculate the current structure's correct CRC value, and write it to disk. +.TP +.B \-v +Validate and display the current value and state of the structure's CRC. +.RE +.TP .BI "daddr [" d ] Set current address to the daddr (512 byte block) given by .IR d . From david@fromorbit.com Sat Sep 6 17:54:37 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 9BDED7F3F for ; Sat, 6 Sep 2014 17:54:37 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1B4C7AC001 for ; Sat, 6 Sep 2014 15:54:33 -0700 (PDT) X-ASG-Debug-ID: 1410044068-04cb6c54fd81eb30001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id b6JycGB2LCecyDBh for ; Sat, 06 Sep 2014 15:54:28 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: At1AAGSPC1R5LKYhPGdsb2JhbABYgw2BKoczqREBAQEGmnCFaQEDAQEBfxcFAQEBATg2hAQBBScTHCMQCAMOCgklDwUlAwcaE4hBvGoBFxiFZIhmIkkHgy+BHQEEnHGXFB6BbisvgQeBSAEBAQ Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 07 Sep 2014 08:24:26 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XQOsD-0005Eh-0v; Sun, 07 Sep 2014 08:54:25 +1000 Date: Sun, 7 Sep 2014 08:54:24 +1000 From: Dave Chinner To: Brian Foster Cc: Stefan Priebe - Profihost AG , "xfs@oss.sgi.com" Subject: Re: Is XFS suitable for 350 million files on 20TB storage? Message-ID: <20140906225424.GA9955@dastard> X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? References: <540986B1.4080306@profihost.ag> <20140905123058.GA29710@bfoster.bfoster> <5409AF40.10801@profihost.ag> <20140905230528.GO20473@dastard> <20140906145105.GA23506@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140906145105.GA23506@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410044068 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9240 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sat, Sep 06, 2014 at 10:51:05AM -0400, Brian Foster wrote: > On Sat, Sep 06, 2014 at 09:05:28AM +1000, Dave Chinner wrote: > > On Fri, Sep 05, 2014 at 02:40:32PM +0200, Stefan Priebe - Profihost AG wrote: > > > > > > Am 05.09.2014 um 14:30 schrieb Brian Foster: > > > > On Fri, Sep 05, 2014 at 11:47:29AM +0200, Stefan Priebe - Profihost AG wrote: > > > >> Hi, > > > >> > > > >> i have a backup system running 20TB of storage having 350 million files. > > > >> This was working fine for month. > > > >> > > > >> But now the free space is so heavily fragmented that i only see the > > > >> kworker with 4x 100% CPU and write speed beeing very slow. 15TB of the > > > >> 20TB are in use. > > > > What does perf tell you about the CPU being burnt? (i.e run perf top > > for 10-20s while that CPU burn is happening and paste the top 10 CPU > > consuming functions). > > > > > >> > > > >> Overall files are 350 Million - all in different directories. Max 5000 > > > >> per dir. > > > >> > > > >> Kernel is 3.10.53 and mount options are: > > > >> noatime,nodiratime,attr2,inode64,logbufs=8,logbsize=256k,noquota > > > >> > > > >> # xfs_db -r -c freesp /dev/sda1 > > > >> from to extents blocks pct > > > >> 1 1 29484138 29484138 2,16 > > > >> 2 3 16930134 39834672 2,92 > > > >> 4 7 16169985 87877159 6,45 > > > >> 8 15 78202543 999838327 73,41 > > > > With an inode size of 256 bytes, this is going to be your real > > problem soon - most of the free space is smaller than an inode > > chunk so soon you won't be able to allocate new inodes, even though > > there is free space on disk. > > > > The extent list here is in fsb units, right? 256b inodes means 16k inode > chunks, in which case it seems like there's still plenty of room for > inode chunks (e.g., 8-15 blocks -> 32k-64k). PEBKAC. My bad. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Sat Sep 6 17:56:58 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 789997F3F for ; Sat, 6 Sep 2014 17:56:58 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 22F42AC001 for ; Sat, 6 Sep 2014 15:56:57 -0700 (PDT) X-ASG-Debug-ID: 1410044215-04bdf010977c26f0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id oF8uTHVhCTUst5A9 for ; Sat, 06 Sep 2014 15:56:56 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtxAAJmQC1R5LKYhPGdsb2JhbABYgw2BKoczqRIBAQEGmnCFaQEDAQEBfxcFAQEBATg2hAQBBTocIxAIAw4KCSUPBSUDBxoTiEG8agEXGIVkiGYiSQeDL4EdBZxxmSArL4EHgUgBAQE Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 07 Sep 2014 08:26:55 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XQOuc-0005FH-QS; Sun, 07 Sep 2014 08:56:54 +1000 Date: Sun, 7 Sep 2014 08:56:54 +1000 From: Dave Chinner To: Brian Foster Cc: Stefan Priebe , "xfs@oss.sgi.com" Subject: Re: Is XFS suitable for 350 million files on 20TB storage? Message-ID: <20140906225654.GB9955@dastard> X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? References: <540986B1.4080306@profihost.ag> <20140905123058.GA29710@bfoster.bfoster> <5409AF40.10801@profihost.ag> <20140905230528.GO20473@dastard> <540AB933.4030707@profihost.ag> <20140906150412.GB23506@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140906150412.GB23506@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410044215 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9240 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sat, Sep 06, 2014 at 11:04:13AM -0400, Brian Foster wrote: > On Sat, Sep 06, 2014 at 09:35:15AM +0200, Stefan Priebe wrote: > > Hi Dave, > > > > Am 06.09.2014 01:05, schrieb Dave Chinner: > > >On Fri, Sep 05, 2014 at 02:40:32PM +0200, Stefan Priebe - Profihost AG wrote: > > >> > > >>Am 05.09.2014 um 14:30 schrieb Brian Foster: > > >>>On Fri, Sep 05, 2014 at 11:47:29AM +0200, Stefan Priebe - Profihost AG wrote: > > >>>>Hi, > > >>>> > > >>>>i have a backup system running 20TB of storage having 350 million files. > > >>>>This was working fine for month. > > >>>> > > >>>>But now the free space is so heavily fragmented that i only see the > > >>>>kworker with 4x 100% CPU and write speed beeing very slow. 15TB of the > > >>>>20TB are in use. > > > > > >What does perf tell you about the CPU being burnt? (i.e run perf top > > >for 10-20s while that CPU burn is happening and paste the top 10 CPU > > >consuming functions). > > > > here we go: > > 15,79% [kernel] [k] xfs_inobt_get_rec > > 14,57% [kernel] [k] xfs_btree_get_rec > > 10,37% [kernel] [k] xfs_btree_increment > > 7,20% [kernel] [k] xfs_btree_get_block > > 6,13% [kernel] [k] xfs_btree_rec_offset > > 4,90% [kernel] [k] xfs_dialloc_ag > > 3,53% [kernel] [k] xfs_btree_readahead > > 2,87% [kernel] [k] xfs_btree_rec_addr > > 2,80% [kernel] [k] _xfs_buf_find > > 1,94% [kernel] [k] intel_idle > > 1,49% [kernel] [k] _raw_spin_lock > > 1,13% [kernel] [k] copy_pte_range > > 1,10% [kernel] [k] unmap_single_vma > > > > The top 6 or so items look related to inode allocation, so that probably > confirms the primary bottleneck as searching around for free inodes out > of the existing inode chunks, precisely what the finobt is intended to > resolve. That was introduced in 3.16 kernels, so unfortunately it is not > available in 3.10. *nod* Again, the only workaround for this on a non-finobt fs is to greatly increase the number of AGs so there's less records in each btree to search. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Sat Sep 6 18:00:30 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B69767F3F for ; Sat, 6 Sep 2014 18:00:30 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 96F5D304048 for ; Sat, 6 Sep 2014 16:00:27 -0700 (PDT) X-ASG-Debug-ID: 1410044424-04cbb05486aaa170001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id 6cB7j09490RZCntr for ; Sat, 06 Sep 2014 16:00:25 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: At9AAL2RC1R5LKYhPGdsb2JhbABYgw2BKoczqRIBAQEGmnCFaQEDAQEBfxcFAQEBATg2hAMBAQQBJxMcIwULCAMYCSUPBSUDBxoTiDoHvGoBFxiFZIlRB4MvgR0FnHGMKIsggVgrL4JPAQEB Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 07 Sep 2014 08:30:08 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XQOxk-0005Fr-F7; Sun, 07 Sep 2014 09:00:08 +1000 Date: Sun, 7 Sep 2014 09:00:08 +1000 From: Dave Chinner To: Eric Sandeen Cc: xfs-oss Subject: Re: [PATCH 1/2] xfs_db: fix inode CRC validity state, and warn on read if invalid Message-ID: <20140906230008.GC9955@dastard> X-ASG-Orig-Subj: Re: [PATCH 1/2] xfs_db: fix inode CRC validity state, and warn on read if invalid References: <540B4399.4020804@sandeen.net> <540B485F.8070502@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540B485F.8070502@sandeen.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410044424 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9240 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sat, Sep 06, 2014 at 12:46:07PM -0500, Eric Sandeen wrote: > Currently, the "ino_crc_ok" field on the io cursor > reflects overall inode validity, not CRC correctness. > Because it is only used when printing CRC validity, > change it to reflect only that. > > In addition, when reading an inode, print the current > CRC state. > > Note, if specifying an inode which doesn't actually > exist, this will claim corruption; I'm not sure if > that's good or bad. Today, it already issues corruption > errors on the way; this adds a new message as well ;) > > xfs_db> inode 129 > Metadata corruption detected at block 0x80/0x2000 > Metadata corruption detected at block 0x80/0x2000 > ... > Metadata CRC error detected for ino 129 > > Signed-off-by: Eric Sandeen > --- > > diff --git a/db/inode.c b/db/inode.c > index 24170ba..244d03b 100644 > --- a/db/inode.c > +++ b/db/inode.c > @@ -684,13 +684,18 @@ set_cur_inode( > numblks, DB_RING_IGN, NULL); > off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize); > dip = iocur_top->data; > - iocur_top->ino_crc_ok = libxfs_dinode_verify(mp, ino, dip); > + iocur_top->ino_crc_ok = xfs_verify_cksum((char *)dip, > + mp->m_sb.sb_inodesize, > + XFS_DINODE_CRC_OFF); that needs to be "libxfs_verify_cksum". > iocur_top->ino_buf = 1; > iocur_top->ino = ino; > iocur_top->mode = be16_to_cpu(dip->di_mode); > if ((iocur_top->mode & S_IFMT) == S_IFDIR) > iocur_top->dirino = ino; > + if (xfs_sb_version_hascrc(&mp->m_sb) && !iocur_top->ino_crc_ok) > + dbprintf(_("Metadata CRC error detected for ino %lld\n"), ino); > + and we probably shoul dbe looking at making all those sb version checks "libxfs_sb_version_has...." as well. > /* track updated info in ring */ > ring_add(); > } > diff --git a/db/io.c b/db/io.c > index 7f1b76a..93ebf5c 100644 > --- a/db/io.c > +++ b/db/io.c > @@ -473,6 +473,17 @@ write_cur(void) > write_cur_bbs(); > else > write_cur_buf(); > + > + if (iocur_top->ino_buf) { > + xfs_dinode_t *dip; > + xfs_ino_t ino; > + > + dip = iocur_top->data; > + ino = iocur_top->ino; > + iocur_top->ino_crc_ok = xfs_verify_cksum((char *)dip, > + mp->m_sb.sb_inodesize, > + XFS_DINODE_CRC_OFF); > + } Needs a comment explaining why we are reverifying the inode crc. Cheers, Dave. -- Dave Chinner david@fromorbit.com From root@krios.tbi.univie.ac.at Sat Sep 6 23:25:10 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BEFB67F47 for ; Sat, 6 Sep 2014 23:25:10 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4B294AC001 for ; Sat, 6 Sep 2014 21:25:06 -0700 (PDT) X-ASG-Debug-ID: 1410063904-04cbb05487ab5d70001-NocioJ Received: from krios.tbi.univie.ac.at (krios.tbi.univie.ac.at [131.130.44.60]) by cuda.sgi.com with ESMTP id jCi9iiGzLAvSHRAs for ; Sat, 06 Sep 2014 21:25:05 -0700 (PDT) X-Barracuda-Envelope-From: root@krios.tbi.univie.ac.at X-Barracuda-Apparent-Source-IP: 131.130.44.60 Received: by krios.tbi.univie.ac.at (Postfix) id 76DAE5F39C; Sun, 7 Sep 2014 06:25:02 +0200 (CEST) Delivered-To: root@krios.tbi.univie.ac.at Received: by krios.tbi.univie.ac.at (Postfix, from userid 0) id 6730F5F455; Sun, 7 Sep 2014 06:25:02 +0200 (CEST) From: root@krios.tbi.univie.ac.at (Cron Daemon) To: root@krios.tbi.univie.ac.at Subject: Cron test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) Content-Type: text/plain; charset=UTF-8 X-ASG-Orig-Subj: Cron test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) X-Cron-Env: X-Cron-Env: X-Cron-Env: X-Cron-Env: Message-Id: <20140907042502.6730F5F455@krios.tbi.univie.ac.at> Date: Sun, 7 Sep 2014 06:25:02 +0200 (CEST) X-Barracuda-Connect: krios.tbi.univie.ac.at[131.130.44.60] X-Barracuda-Start-Time: 1410063904 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.70 X-Barracuda-Spam-Status: No, SCORE=0.70 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, BSF_SC0_SA_TO_FROM_ADDR_MATCH, PR0N_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9246 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.20 PR0N_SUBJECT Subject has letters around special characters (pr0n) 0.50 BSF_SC0_SA_TO_FROM_ADDR_MATCH Sender Address Matches Recipient Address /etc/cron.daily/logrotate: error: error opening /home/git/gitlab/log/application.log: Permission denied error: error opening /home/git/gitlab/log/githost.log: Permission denied error: error opening /home/git/gitlab/log/production.log: Permission denied error: error opening /home/git/gitlab/log/satellites.log: Permission denied error: error opening /home/git/gitlab/log/sidekiq.log: Permission denied error: error opening /home/git/gitlab/log/unicorn.stderr.log: Permission denied error: error opening /home/git/gitlab/log/unicorn.stdout.log: Permission denied error: error opening /home/git/gitlab-shell/gitlab-shell.log: Permission denied run-parts: /etc/cron.daily/logrotate exited with return code 1 From stan@hardwarefreak.com Sun Sep 7 00:23:08 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id ECF687F4E for ; Sun, 7 Sep 2014 00:23:07 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4E662AC004 for ; Sat, 6 Sep 2014 22:23:04 -0700 (PDT) X-ASG-Debug-ID: 1410067382-04cb6c550082aa40001-NocioJ Received: from greer.hardwarefreak.com (mo-65-41-216-221.sta.embarqhsd.net [65.41.216.221]) by cuda.sgi.com with ESMTP id WA88BTSwLx471NBT for ; Sat, 06 Sep 2014 22:23:02 -0700 (PDT) X-Barracuda-Envelope-From: stan@hardwarefreak.com X-Barracuda-Apparent-Source-IP: 65.41.216.221 X-Barracuda-User-Whitelist: xfs@oss.sgi.com Received: from [134.64.128.162] (unknown [192.65.45.20]) by greer.hardwarefreak.com (Postfix) with ESMTPA id 3BD1F6C0B7; Sun, 7 Sep 2014 00:23:01 -0500 (CDT) Message-ID: <540BEBB7.7020306@hardwarefreak.com> Date: Sun, 07 Sep 2014 00:23:03 -0500 From: stan hoeppner User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Icedove/24.7.0 MIME-Version: 1.0 To: Dave Chinner CC: xfs@oss.sgi.com Subject: Re: storage, libaio, or XFS problem? 3.4.26 References: <20140828003226.GO20518@dastard> <7f9e5aef187b44e899077467aeb0809d@localhost> <20140828230817.GU20518@dastard> <2d2ce7bb38c00a7d35f4a324f6a36cbb@localhost> <20140829235538.GF20518@dastard> <20140831235749.GH20518@dastard> <5403E9B9.7040608@hardwarefreak.com> <20140901234529.GI20518@dastard> <5405FB19.2020208@hardwarefreak.com> <20140902221915.GK20518@dastard> X-ASG-Orig-Subj: Re: storage, libaio, or XFS problem? 3.4.26 In-Reply-To: <20140902221915.GK20518@dastard> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mo-65-41-216-221.sta.embarqhsd.net[65.41.216.221] X-Barracuda-Start-Time: 1410067382 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On 09/02/2014 05:19 PM, Dave Chinner wrote: > On Tue, Sep 02, 2014 at 12:15:05PM -0500, stan hoeppner wrote: >> On 09/01/2014 06:45 PM, Dave Chinner wrote: >>> On Sun, Aug 31, 2014 at 10:36:25PM -0500, stan hoeppner wrote: >>>> On 08/31/2014 06:57 PM, Dave Chinner wrote: >>>>> On Fri, Aug 29, 2014 at 09:55:53PM -0500, Stan Hoeppner wrote: >>>>>> Have you played with bcache yet? >>>>> >>>>> Enough to scare me. So many ways for things to go wrong, no easy way >>>>> to recover when things go wrong. And that's before I even get to >>>>> performance warts, like having systems stall completely because >>>>> there's tens or hundreds of GB of 4k random writes that have to be >>>>> flushed to slow SATA RAID6 in the cache.... >>>> >>>> Yikes. I hadn't yet heard such opinions expressed. By go wrong I >>>> assume you mean the btrees or cached sector data getting broken, corrupted? >>> >>> bcache is a complex filesystem hidden inside a block device. If >>> bcache goes AWOL, so does the all the data on your block device. >>> Need I say more? >> >> So it's no different in that regard than the black box implementations >> such as LSI's CacheCade and various SAN vendor SSD caching >> implementations. Or are you saying the bcache code complexity is so >> much greater that failure is more likely that the vendor implementations? > > No, not the code complexity in particular. It's more that compared > to vendor SSD caching implementations there's an awful lot less > testing and validation, and people tend to use random, unreliable > hardware for cache devices. It's great when it works, but the > configuration and validation of correct behaviour in error > conditions falls to the user... Understood. I'm seeing the potential need for a future contract with Kent if we decide to go forward with bcache. He could advise on a testing and validation regimen, optimizing for the workload, and providing code fixes or features to overcome problems. Attempting to use something so new as bcache in a 24x7 commercial workload likely needs author support. >>> screen is your friend when it comes to keeping remote shells >>> active as the network comes and goes. VPN drops out, just bring it >>> back up when you need it and reconnect to the remote screen instance >>> and it's like you never left.... >> >> Thanks for this tip. I'd heard of screen before but never used it. I >> will say the man page is a bit intimidating for such an apparently >> simple tool... > > Yeah, I use about 0.0001% of what screen can do. It could lose most > of it's functionality and I wouldn't notice or care. tmux is another > option for this functionality, but I've never used it because I > found out about screen first... I'd guess there are many utils out there used in the same way. I have some more information regarding the AIO issue. I fired up the test harness and it ran for 30 hours at 706 MB/s avg write rate, 303 MB/s per LUN, nearly flawlessly, less than 0.01% buffer loss, and avg IO times were less than 0.5 seconds. Then the app crashed and I found the following in dmesg. I had to "hard reset" the box due to the shrapnel. There are no IO errors of any kind leading up to the forced shutdown. I assume the inode update and streamRT-sa hung task traces are a result of the forced shutdown, not a cause of it. In lieu of an xfs_repair with a version newer than I'm able to install, any ideas what caused the forced shutdown after 30 hours, given there are no errors preceding it? Sep 6 06:33:33 Anguish-ssu-1 kernel: [288087.334863] XFS (dm-5): xfs_do_force_shutdown(0x8) called from line 3732 of file fs/xfs/xfs_bmap.c. Return address = 0xffffffffa02009a6 Sep 6 06:33:42 Anguish-ssu-1 kernel: [288096.220920] XFS (dm-5): failed to update timestamps for inode 0x2ffc9caae Sep 6 06:33:48 Anguish-ssu-1 kernel: [288102.492641] XFS (dm-5): failed to update timestamps for inode 0x97b7566dd Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599412] INFO: task streamRT-sa:14706 blocked for more than 120 seconds. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599414] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599416] streamRT-sa D ffff883f3c018408 0 14706 14051 0x00000004 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599420] ffff883e6fc09b28 0000000000000086 0000000000000000 ffff8840666f5180 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599425] 0000000000000000 0000000000000000 00000000000122c0 00000000000122c0 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599428] ffff883e6fc09fd8 ffff883e6fc08000 00000000000122c0 ffff883e6fc08000 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599432] Call Trace: Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599441] [] schedule+0x64/0x66 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599443] [] rwsem_down_failed_common+0xdb/0x10d Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599446] [] rwsem_down_write_failed+0x13/0x15 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599451] [] call_rwsem_down_write_failed+0x13/0x20 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599454] [] ? down_write+0x25/0x27 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599466] [] xfs_ilock+0x4f/0xb4 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599472] [] xfs_rw_ilock+0x2c/0x33 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599476] [] ? _raw_spin_unlock_irq+0x27/0x32 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599481] [] xfs_file_aio_write_checks+0x41/0xfe [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599487] [] xfs_file_dio_aio_write+0x103/0x1fc [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599493] [] xfs_file_aio_write+0x152/0x1b5 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599499] [] ? xfs_file_buffered_aio_write+0x179/0x179 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599503] [] aio_rw_vect_retry+0x85/0x18a Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599505] [] ? aio_fsync+0x29/0x29 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599508] [] aio_run_iocb+0x7b/0x149 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599510] [] io_submit_one+0x199/0x1f3 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599513] [] do_io_submit+0xfa/0x271 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599516] [] sys_io_submit+0x10/0x12 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599519] [] system_call_fastpath+0x16/0x1b Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599521] INFO: task streamRT-sa:14713 blocked for more than 120 seconds. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599523] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599524] streamRT-sa D ffff883b4f52ea48 0 14713 14051 0x00000004 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599527] ffff883e74af9b28 0000000000000086 0000000000000000 ffff884066622140 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599530] 0000000000000000 0000000000000000 00000000000122c0 00000000000122c0 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599534] ffff883e74af9fd8 ffff883e74af8000 00000000000122c0 ffff883e74af8000 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599537] Call Trace: Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599540] [] schedule+0x64/0x66 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599542] [] rwsem_down_failed_common+0xdb/0x10d Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599544] [] rwsem_down_write_failed+0x13/0x15 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599547] [] call_rwsem_down_write_failed+0x13/0x20 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599549] [] ? down_write+0x25/0x27 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599555] [] xfs_ilock+0x4f/0xb4 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599561] [] xfs_rw_ilock+0x2c/0x33 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599563] [] ? _raw_spin_unlock_irq+0x27/0x32 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599569] [] xfs_file_aio_write_checks+0x41/0xfe [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599575] [] xfs_file_dio_aio_write+0x103/0x1fc [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599580] [] xfs_file_aio_write+0x152/0x1b5 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599586] [] ? xfs_file_buffered_aio_write+0x179/0x179 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599589] [] aio_rw_vect_retry+0x85/0x18a Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599591] [] ? aio_fsync+0x29/0x29 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599593] [] aio_run_iocb+0x7b/0x149 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599596] [] io_submit_one+0x199/0x1f3 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599598] [] do_io_submit+0xfa/0x271 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599601] [] sys_io_submit+0x10/0x12 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599603] [] system_call_fastpath+0x16/0x1b Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599605] INFO: task streamRT-sa:14723 blocked for more than 120 seconds. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599607] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599608] streamRT-sa D ffff883e754b2b88 0 14723 14051 0x00000004 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599610] ffff883e6fca3b28 0000000000000086 0000000000000000 ffff8840662521c0 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599614] 0000000000000000 0000000000000000 00000000000122c0 00000000000122c0 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599617] ffff883e6fca3fd8 ffff883e6fca2000 00000000000122c0 ffff883e6fca2000 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599620] Call Trace: Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599623] [] schedule+0x64/0x66 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599625] [] rwsem_down_failed_common+0xdb/0x10d Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599628] [] rwsem_down_write_failed+0x13/0x15 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599630] [] call_rwsem_down_write_failed+0x13/0x20 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599632] [] ? down_write+0x25/0x27 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599638] [] xfs_ilock+0x4f/0xb4 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599644] [] xfs_rw_ilock+0x2c/0x33 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599646] [] ? _raw_spin_unlock_irq+0x27/0x32 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599652] [] xfs_file_aio_write_checks+0x41/0xfe [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599657] [] xfs_file_dio_aio_write+0x103/0x1fc [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599663] [] xfs_file_aio_write+0x152/0x1b5 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599669] [] ? xfs_file_buffered_aio_write+0x179/0x179 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599671] [] aio_rw_vect_retry+0x85/0x18a Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599674] [] ? aio_fsync+0x29/0x29 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599676] [] aio_run_iocb+0x7b/0x149 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599678] [] io_submit_one+0x199/0x1f3 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599681] [] do_io_submit+0xfa/0x271 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599684] [] sys_io_submit+0x10/0x12 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599686] [] system_call_fastpath+0x16/0x1b Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599688] INFO: task streamRT-sa:14730 blocked for more than 120 seconds. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599689] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599691] streamRT-sa D ffff883dc2360388 0 14730 14051 0x00000004 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599693] ffff883e6fde1b28 0000000000000086 0000000000000000 ffff884066043080 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599696] 0000000000000000 0000000000000000 00000000000122c0 00000000000122c0 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599700] ffff883e6fde1fd8 ffff883e6fde0000 00000000000122c0 ffff883e6fde0000 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599703] Call Trace: Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599705] [] schedule+0x64/0x66 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599708] [] rwsem_down_failed_common+0xdb/0x10d Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599710] [] rwsem_down_write_failed+0x13/0x15 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599712] [] call_rwsem_down_write_failed+0x13/0x20 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599715] [] ? down_write+0x25/0x27 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599720] [] xfs_ilock+0x4f/0xb4 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599726] [] xfs_rw_ilock+0x2c/0x33 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599728] [] ? _raw_spin_unlock_irq+0x27/0x32 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599734] [] xfs_file_aio_write_checks+0x41/0xfe [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599740] [] xfs_file_dio_aio_write+0x103/0x1fc [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599745] [] xfs_file_aio_write+0x152/0x1b5 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599751] [] ? xfs_file_buffered_aio_write+0x179/0x179 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599754] [] aio_rw_vect_retry+0x85/0x18a Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599756] [] ? aio_fsync+0x29/0x29 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599758] [] aio_run_iocb+0x7b/0x149 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599761] [] io_submit_one+0x199/0x1f3 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599763] [] do_io_submit+0xfa/0x271 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599766] [] sys_io_submit+0x10/0x12 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599768] [] system_call_fastpath+0x16/0x1b Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599770] INFO: task streamRT-sa:14733 blocked for more than 120 seconds. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599771] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599773] streamRT-sa D ffff883e7555cb08 0 14733 14051 0x00000004 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599775] ffff883e7389db28 0000000000000086 0000000000000000 ffff88406663a040 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599778] 0000000000000000 0000000000000000 00000000000122c0 00000000000122c0 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599782] ffff883e7389dfd8 ffff883e7389c000 00000000000122c0 ffff883e7389c000 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599785] Call Trace: Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599787] [] schedule+0x64/0x66 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599790] [] rwsem_down_failed_common+0xdb/0x10d Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599792] [] rwsem_down_write_failed+0x13/0x15 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599794] [] call_rwsem_down_write_failed+0x13/0x20 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599797] [] ? down_write+0x25/0x27 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599802] [] xfs_ilock+0x4f/0xb4 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599808] [] xfs_rw_ilock+0x2c/0x33 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599811] [] ? _raw_spin_unlock_irq+0x27/0x32 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599816] [] xfs_file_aio_write_checks+0x41/0xfe [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599822] [] xfs_file_dio_aio_write+0x103/0x1fc [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599827] [] xfs_file_aio_write+0x152/0x1b5 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599833] [] ? xfs_file_buffered_aio_write+0x179/0x179 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599836] [] aio_rw_vect_retry+0x85/0x18a Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599838] [] ? aio_fsync+0x29/0x29 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599840] [] aio_run_iocb+0x7b/0x149 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599843] [] io_submit_one+0x199/0x1f3 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599845] [] do_io_submit+0xfa/0x271 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599848] [] sys_io_submit+0x10/0x12 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599850] [] system_call_fastpath+0x16/0x1b Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599852] INFO: task streamRT-sa:14736 blocked for more than 120 seconds. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599853] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599855] streamRT-sa D ffff883e73915448 0 14736 14051 0x00000004 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599857] ffff883e73bb5b28 0000000000000086 0000000000000000 ffff884066709080 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599860] 000000025600a331 0000000000000000 00000000000122c0 00000000000122c0 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599864] ffff883e73bb5fd8 ffff883e73bb4000 00000000000122c0 ffff883e73bb4000 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599867] Call Trace: Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599870] [] schedule+0x64/0x66 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599872] [] rwsem_down_failed_common+0xdb/0x10d Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599874] [] rwsem_down_write_failed+0x13/0x15 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599877] [] call_rwsem_down_write_failed+0x13/0x20 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599879] [] ? down_write+0x25/0x27 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599885] [] xfs_ilock+0x4f/0xb4 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599890] [] xfs_rw_ilock+0x2c/0x33 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599892] [] ? _raw_spin_unlock_irq+0x27/0x32 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599898] [] xfs_file_aio_write_checks+0x41/0xfe [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599904] [] xfs_file_dio_aio_write+0x103/0x1fc [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599909] [] xfs_file_aio_write+0x152/0x1b5 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599915] [] ? xfs_file_buffered_aio_write+0x179/0x179 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599918] [] aio_rw_vect_retry+0x85/0x18a Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599920] [] ? aio_fsync+0x29/0x29 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599922] [] aio_run_iocb+0x7b/0x149 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599925] [] io_submit_one+0x199/0x1f3 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599927] [] do_io_submit+0xfa/0x271 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599930] [] sys_io_submit+0x10/0x12 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599932] [] system_call_fastpath+0x16/0x1b Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599934] INFO: task streamRT-sa:14738 blocked for more than 120 seconds. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599936] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599937] streamRT-sa D ffff883f7c605488 0 14738 14051 0x00000004 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599939] ffff883c4cda7b28 0000000000000086 0000000000000000 ffff8840667bd1c0 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599943] 0000000000000000 0000000000000000 00000000000122c0 00000000000122c0 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599946] ffff883c4cda7fd8 ffff883c4cda6000 00000000000122c0 ffff883c4cda6000 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599949] Call Trace: Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599952] [] schedule+0x64/0x66 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599954] [] rwsem_down_failed_common+0xdb/0x10d Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599956] [] rwsem_down_write_failed+0x13/0x15 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599959] [] call_rwsem_down_write_failed+0x13/0x20 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599961] [] ? down_write+0x25/0x27 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599967] [] xfs_ilock+0x4f/0xb4 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599972] [] xfs_rw_ilock+0x2c/0x33 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599975] [] ? _raw_spin_unlock_irq+0x27/0x32 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599980] [] xfs_file_aio_write_checks+0x41/0xfe [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599986] [] xfs_file_dio_aio_write+0x103/0x1fc [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599991] [] xfs_file_aio_write+0x152/0x1b5 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.599997] [] ? xfs_file_buffered_aio_write+0x179/0x179 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600000] [] aio_rw_vect_retry+0x85/0x18a Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600002] [] ? aio_fsync+0x29/0x29 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600004] [] aio_run_iocb+0x7b/0x149 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600007] [] io_submit_one+0x199/0x1f3 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600009] [] do_io_submit+0xfa/0x271 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600012] [] sys_io_submit+0x10/0x12 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600014] [] system_call_fastpath+0x16/0x1b Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600016] INFO: task streamRT-sa:14739 blocked for more than 120 seconds. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600018] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600019] streamRT-sa D ffff883e75536a08 0 14739 14051 0x00000004 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600021] ffff883b4f411b28 0000000000000086 0000000000000000 ffff884066739140 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600025] 0000000000000000 0000000000000000 00000000000122c0 00000000000122c0 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600028] ffff883b4f411fd8 ffff883b4f410000 00000000000122c0 ffff883b4f410000 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600031] Call Trace: Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600034] [] schedule+0x64/0x66 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600036] [] rwsem_down_failed_common+0xdb/0x10d Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600038] [] rwsem_down_write_failed+0x13/0x15 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600041] [] call_rwsem_down_write_failed+0x13/0x20 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600043] [] ? down_write+0x25/0x27 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600048] [] xfs_ilock+0x4f/0xb4 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600054] [] xfs_rw_ilock+0x2c/0x33 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600056] [] ? _raw_spin_unlock_irq+0x27/0x32 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600062] [] xfs_file_aio_write_checks+0x41/0xfe [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600068] [] xfs_file_dio_aio_write+0x103/0x1fc [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600073] [] xfs_file_aio_write+0x152/0x1b5 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600079] [] ? xfs_file_buffered_aio_write+0x179/0x179 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600082] [] aio_rw_vect_retry+0x85/0x18a Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600084] [] ? aio_fsync+0x29/0x29 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600086] [] aio_run_iocb+0x7b/0x149 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600089] [] io_submit_one+0x199/0x1f3 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600091] [] do_io_submit+0xfa/0x271 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600094] [] sys_io_submit+0x10/0x12 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600096] [] system_call_fastpath+0x16/0x1b Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600099] INFO: task streamRT-sa:14768 blocked for more than 120 seconds. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600100] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600101] streamRT-sa D ffff883b5f120308 0 14768 14051 0x00000004 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600104] ffff883cca73bb28 0000000000000086 0000000000000000 ffffffff81813020 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600107] 0000000000000000 0000000000000000 00000000000122c0 00000000000122c0 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600110] ffff883cca73bfd8 ffff883cca73a000 00000000000122c0 ffff883cca73a000 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600113] Call Trace: Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600116] [] schedule+0x64/0x66 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600118] [] rwsem_down_failed_common+0xdb/0x10d Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600120] [] rwsem_down_write_failed+0x13/0x15 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600123] [] call_rwsem_down_write_failed+0x13/0x20 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600125] [] ? down_write+0x25/0x27 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600131] [] xfs_ilock+0x4f/0xb4 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600136] [] xfs_rw_ilock+0x2c/0x33 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600139] [] ? _raw_spin_unlock_irq+0x27/0x32 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600144] [] xfs_file_aio_write_checks+0x41/0xfe [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600150] [] xfs_file_dio_aio_write+0x103/0x1fc [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600156] [] xfs_file_aio_write+0x152/0x1b5 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600161] [] ? xfs_file_buffered_aio_write+0x179/0x179 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600164] [] aio_rw_vect_retry+0x85/0x18a Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600166] [] ? aio_fsync+0x29/0x29 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600168] [] aio_run_iocb+0x7b/0x149 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600171] [] io_submit_one+0x199/0x1f3 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600173] [] do_io_submit+0xfa/0x271 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600176] [] sys_io_submit+0x10/0x12 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600178] [] system_call_fastpath+0x16/0x1b Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600180] INFO: task streamRT-sa:14789 blocked for more than 120 seconds. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600181] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600183] streamRT-sa D ffff883cca430b08 0 14789 14051 0x00000004 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600185] ffff883f3d9c3b28 0000000000000086 0000000000000000 ffff884066739140 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600188] 0000000000000000 0000000000000000 00000000000122c0 00000000000122c0 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600192] ffff883f3d9c3fd8 ffff883f3d9c2000 00000000000122c0 ffff883f3d9c2000 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600195] Call Trace: Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600197] [] schedule+0x64/0x66 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600200] [] rwsem_down_failed_common+0xdb/0x10d Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600202] [] rwsem_down_write_failed+0x13/0x15 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600204] [] call_rwsem_down_write_failed+0x13/0x20 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600207] [] ? down_write+0x25/0x27 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600212] [] xfs_ilock+0x4f/0xb4 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600218] [] xfs_rw_ilock+0x2c/0x33 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600220] [] ? _raw_spin_unlock_irq+0x27/0x32 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600226] [] xfs_file_aio_write_checks+0x41/0xfe [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600231] [] xfs_file_dio_aio_write+0x103/0x1fc [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600237] [] xfs_file_aio_write+0x152/0x1b5 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600243] [] ? xfs_file_buffered_aio_write+0x179/0x179 [xfs] Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600245] [] aio_rw_vect_retry+0x85/0x18a Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600248] [] ? aio_fsync+0x29/0x29 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600250] [] aio_run_iocb+0x7b/0x149 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600252] [] io_submit_one+0x199/0x1f3 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600255] [] do_io_submit+0xfa/0x271 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600258] [] sys_io_submit+0x10/0x12 Sep 6 06:35:41 Anguish-ssu-1 kernel: [288215.600260] [] system_call_fastpath+0x16/0x1b Sep 6 15:42:02 Anguish-ssu-1 kernel: [320925.045195] SysRq : Resetting Thanks, Stan From admin@vista1.magizz.com Sun Sep 7 02:24:45 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_IMAGE_RATIO_08, HTML_MESSAGE,RCVD_NUMERIC_HELO,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 0B5797F51 for ; Sun, 7 Sep 2014 02:24:45 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id ED622304043 for ; Sun, 7 Sep 2014 00:24:41 -0700 (PDT) X-ASG-Debug-ID: 1410074678-04cb6c54ff82d320001-NocioJ Received: from vps.magizz.com (vps.magizz.com [162.251.83.157]) by cuda.sgi.com with ESMTP id aE69B4oMKyvpLnLO (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sun, 07 Sep 2014 00:24:39 -0700 (PDT) X-Barracuda-Envelope-From: admin@vista1.magizz.com X-Barracuda-Apparent-Source-IP: 162.251.83.157 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=vista1.magizz.com; s=default; h=Content-Type:MIME-Version:List-Owner:List-Subscribe:List-Unsubscribe:List-Help:Message-ID:Reply-To:From:Date:Subject:To; bh=7R53dxrsq1VmxwPbo7FM2weOJVHisEECnbMX7YEfhNM=; b=Jh2VK8nlpOstQznWiLKyIGmqfEt3obV/I9gYGsrtzrpRUJ97paV/Q0RW2Bqp9jQMvFyyvNz9n1tjEPjs15bU3faZ7SQjHeLdF5jKAXsib9Kv8XDoZwf3coiZsYhW9XTwZILGb++mQCByjmWADc47pO/z10VfsaviYeJpff5weyY=; Received: from magivis by vps.magizz.com with local (Exim 4.82) (envelope-from ) id 1XQWpy-0000ar-0P for xfs@oss.sgi.com; Sun, 07 Sep 2014 11:24:38 +0400 To: xfs@oss.sgi.com Subject: Insure your bike in 3 easy steps X-PHP-Script: vista1.magizz.com/mailz/admin/index.php for 116.203.126.88 X-ASG-Orig-Subj: Insure your bike in 3 easy steps Received: from 116.203.126.88 [116.203.126.88] by vista1.magizz.com with HTTP; Sun, 07 Sep 2014 05:42:00 +0000 Date: Sun, 7 Sep 2014 07:24:37 +0000 From: ICICI Lombard Reply-To: ICICI Lombard Message-ID: <7b5d98db7db9176126fa1ab7b964fa99@vista1.magizz.com> X-Priority: 3 X-Mailer: PHPMailer 5.2.5 (https://github.com/Synchro/PHPMailer/) X-phpList-version: 3.0.7 X-MessageID: 7 X-ListMember: xfs@oss.sgi.com Precedence: bulk Bounces-To: admin@vista1.magizz.com List-Help: List-Unsubscribe: List-Subscribe: List-Owner: MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="b1_7b5d98db7db9176126fa1ab7b964fa99" X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - vps.magizz.com X-AntiAbuse: Original Domain - oss.sgi.com X-AntiAbuse: Originator/Caller UID/GID - [524 534] / [47 12] X-AntiAbuse: Sender Address Domain - vista1.magizz.com X-Get-Message-Sender-Via: vps.magizz.com: authenticated_id: magivis/from_h X-Barracuda-Connect: vps.magizz.com[162.251.83.157] X-Barracuda-Start-Time: 1410074679 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.26 X-Barracuda-Spam-Status: No, SCORE=1.26 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, HTML_IMAGE_RATIO_08, HTML_MESSAGE, RCVD_NUMERIC_HELO, RCVD_NUMERIC_HELO_2 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9249 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 RCVD_NUMERIC_HELO Received: contains an IP address used for HELO -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_IMAGE_RATIO_08 BODY: HTML has a low ratio of text to image area 0.00 HTML_MESSAGE BODY: HTML included in message 1.25 RCVD_NUMERIC_HELO_2 Received: contains an IP address used for HELO --b1_7b5d98db7db9176126fa1ab7b964fa99 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable =20 A Two Wheeler insurance quote is just 30 seconds away also on your mobile & tablet Dear Customer, A comprehensive Two Wheeler Insurance Policy provides the assurance of security against damage caused by natural and man-made calamities, including acts of terrorism. Click here to get a quick quote and secure your two wheeler instantly. Policy copy issued immediately online =20 Avail no claim bonus on renewals* =20 Cashless claim servicing at 1330+ garages# Warm Regards, Team ICICI Lombard Disclaimer EC014ML1635II #1330+ garages as on 1st September 2014 *NCB (No Claims Bonus) will only be allowed provided the policy is renewed within 90 days of the expiry date of the previous policy. The NCB will be available; provided you show evidence that you are entitled to NCB from your previous motor insurance company. Evidence can be in form of a written declaration or renewal notice or a letter confirming the NCB entitlement from the previous insurer.=20 Insurance is the subject matter of solicitation. The advertisement contains only an indication of cover offered. For more details on risk factors, terms, conditions and exclusions, please read the sales brochure carefully before concluding a sale. ICICI Lombard General Insurance Company Limited, ICICI Lombard House, 414, Veer Savarkar Marg, Prabhadevi, Mumbai - 400025. IRDA Reg. No. 115. Toll Free 1800 2666. Motor 05. Fax no - 022 61961323. Corporate Identity Number (U67200MH2000PLC129408). Your privacy is important to us. If you do not wish to receive emails, please unsubscribe . For any queries or assistance you can Email us at customersupport@icicilombard.com -- This message was sent to xfs@oss.sgi.com by swati@vista1.magizz.com To forward this message, please do not use the forward button of your email application, because this message was made specifically for you only. Instead use the forward page=0A in our newsletter system. To change your details and to choose which lists to be subscribed to, visit your personal preferences page=0A Or you can UNSUBSCRIBE for this panel.=0A from all future mailings. =20 amj --b1_7b5d98db7db9176126fa1ab7b964fa99 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable =0A =0A

 

3D"ICICI 3D"Facebook"&= nbsp;  3D"Twitt=   3D"LinkedIn"   3D"Google+"  3D"You=  3D"Android
A Two Wheeler insurance quote is&nb= sp;just 30 seconds&n= bsp;away
3D"A
3D"Getalso on your mobile & tablet

Dear Customer,

A comprehensive Two Wheeler Insurance Policy provides th= e assurance of security against damage caused by natural and man-made calam= ities, including acts of terrorism. Click hereto get a quick quote and secure your two whee= ler instantly.

3D"Key
  = Policy copy issued immediately online   Avail no claim bonus on renewals*   Cashless claim servicing at 1330+ garages#=  
3D""

Warm Regards,
Team ICICI Lombard<= /strong>

Disclaimer EC014ML1635II
#1330+ garages as on 1st September 2014
*NCB (No Claims Bonus) will only be allowed provided the policy= is renewed within 90 days of the expiry date of the previous policy. The N= CB will be available; provided you show evidence that you are entitled to N= CB from your previous motor insurance company. Evidence can be in form of a= written declaration or renewal notice or a letter confirming the NCB entit= lement from the previous insurer. 
Insurance is the subject matter of solicitation. The advertisem= ent contains only an indication of cover offered. For more details on risk = factors, terms, conditions and exclusions, please read the sales brochure c= arefully before concluding a sale. ICICI Lombard General Insurance Company = Limited, ICICI Lombard House, 414, Veer Savarkar Marg, Prabhadevi= , Mumbai - 400025. IRDA Reg. No. 115. Toll Free 1800 2666. Motor 05. Fax no= - 022 61961323. Corporate Identity Number (U67200MH2000PLC129408).

Your privacy is important to us. If you do not wish to receive = emails, please unsubscribe.
For any queries or assistance you can Email us at customersupport@icicilombard.c= om
&nbs= p;
 

-- =20

This message was sent to xfs@oss.sgi.com by swati@vista1.magizz.co= m

To forward this message, please do not use the forward button of y= our email application, because this message was made specifically for you o= nly. Instead use the forward page in our newsletter system.
To change your details and to choose which lists to be subscribed to,= visit your personal preferences page
Or you can UNSUBSCRIBE for this panel. from all future mailings.

=0Aamj --b1_7b5d98db7db9176126fa1ab7b964fa99-- From bfoster@redhat.com Sun Sep 7 07:26:06 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 76D497F50 for ; Sun, 7 Sep 2014 07:26:06 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 63A128F8059 for ; Sun, 7 Sep 2014 05:26:06 -0700 (PDT) X-ASG-Debug-ID: 1410092761-04cbb05487abe480001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ZUGku0XNVBL4UNvt (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sun, 07 Sep 2014 05:26:02 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s87CQ1Jh013228 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Sun, 7 Sep 2014 08:26:01 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s87CQ1vk029364 for ; Sun, 7 Sep 2014 08:26:01 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 586261256F8; Sun, 7 Sep 2014 08:26:00 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 0/4] clean up collapse range and handle post-eof delalloc Date: Sun, 7 Sep 2014 08:25:56 -0400 X-ASG-Orig-Subj: [PATCH 0/4] clean up collapse range and handle post-eof delalloc Message-Id: <1410092760-3451-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410092762 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hi all, Here's a new drop of the patches that tweak collapse to be fsb based and organize the code a bit. This has seen ~1.5b fsx ops without a failure and some light xfstests testing so far. The primary difference from this version and the rfc is the retention of the eofblocks trim prior to collapse. Patch 4 is also new. It isolates the pagecache writeback/truncate in xfs_free_file_space() to the range affected by the free. Thoughts, reviews, flames appreciated. Brian v1: - Retain the eofblocks trim and writeback/inval. the range of shifted data only. - Added the xfs_free_file_space() patch to no longer writeback the entire file. rfc: http://oss.sgi.com/archives/xfs/2014-08/msg00462.html Brian Foster (4): xfs: track collapse via file offset rather than extent index xfs: refactor xfs_bmap_shift_extents() into multiple functions xfs: writeback and inval. file range to be shifted by collapse xfs: only writeback and truncate pages for the freed range fs/xfs/libxfs/xfs_bmap.c | 294 +++++++++++++++++++++++++++++++---------------- fs/xfs/libxfs/xfs_bmap.h | 7 +- fs/xfs/xfs_bmap_util.c | 54 +++++---- 3 files changed, 230 insertions(+), 125 deletions(-) -- 1.8.3.1 From bfoster@redhat.com Sun Sep 7 07:26:07 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 54FCB7F50 for ; Sun, 7 Sep 2014 07:26:07 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id D87E0AC002 for ; Sun, 7 Sep 2014 05:26:06 -0700 (PDT) X-ASG-Debug-ID: 1410092762-04cb6c55008333c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id IlIcUZlPg69ey4QZ (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sun, 07 Sep 2014 05:26:02 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s87CQ11G009156 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Sun, 7 Sep 2014 08:26:01 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s87CQ1m2030638 for ; Sun, 7 Sep 2014 08:26:01 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 6EC601256FA; Sun, 7 Sep 2014 08:26:00 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 2/4] xfs: refactor xfs_bmap_shift_extents() into multiple functions Date: Sun, 7 Sep 2014 08:25:58 -0400 X-ASG-Orig-Subj: [PATCH 2/4] xfs: refactor xfs_bmap_shift_extents() into multiple functions Message-Id: <1410092760-3451-3-git-send-email-bfoster@redhat.com> In-Reply-To: <1410092760-3451-1-git-send-email-bfoster@redhat.com> References: <1410092760-3451-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410092762 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The extent shift mechanism in xfs_bmap_shift_extents() is complicated and handles several different, non-deterministic scenarios. These include extent shifts, extent merges and potential btree updates in either of the former scenarios. Refactor the code to be more linear and readable. The loop logic in xfs_bmap_shift_extents() and some initial error checking is adjusted slightly. The associated btree lookup and update/delete operations are condensed into single blocks of code. This reduces the number of btree-specific blocks and facilitates the separation of the merge operation into a new xfs_bmap_shift_extents_merge() helper. The merge check is also separated into an inline. This is a code refactor only. The behavior of extent shift and collapse range is not modified. Signed-off-by: Brian Foster --- fs/xfs/libxfs/xfs_bmap.c | 243 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 168 insertions(+), 75 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 4b3f1b9..449a016 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5404,6 +5404,120 @@ error0: } /* + * Determine whether an extent shift can be accomplished by a merge with the + * extent that precedes the target hole of the shift. + */ +static inline bool +xfs_bmap_shift_extents_can_merge( + struct xfs_bmbt_irec *left, /* preceding extent */ + struct xfs_bmbt_irec *got, /* current extent to shift */ + xfs_fileoff_t shift) /* shift fsb */ +{ + xfs_fileoff_t startoff; + + startoff = got->br_startoff - shift; + + /* + * The extent, once shifted, must be adjacent in-file and on-disk with + * the preceding extent. + */ + if ((left->br_startoff + left->br_blockcount != startoff) || + (left->br_startblock + left->br_blockcount != got->br_startblock) || + (left->br_state != got->br_state) || + (left->br_blockcount + got->br_blockcount > MAXEXTLEN)) + return false; + + return true; +} + +/* + * An extent shift adjusts the file offset of an extent to fill a preceding hole + * in the file. If an extent shift would result in the extent being fully + * adjacent to the extent that currently precedes the hole, we can merge with + * the preceding extent rather than do the shift. + * + * This function assumes the caller has verified a shift-by-merge is possible + * with the provided extents via xfs_bmap_shift_extents_can_merge(). + */ +static int +xfs_bmap_shift_extents_merge( + struct xfs_inode *ip, + int whichfork, + xfs_fileoff_t shift, /* shift fsb */ + int current_ext, /* idx of gotp */ + struct xfs_bmbt_rec_host *gotp, /* extent to shift */ + struct xfs_bmbt_rec_host *leftp, /* preceding extent */ + struct xfs_btree_cur *cur, + int *logflags) /* output */ +{ + struct xfs_ifork *ifp; + struct xfs_bmbt_irec got; + struct xfs_bmbt_irec left; + xfs_filblks_t blockcount; + int error, i; + + ifp = XFS_IFORK_PTR(ip, whichfork); + xfs_bmbt_get_all(gotp, &got); + xfs_bmbt_get_all(leftp, &left); + blockcount = left.br_blockcount + got.br_blockcount; + + ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); + ASSERT(xfs_bmap_shift_extents_can_merge(&left, &got, shift)); + + /* + * Merge the in-core extents. Note that the host record pointers and + * current_ext index are invalid once the extent has been removed via + * xfs_iext_remove(). + */ + xfs_bmbt_set_blockcount(leftp, blockcount); + xfs_iext_remove(ip, current_ext, 1, 0); + + /* + * Update the on-disk extent count, the btree if necessary and log the + * inode. + */ + XFS_IFORK_NEXT_SET(ip, whichfork, + XFS_IFORK_NEXTENTS(ip, whichfork) - 1); + *logflags |= XFS_ILOG_CORE; + if (cur) { + /* lookup and remove the extent to merge */ + error = xfs_bmbt_lookup_eq(cur, got.br_startoff, + got.br_startblock, got.br_blockcount, &i); + if (error) + goto error; + XFS_WANT_CORRUPTED_GOTO(i == 1, error); + + error = xfs_btree_delete(cur, &i); + if (error) + goto error; + XFS_WANT_CORRUPTED_GOTO(i == 1, error); + + /* lookup and update size of the previous extent */ + error = xfs_bmbt_lookup_eq(cur, left.br_startoff, + left.br_startblock, left.br_blockcount, &i); + if (error) + goto error; + XFS_WANT_CORRUPTED_GOTO(i == 1, error); + + left.br_blockcount = blockcount; + + error = xfs_bmbt_update(cur, left.br_startoff, + left.br_startblock, left.br_blockcount, + left.br_state); + if (error) + goto error; + } else { + *logflags |= XFS_ILOG_DEXT; + } + + return 0; + +error: + return error; +} + +/* * Shift extent records to the left to cover a hole. * * The maximum number of extents to be shifted in a single operation is @@ -5427,6 +5541,7 @@ xfs_bmap_shift_extents( { struct xfs_btree_cur *cur = NULL; struct xfs_bmbt_rec_host *gotp; + struct xfs_bmbt_rec_host *leftp; struct xfs_bmbt_irec got; struct xfs_bmbt_irec left; struct xfs_mount *mp = ip->i_mount; @@ -5438,7 +5553,6 @@ xfs_bmap_shift_extents( int i; int whichfork = XFS_DATA_FORK; int logflags = 0; - xfs_filblks_t blockcount = 0; int total_extents; if (unlikely(XFS_TEST_ERROR( @@ -5464,6 +5578,13 @@ xfs_bmap_shift_extents( return error; } + if (ifp->if_flags & XFS_IFBROOT) { + cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); + cur->bc_private.b.firstblock = *firstblock; + cur->bc_private.b.flist = flist; + cur->bc_private.b.flags = 0; + } + /* * Look up the extent index for the fsb where we start shifting. We can * henceforth iterate with current_ext as extent list changes are locked @@ -5476,14 +5597,17 @@ xfs_bmap_shift_extents( gotp = xfs_iext_bno_to_ext(ifp, start_fsb, ¤t_ext); if (!gotp) { *done = 1; - return 0; + goto del_cursor; } + xfs_bmbt_get_all(gotp, &got); - if (ifp->if_flags & XFS_IFBROOT) { - cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); - cur->bc_private.b.firstblock = *firstblock; - cur->bc_private.b.flist = flist; - cur->bc_private.b.flags = 0; + /* + * If the first extent is shifted, offset_shift_fsb cannot be larger + * than the starting offset of the first extent. + */ + if (current_ext == 0 && got.br_startoff < offset_shift_fsb) { + error = -EINVAL; + goto del_cursor; } /* @@ -5493,30 +5617,42 @@ xfs_bmap_shift_extents( */ total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); while (nexts++ < num_exts && current_ext < total_extents) { - - gotp = xfs_iext_get_ext(ifp, current_ext); - xfs_bmbt_get_all(gotp, &got); startoff = got.br_startoff - offset_shift_fsb; - /* - * Before shifting extent into hole, make sure that the hole is - * large enough to accommodate the shift. - */ + /* grab the left extent and check for a potential merge */ if (current_ext > 0) { - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, current_ext - 1), - &left); - if (startoff < left.br_startoff + left.br_blockcount) + leftp = xfs_iext_get_ext(ifp, current_ext - 1); + xfs_bmbt_get_all(leftp, &left); + + /* make sure hole is large enough for shift */ + if (startoff < left.br_startoff + left.br_blockcount) { error = -EINVAL; - } else if (offset_shift_fsb > got.br_startoff) { - /* - * When first extent is shifted, offset_shift_fsb should - * be less than the stating offset of the first extent. - */ - error = -EINVAL; + goto del_cursor; + } + + if (xfs_bmap_shift_extents_can_merge(&left, &got, + offset_shift_fsb)) { + error = xfs_bmap_shift_extents_merge(ip, whichfork, + offset_shift_fsb, current_ext, gotp, + leftp, cur, &logflags); + if (error) + goto del_cursor; + + /* + * The extent was merged so adjust the extent + * index and move onto the next. + */ + current_ext--; + goto next; + } } - if (error) - goto del_cursor; + /* + * We didn't merge the extent so do the shift. Update the start + * offset in the in-core extent and btree, if necessary. + */ + xfs_bmbt_set_startoff(gotp, startoff); + logflags |= XFS_ILOG_CORE; if (cur) { error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock, @@ -5525,53 +5661,8 @@ xfs_bmap_shift_extents( if (error) goto del_cursor; XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor); - } - - /* Check if we can merge 2 adjacent extents */ - if (current_ext && - left.br_startoff + left.br_blockcount == startoff && - left.br_startblock + left.br_blockcount == - got.br_startblock && - left.br_state == got.br_state && - left.br_blockcount + got.br_blockcount <= MAXEXTLEN) { - blockcount = left.br_blockcount + - got.br_blockcount; - xfs_iext_remove(ip, current_ext, 1, 0); - logflags |= XFS_ILOG_CORE; - if (cur) { - error = xfs_btree_delete(cur, &i); - if (error) - goto del_cursor; - XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor); - } else { - logflags |= XFS_ILOG_DEXT; - } - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) - 1); - gotp = xfs_iext_get_ext(ifp, --current_ext); - xfs_bmbt_get_all(gotp, &got); - - /* Make cursor point to the extent we will update */ - if (cur) { - error = xfs_bmbt_lookup_eq(cur, got.br_startoff, - got.br_startblock, - got.br_blockcount, - &i); - if (error) - goto del_cursor; - XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor); - } - xfs_bmbt_set_blockcount(gotp, blockcount); - got.br_blockcount = blockcount; - } else { - /* We have to update the startoff */ - xfs_bmbt_set_startoff(gotp, startoff); got.br_startoff = startoff; - } - - logflags |= XFS_ILOG_CORE; - if (cur) { error = xfs_bmbt_update(cur, got.br_startoff, got.br_startblock, got.br_blockcount, @@ -5582,18 +5673,20 @@ xfs_bmap_shift_extents( logflags |= XFS_ILOG_DEXT; } - current_ext++; +next: + /* update total extent count and grab the next record */ total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); + if (++current_ext >= total_extents) + break; + gotp = xfs_iext_get_ext(ifp, current_ext); + xfs_bmbt_get_all(gotp, &got); } /* Check if we are done */ if (current_ext == total_extents) *done = 1; - else if (next_fsb) { - gotp = xfs_iext_get_ext(ifp, current_ext); - xfs_bmbt_get_all(gotp, &got); + else if (next_fsb) *next_fsb = got.br_startoff; - } del_cursor: if (cur) -- 1.8.3.1 From bfoster@redhat.com Sun Sep 7 07:26:08 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 52A037F53 for ; Sun, 7 Sep 2014 07:26:08 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id C09B7AC001 for ; Sun, 7 Sep 2014 05:26:04 -0700 (PDT) X-ASG-Debug-ID: 1410092762-04cbb05485abe480001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id cNSbk0P9a55Zoah4 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sun, 07 Sep 2014 05:26:03 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s87CQ1kl013562 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Sun, 7 Sep 2014 08:26:02 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s87CQ1mE030640 for ; Sun, 7 Sep 2014 08:26:01 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 7F1501256FB; Sun, 7 Sep 2014 08:26:00 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 3/4] xfs: writeback and inval. file range to be shifted by collapse Date: Sun, 7 Sep 2014 08:25:59 -0400 X-ASG-Orig-Subj: [PATCH 3/4] xfs: writeback and inval. file range to be shifted by collapse Message-Id: <1410092760-3451-4-git-send-email-bfoster@redhat.com> In-Reply-To: <1410092760-3451-1-git-send-email-bfoster@redhat.com> References: <1410092760-3451-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410092763 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The collapse range operation currently writes the entire file before starting the collapse to avoid changes in the in-core extent list due to writeback causing the extent count to change. Now that collapse range is fsb based rather than extent index based it can sustain changes in the extent list during the shift sequence without disruption. Modify xfs_collapse_file_space() to writeback and invalidate pages associated with the range of the file to be shifted. xfs_free_file_space() currently has similar behavior, but the space free need only affect the region of the file that is freed and this could change in the future. Also update the comments to reflect the current implementation. We retain the eofblocks trim permanently as a best option for dealing with delalloc extents. We don't shift delalloc extents because this scenario only occurs with post-eof preallocation (since data must be flushed such that the cache can be invalidated and data can be shifted). That means said space must also be initialized before being shifted into the accessible region of the file only to be immediately truncated off as the last part of the collapse. In other words, the eofblocks trim will happen anyways, we just run it first to ensure the file remains in a consistent state throughout the collapse. Finally, BUG() in the event of a delalloc extent during the extent shift such that a failure is obvious. The implementation explicitly does not support delalloc extents and the caller is expected to prevent this scenario in advance as is done by collapse. Signed-off-by: Brian Foster --- fs/xfs/libxfs/xfs_bmap.c | 2 ++ fs/xfs/xfs_bmap_util.c | 32 +++++++++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 449a016..1dd04c2 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5617,6 +5617,8 @@ xfs_bmap_shift_extents( */ total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); while (nexts++ < num_exts && current_ext < total_extents) { + /* can't handle delalloc extents */ + BUG_ON(isnullstartblock(got.br_startblock)); startoff = got.br_startoff - offset_shift_fsb; /* grab the left extent and check for a potential merge */ diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 1e96d77..eae763f 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1470,27 +1470,33 @@ xfs_collapse_file_space( next_fsb = XFS_B_TO_FSB(mp, offset + len); shift_fsb = XFS_B_TO_FSB(mp, len); - /* - * Writeback the entire file and force remove any post-eof blocks. The - * writeback prevents changes to the extent list via concurrent - * writeback and the eofblocks trim prevents the extent shift algorithm - * from running into a post-eof delalloc extent. - * - * XXX: This is a temporary fix until the extent shift loop below is - * converted to use offsets and lookups within the ILOCK rather than - * carrying around the index into the extent list for the next - * iteration. - */ - error = filemap_write_and_wait(VFS_I(ip)->i_mapping); + error = xfs_free_file_space(ip, offset, len); if (error) return error; + + /* + * Trim eofblocks to avoid shifting uninitialized post-eof preallocation + * into the accessible region of the file. + */ if (xfs_can_free_eofblocks(ip, true)) { error = xfs_free_eofblocks(mp, ip, false); if (error) return error; } - error = xfs_free_file_space(ip, offset, len); + /* + * Writeback and invalidate cache for the remainder of the file as we're + * about to shift down every extent from the collapse range to EOF. The + * free of the collapse range above might have already done some of + * this, but we shouldn't rely on it to do anything outside of the range + * that was freed. + */ + error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, + offset + len, -1); + if (error) + return error; + error = invalidate_inode_pages2_range(VFS_I(ip)->i_mapping, + (offset + len) >> PAGE_CACHE_SHIFT, -1); if (error) return error; -- 1.8.3.1 From bfoster@redhat.com Sun Sep 7 07:26:06 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 7491B7F4E for ; Sun, 7 Sep 2014 07:26:06 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6282F8F8054 for ; Sun, 7 Sep 2014 05:26:06 -0700 (PDT) X-ASG-Debug-ID: 1410092761-04cbb05486abe480001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id AD9bRXLCsSXVKGZH (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sun, 07 Sep 2014 05:26:02 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s87CQ1a3009154 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Sun, 7 Sep 2014 08:26:01 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s87CQ11i030642 for ; Sun, 7 Sep 2014 08:26:01 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 8901E125701; Sun, 7 Sep 2014 08:26:00 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 4/4] xfs: only writeback and truncate pages for the freed range Date: Sun, 7 Sep 2014 08:26:00 -0400 X-ASG-Orig-Subj: [PATCH 4/4] xfs: only writeback and truncate pages for the freed range Message-Id: <1410092760-3451-5-git-send-email-bfoster@redhat.com> In-Reply-To: <1410092760-3451-1-git-send-email-bfoster@redhat.com> References: <1410092760-3451-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410092762 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xfs_free_file_space() only affects the range of the file for which space is being freed. It currently writes and truncates the page cache from the start offset of the free to EOF. Modify xfs_free_file_space() to write back and truncate page cache of just the range being freed. Signed-off-by: Brian Foster --- fs/xfs/xfs_bmap_util.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index eae763f..809ae7d 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1205,6 +1205,7 @@ xfs_free_file_space( xfs_bmap_free_t free_list; xfs_bmbt_irec_t imap; xfs_off_t ioffset; + xfs_off_t iendoffset; xfs_extlen_t mod=0; xfs_mount_t *mp; int nimap; @@ -1233,12 +1234,13 @@ xfs_free_file_space( inode_dio_wait(VFS_I(ip)); rounding = max_t(xfs_off_t, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); - ioffset = offset & ~(rounding - 1); - error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, - ioffset, -1); + ioffset = round_down(offset, rounding); + iendoffset = round_up(offset + len, rounding) - 1; + error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, ioffset, + iendoffset); if (error) goto out; - truncate_pagecache_range(VFS_I(ip), ioffset, -1); + truncate_pagecache_range(VFS_I(ip), ioffset, iendoffset); /* * Need to zero the stuff we're not freeing, on disk. -- 1.8.3.1 From bfoster@redhat.com Sun Sep 7 07:26:08 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 5A24A7F54 for ; Sun, 7 Sep 2014 07:26:08 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id CE984AC002 for ; Sun, 7 Sep 2014 05:26:04 -0700 (PDT) X-ASG-Debug-ID: 1410092762-04cbb05488abe490001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id V4dd3YU5l2MN5YFl (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sun, 07 Sep 2014 05:26:03 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s87CQ1WR013563 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Sun, 7 Sep 2014 08:26:02 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s87CQ13W020833 for ; Sun, 7 Sep 2014 08:26:01 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 63468123B5C; Sun, 7 Sep 2014 08:26:00 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 1/4] xfs: track collapse via file offset rather than extent index Date: Sun, 7 Sep 2014 08:25:57 -0400 X-ASG-Orig-Subj: [PATCH 1/4] xfs: track collapse via file offset rather than extent index Message-Id: <1410092760-3451-2-git-send-email-bfoster@redhat.com> In-Reply-To: <1410092760-3451-1-git-send-email-bfoster@redhat.com> References: <1410092760-3451-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410092763 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The collapse range implementation uses a transaction per extent shift. The progress of the overall operation is tracked via the current extent index of the in-core extent list. This is racy because the ilock must be dropped and reacquired for each transaction according to locking and log reservation rules. Therefore, writeback to prior regions of the file is possible and can change the extent count. This changes the extent to which the current index refers and causes the collapse to fail mid operation. To avoid this problem, the entire file is currently written back before the collapse operation starts. To eliminate the need to flush the entire file, use the file offset (fsb) to track the progress of the overall extent shift operation rather than the extent index. Modify xfs_bmap_shift_extents() to unconditionally convert the start_fsb parameter to an extent index and return the file offset of the extent where the shift left off, if further extents exist. The bulk of ths function can remain based on extent index as ilock is held by the caller. xfs_collapse_file_space() now uses the fsb output as the starting point for the subsequent shift. Signed-off-by: Brian Foster --- fs/xfs/libxfs/xfs_bmap.c | 85 +++++++++++++++++++++++++----------------------- fs/xfs/libxfs/xfs_bmap.h | 7 ++-- fs/xfs/xfs_bmap_util.c | 12 +++---- 3 files changed, 53 insertions(+), 51 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 86df952..4b3f1b9 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5406,20 +5406,21 @@ error0: /* * Shift extent records to the left to cover a hole. * - * The maximum number of extents to be shifted in a single operation - * is @num_exts, and @current_ext keeps track of the current extent - * index we have shifted. @offset_shift_fsb is the length by which each - * extent is shifted. If there is no hole to shift the extents - * into, this will be considered invalid operation and we abort immediately. + * The maximum number of extents to be shifted in a single operation is + * @num_exts. @start_fsb specifies the file offset to start the shift and the + * file offset where we've left off is returned in @next_fsb. @offset_shift_fsb + * is the length by which each extent is shifted. If there is no hole to shift + * the extents into, this will be considered invalid operation and we abort + * immediately. */ int xfs_bmap_shift_extents( struct xfs_trans *tp, struct xfs_inode *ip, - int *done, xfs_fileoff_t start_fsb, xfs_fileoff_t offset_shift_fsb, - xfs_extnum_t *current_ext, + int *done, + xfs_fileoff_t *next_fsb, xfs_fsblock_t *firstblock, struct xfs_bmap_free *flist, int num_exts) @@ -5431,6 +5432,7 @@ xfs_bmap_shift_extents( struct xfs_mount *mp = ip->i_mount; struct xfs_ifork *ifp; xfs_extnum_t nexts = 0; + xfs_extnum_t current_ext; xfs_fileoff_t startoff; int error = 0; int i; @@ -5451,7 +5453,8 @@ xfs_bmap_shift_extents( if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; - ASSERT(current_ext != NULL); + ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ifp = XFS_IFORK_PTR(ip, whichfork); if (!(ifp->if_flags & XFS_IFEXTENTS)) { @@ -5462,20 +5465,18 @@ xfs_bmap_shift_extents( } /* - * If *current_ext is 0, we would need to lookup the extent - * from where we would start shifting and store it in gotp. + * Look up the extent index for the fsb where we start shifting. We can + * henceforth iterate with current_ext as extent list changes are locked + * out via ilock. + * + * gotp can be null in 2 cases: 1) if there are no extents or 2) + * start_fsb lies in a hole beyond which there are no extents. Either + * way, we are done. */ - if (!*current_ext) { - gotp = xfs_iext_bno_to_ext(ifp, start_fsb, current_ext); - /* - * gotp can be null in 2 cases: 1) if there are no extents - * or 2) start_fsb lies in a hole beyond which there are - * no extents. Either way, we are done. - */ - if (!gotp) { - *done = 1; - return 0; - } + gotp = xfs_iext_bno_to_ext(ifp, start_fsb, ¤t_ext); + if (!gotp) { + *done = 1; + return 0; } if (ifp->if_flags & XFS_IFBROOT) { @@ -5487,36 +5488,32 @@ xfs_bmap_shift_extents( /* * There may be delalloc extents in the data fork before the range we - * are collapsing out, so we cannot - * use the count of real extents here. Instead we have to calculate it - * from the incore fork. + * are collapsing out, so we cannot use the count of real extents here. + * Instead we have to calculate it from the incore fork. */ total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); - while (nexts++ < num_exts && *current_ext < total_extents) { + while (nexts++ < num_exts && current_ext < total_extents) { - gotp = xfs_iext_get_ext(ifp, *current_ext); + gotp = xfs_iext_get_ext(ifp, current_ext); xfs_bmbt_get_all(gotp, &got); startoff = got.br_startoff - offset_shift_fsb; /* - * Before shifting extent into hole, make sure that the hole - * is large enough to accomodate the shift. + * Before shifting extent into hole, make sure that the hole is + * large enough to accommodate the shift. */ - if (*current_ext) { - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, - *current_ext - 1), &left); - + if (current_ext > 0) { + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, current_ext - 1), + &left); if (startoff < left.br_startoff + left.br_blockcount) error = -EINVAL; } else if (offset_shift_fsb > got.br_startoff) { /* - * When first extent is shifted, offset_shift_fsb - * should be less than the stating offset of - * the first extent. + * When first extent is shifted, offset_shift_fsb should + * be less than the stating offset of the first extent. */ error = -EINVAL; } - if (error) goto del_cursor; @@ -5531,7 +5528,7 @@ xfs_bmap_shift_extents( } /* Check if we can merge 2 adjacent extents */ - if (*current_ext && + if (current_ext && left.br_startoff + left.br_blockcount == startoff && left.br_startblock + left.br_blockcount == got.br_startblock && @@ -5539,7 +5536,7 @@ xfs_bmap_shift_extents( left.br_blockcount + got.br_blockcount <= MAXEXTLEN) { blockcount = left.br_blockcount + got.br_blockcount; - xfs_iext_remove(ip, *current_ext, 1, 0); + xfs_iext_remove(ip, current_ext, 1, 0); logflags |= XFS_ILOG_CORE; if (cur) { error = xfs_btree_delete(cur, &i); @@ -5551,7 +5548,7 @@ xfs_bmap_shift_extents( } XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) - 1); - gotp = xfs_iext_get_ext(ifp, --*current_ext); + gotp = xfs_iext_get_ext(ifp, --current_ext); xfs_bmbt_get_all(gotp, &got); /* Make cursor point to the extent we will update */ @@ -5585,13 +5582,18 @@ xfs_bmap_shift_extents( logflags |= XFS_ILOG_DEXT; } - (*current_ext)++; + current_ext++; total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); } /* Check if we are done */ - if (*current_ext == total_extents) + if (current_ext == total_extents) *done = 1; + else if (next_fsb) { + gotp = xfs_iext_get_ext(ifp, current_ext); + xfs_bmbt_get_all(gotp, &got); + *next_fsb = got.br_startoff; + } del_cursor: if (cur) @@ -5600,5 +5602,6 @@ del_cursor: if (logflags) xfs_trans_log_inode(tp, ip, logflags); + return error; } diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index b879ca5..44db6db 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -178,9 +178,8 @@ int xfs_check_nostate_extents(struct xfs_ifork *ifp, xfs_extnum_t idx, xfs_extnum_t num); uint xfs_default_attroffset(struct xfs_inode *ip); int xfs_bmap_shift_extents(struct xfs_trans *tp, struct xfs_inode *ip, - int *done, xfs_fileoff_t start_fsb, - xfs_fileoff_t offset_shift_fsb, xfs_extnum_t *current_ext, - xfs_fsblock_t *firstblock, struct xfs_bmap_free *flist, - int num_exts); + xfs_fileoff_t start_fsb, xfs_fileoff_t offset_shift_fsb, + int *done, xfs_fileoff_t *next_fsb, xfs_fsblock_t *firstblock, + struct xfs_bmap_free *flist, int num_exts); #endif /* __XFS_BMAP_H__ */ diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 1707980..1e96d77 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1456,18 +1456,18 @@ xfs_collapse_file_space( struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; int error; - xfs_extnum_t current_ext = 0; struct xfs_bmap_free free_list; xfs_fsblock_t first_block; int committed; xfs_fileoff_t start_fsb; + xfs_fileoff_t next_fsb; xfs_fileoff_t shift_fsb; ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); trace_xfs_collapse_file_space(ip); - start_fsb = XFS_B_TO_FSB(mp, offset + len); + next_fsb = XFS_B_TO_FSB(mp, offset + len); shift_fsb = XFS_B_TO_FSB(mp, len); /* @@ -1525,10 +1525,10 @@ xfs_collapse_file_space( * We are using the write transaction in which max 2 bmbt * updates are allowed */ - error = xfs_bmap_shift_extents(tp, ip, &done, start_fsb, - shift_fsb, ¤t_ext, - &first_block, &free_list, - XFS_BMAP_MAX_SHIFT_EXTENTS); + start_fsb = next_fsb; + error = xfs_bmap_shift_extents(tp, ip, start_fsb, shift_fsb, + &done, &next_fsb, &first_block, &free_list, + XFS_BMAP_MAX_SHIFT_EXTENTS); if (error) goto out; -- 1.8.3.1 From admin@vista1.magizz.com Sun Sep 7 08:31:19 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C21AD7F4E for ; Sun, 7 Sep 2014 08:31:19 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 62A64AC001 for ; Sun, 7 Sep 2014 06:31:16 -0700 (PDT) X-ASG-Debug-ID: 1410096673-04cb6c54ff835270001-NocioJ Received: from vps.magizz.com (vps.magizz.com [162.251.83.157]) by cuda.sgi.com with ESMTP id jsK2FREm0olEzzKZ (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sun, 07 Sep 2014 06:31:13 -0700 (PDT) X-Barracuda-Envelope-From: admin@vista1.magizz.com X-Barracuda-Apparent-Source-IP: 162.251.83.157 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=vista1.magizz.com; s=default; h=Content-Type:Content-Transfer-Encoding:MIME-Version:List-Unsubscribe:Message-ID:Reply-To:From:Date:Subject:To; bh=IeQs2k9fFo/qz33WbH3w6bMRPtkJvDOGa2uL5Aw1S/Y=; b=fwhE/ShIaqhs/FjdJgkmCHv5nCE0W6ZfqIV1xxPXyBmCN6NQDupTyFRO9aW5E5y7KNQVmtoOmIqHBWtl7+938TjRE7cXHAo7PBeEV0Sm/FtcAdp8SSIzllaz8O19gMyYw0QAXYsJkJjv/+vv9Z2QvOKnrdBGPPHfrI+IqSLGLEU=; Received: from magivis by vps.magizz.com with local (Exim 4.82) (envelope-from ) id 1XQcYj-0003uX-0w for xfs@oss.sgi.com; Sun, 07 Sep 2014 17:31:13 +0400 To: xfs@oss.sgi.com Subject: Goodbye from our newsletter X-PHP-Script: vista1.magizz.com/mailz/index.php for 66.249.65.38 X-ASG-Orig-Subj: Goodbye from our newsletter Received: from crawl-66-249-65-38.googlebot.com [66.249.65.38] by vista1.magizz.com with HTTP; Sun, 07 Sep 2014 13:31:12 +0000 Date: Sun, 7 Sep 2014 13:31:12 +0000 From: Administrator Reply-To: Administrator Message-ID: <59d56c4701e843312d21ad1fc6325e6e@vista1.magizz.com> X-Priority: 3 X-Mailer: PHPMailer 5.2.5 (https://github.com/Synchro/PHPMailer/) X-phpList-version: 3.0.7 X-MessageID: systemmessage X-ListMember: xfs@oss.sgi.com Precedence: bulk Bounces-To: admin@vista1.magizz.com List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - vps.magizz.com X-AntiAbuse: Original Domain - oss.sgi.com X-AntiAbuse: Originator/Caller UID/GID - [524 534] / [47 12] X-AntiAbuse: Sender Address Domain - vista1.magizz.com X-Get-Message-Sender-Via: vps.magizz.com: authenticated_id: magivis/from_h X-Barracuda-Connect: vps.magizz.com[162.251.83.157] X-Barracuda-Start-Time: 1410096673 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9255 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature Goodbye from our Newsletter, sorry to see you go. You have been unsubscribed from our newsletters. This is the last email you will receive from us. Our newsletter system, phpList, will refuse to send you any further messages, without manual intervention by our administrator. If there is an error in this information, you can re-subscribe: please go to http://vista1.magizz.com/mailz/?p=subscribe and follow the steps. Thank you From sandeen@sandeen.net Sun Sep 7 11:41:08 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 7AF217F4E for ; Sun, 7 Sep 2014 11:41:08 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 659FB8F8039 for ; Sun, 7 Sep 2014 09:41:08 -0700 (PDT) X-ASG-Debug-ID: 1410108066-04cbb05487ac4430001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id YXKVqTLhRtBD6TFy for ; Sun, 07 Sep 2014 09:41:06 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: by sandeen.net (Postfix, from userid 500) id 8303061A5851; Sun, 7 Sep 2014 11:41:06 -0500 (CDT) From: Eric Sandeen To: xfs@oss.sgi.com Subject: [PATCH 0/5] xfs_repair fixes, part 1 Date: Sun, 7 Sep 2014 11:41:00 -0500 X-ASG-Orig-Subj: [PATCH 0/5] xfs_repair fixes, part 1 Message-Id: <1410108065-18156-1-git-send-email-sandeen@redhat.com> X-Mailer: git-send-email 1.7.1 X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410108066 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9258 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- I've been running a modified fsfuzzer and looking at the results of xfs_repair of the corrupt images; plenty of things pop out. I'm calling this "part one" because I expect that I'll find more, but will send things out in digestable chunks as I accumulate them... Most of these are obviously correct and trivial; a coupl require more thought & review. Thanks, -Eric From sandeen@sandeen.net Sun Sep 7 11:41:08 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 8D9897F50 for ; Sun, 7 Sep 2014 11:41:08 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 64B5B8F8035 for ; Sun, 7 Sep 2014 09:41:08 -0700 (PDT) X-ASG-Debug-ID: 1410108066-04bdf010977dcc60001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id kAlWteQoyUxGTkl9 for ; Sun, 07 Sep 2014 09:41:07 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: by sandeen.net (Postfix, from userid 500) id 9E0F461A5853; Sun, 7 Sep 2014 11:41:06 -0500 (CDT) From: Eric Sandeen To: xfs@oss.sgi.com Subject: [PATCH 2/5] xfs_repair: preserve error state in process_shortform_attr Date: Sun, 7 Sep 2014 11:41:02 -0500 X-ASG-Orig-Subj: [PATCH 2/5] xfs_repair: preserve error state in process_shortform_attr Message-Id: <1410108065-18156-3-git-send-email-sandeen@redhat.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1410108065-18156-1-git-send-email-sandeen@redhat.com> References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410108067 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9258 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- process_shortform_attr uses the "junkit" error to track whether an error was found, but by assigning it directly to the result of valuecheck, previous errors are ignored, leading to unrepairable errors of the form i.e. "entry has INCOMPLETE flag on in shortform attribute" or "entry contains illegal character in shortform attribute name" Signed-off-by: Eric Sandeen --- repair/attr_repair.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/repair/attr_repair.c b/repair/attr_repair.c index a27a3ec..d60b664 100644 --- a/repair/attr_repair.c +++ b/repair/attr_repair.c @@ -914,7 +914,8 @@ process_shortform_attr( /* Only check values for root security attributes */ if (currententry->flags & XFS_ATTR_ROOT) - junkit = valuecheck(mp, (char *)¤tentry->nameval[0], + junkit |= valuecheck(mp, + (char *)¤tentry->nameval[0], NULL, currententry->namelen, currententry->valuelen); -- 1.7.1 From sandeen@sandeen.net Sun Sep 7 11:41:09 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 417447F4E for ; Sun, 7 Sep 2014 11:41:09 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id B5766AC004 for ; Sun, 7 Sep 2014 09:41:08 -0700 (PDT) X-ASG-Debug-ID: 1410108066-04cbb05485ac4430001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id 8iIw0F9BC2bkM27M for ; Sun, 07 Sep 2014 09:41:06 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: by sandeen.net (Postfix, from userid 500) id BE27061A5855; Sun, 7 Sep 2014 11:41:06 -0500 (CDT) From: Eric Sandeen To: xfs@oss.sgi.com Subject: [PATCH 4/5] xfs_repair: don't ASSERT on corrupt ftype Date: Sun, 7 Sep 2014 11:41:04 -0500 X-ASG-Orig-Subj: [PATCH 4/5] xfs_repair: don't ASSERT on corrupt ftype Message-Id: <1410108065-18156-5-git-send-email-sandeen@redhat.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1410108065-18156-1-git-send-email-sandeen@redhat.com> References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410108066 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9258 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- xfs_dir3_dirent_get_ftype() gets the file type off disk, but ASSERTs if it's invalid: ASSERT(type < XFS_DIR3_FT_MAX); This might be cut & paste from xfs_dir3_dirent_put_ftype which should be checking that it's not been passed bad values, but we shouldn't ASSERT on bad values read from disk. Signed-off-by: Eric Sandeen --- include/xfs_da_format.h | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/include/xfs_da_format.h b/include/xfs_da_format.h index 89a1a21..11f1420 100644 --- a/include/xfs_da_format.h +++ b/include/xfs_da_format.h @@ -561,7 +561,6 @@ xfs_dir3_dirent_get_ftype( if (xfs_sb_version_hasftype(&mp->m_sb)) { __uint8_t type = dep->name[dep->namelen]; - ASSERT(type < XFS_DIR3_FT_MAX); if (type < XFS_DIR3_FT_MAX) return type; -- 1.7.1 From sandeen@sandeen.net Sun Sep 7 11:41:09 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 697BF7F50 for ; Sun, 7 Sep 2014 11:41:09 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 2D2208F8033 for ; Sun, 7 Sep 2014 09:41:09 -0700 (PDT) X-ASG-Debug-ID: 1410108067-04bdf010a17dcc70001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id zavfwSWDH7LbFfdS for ; Sun, 07 Sep 2014 09:41:07 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: by sandeen.net (Postfix, from userid 500) id CC5F661A5856; Sun, 7 Sep 2014 11:41:06 -0500 (CDT) From: Eric Sandeen To: xfs@oss.sgi.com Subject: [PATCH 5/5] xfs_repair: set proper ftype when moving to lost+found Date: Sun, 7 Sep 2014 11:41:05 -0500 X-ASG-Orig-Subj: [PATCH 5/5] xfs_repair: set proper ftype when moving to lost+found Message-Id: <1410108065-18156-6-git-send-email-sandeen@redhat.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1410108065-18156-1-git-send-email-sandeen@redhat.com> References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410108067 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9258 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- When we move files to lost+found, we're setting the filetype to UNKNOWN. This leaves an inconsistency which is discovered on a subsequent repair: would fix ftype mismatch (0/1) in directory/child inode 5838/5839 Setting the proper ftype at the time of the move resolves this: Signed-off-by: Eric Sandeen --- repair/phase6.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/repair/phase6.c b/repair/phase6.c index cc36a9c..02714c2 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -1091,14 +1091,13 @@ mv_orphanage( ino_tree_node_t *irec; int ino_offset = 0; struct xfs_name xname; + __uint16_t di_mode; ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb)); xname.name = fname; xname.len = snprintf((char *)fname, sizeof(fname), "%llu", (unsigned long long)ino); - /* XXX use xfs_mode_to_ftype[] when userspace gains it */ - xname.type = XFS_DIR3_FT_UNKNOWN; err = libxfs_iget(mp, NULL, orphanage_ino, 0, &orphanage_ip, 0); if (err) @@ -1117,6 +1116,10 @@ mv_orphanage( if ((err = libxfs_iget(mp, NULL, ino, 0, &ino_p, 0))) do_error(_("%d - couldn't iget disconnected inode\n"), err); + di_mode = ino_p->i_d.di_mode; + di_mode = (di_mode & S_IFMT) >> S_SHIFT; + xname.type = xfs_mode_to_ftype[di_mode]; + if (isa_dir) { irec = find_inode_rec(mp, XFS_INO_TO_AGNO(mp, orphanage_ino), XFS_INO_TO_AGINO(mp, orphanage_ino)); -- 1.7.1 From sandeen@sandeen.net Sun Sep 7 11:41:11 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 3D1F07F57 for ; Sun, 7 Sep 2014 11:41:11 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 279028F8033 for ; Sun, 7 Sep 2014 09:41:11 -0700 (PDT) X-ASG-Debug-ID: 1410108066-04cb6c5500839f70001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id KMGNXqrm9647AgSR for ; Sun, 07 Sep 2014 09:41:06 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: by sandeen.net (Postfix, from userid 500) id AF80361A5854; Sun, 7 Sep 2014 11:41:06 -0500 (CDT) From: Eric Sandeen To: xfs@oss.sgi.com Subject: [PATCH 3/5] xfs_repair: fix dir refcount when '.' missing and dir is rebuilt Date: Sun, 7 Sep 2014 11:41:03 -0500 X-ASG-Orig-Subj: [PATCH 3/5] xfs_repair: fix dir refcount when '.' missing and dir is rebuilt Message-Id: <1410108065-18156-4-git-send-email-sandeen@redhat.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1410108065-18156-1-git-send-email-sandeen@redhat.com> References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410108066 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9258 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- In phase 6's longform_dir2_entry_check, if we never find a '.' entry we never add a reference to that entry; if we subsequently rebuild it, '.' gets added, but no ref to it is ever made. This leads to Phase 7 doing i.e.: Phase 7 - verify and correct link counts... resetting inode 5184 nlinks from 2 to 1 and the next run will do: Phase 7 - verify and correct link counts... resetting inode 5184 nlinks from 1 to 2 So if '.' was never found, but the directory got rebuilt, manually add the ref for it. Signed-off-by: Eric Sandeen --- repair/phase6.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/repair/phase6.c b/repair/phase6.c index f13069f..cc36a9c 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -2288,6 +2288,12 @@ out_fix: if (bplist[i]) libxfs_putbuf(bplist[i]); longform_dir2_rebuild(mp, ino, ip, irec, ino_offset, hashtab); + /* + * If we didn't find a dot, we never added a ref for it; + * it's there now after the rebuild, so mark it as reached. + */ + if (*need_dot) + add_inode_ref(irec, ino_offset); *num_illegal = 0; *need_dot = 0; } else { -- 1.7.1 From sandeen@sandeen.net Sun Sep 7 11:41:11 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 902B77F67 for ; Sun, 7 Sep 2014 11:41:11 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6545A304032 for ; Sun, 7 Sep 2014 09:41:08 -0700 (PDT) X-ASG-Debug-ID: 1410108066-04cbb05486ac4430001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id BL0XxqGmH1vDU7PL for ; Sun, 07 Sep 2014 09:41:06 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: by sandeen.net (Postfix, from userid 500) id 9016F61A5852; Sun, 7 Sep 2014 11:41:06 -0500 (CDT) From: Eric Sandeen To: xfs@oss.sgi.com Subject: [PATCH 1/5] xfs_repair: clear bad flgs in process_dinode_int Date: Sun, 7 Sep 2014 11:41:01 -0500 X-ASG-Orig-Subj: [PATCH 1/5] xfs_repair: clear bad flgs in process_dinode_int Message-Id: <1410108065-18156-2-git-send-email-sandeen@redhat.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1410108065-18156-1-git-send-email-sandeen@redhat.com> References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410108066 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9258 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- process_dinode_int() reports bad flags if dino->di_flags & ~XFS_DIFLAG_ANY - i.e. if any flags are set outside the known set. But then instead of clearing them, it does flags &= ~XFS_DIFLAG_ANY which keeps *only* the bad flags. This leads to persistent, unrepairable errors of the form: "Bad flags set in inode XXX" Fix this. While we are at it, fix a couple lines which look like they used to be continuation lines, but are no longer. Signed-off-by: Eric Sandeen --- repair/dinode.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/repair/dinode.c b/repair/dinode.c index 8891e84..38a6562 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -2456,7 +2456,7 @@ _("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"), _("Bad flags set in inode %" PRIu64 "\n"), lino); } - flags &= ~XFS_DIFLAG_ANY; + flags &= XFS_DIFLAG_ANY; } if (flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT)) { @@ -2513,11 +2513,11 @@ _("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"), } if (!verify_mode && flags != be16_to_cpu(dino->di_flags)) { if (!no_modify) { - do_warn(_(", fixing bad flags.\n")); + do_warn(_("fixing bad flags.\n")); dino->di_flags = cpu_to_be16(flags); *dirty = 1; } else - do_warn(_(", would fix bad flags.\n")); + do_warn(_("would fix bad flags.\n")); } } -- 1.7.1 From sandeen@sandeen.net Sun Sep 7 12:02:15 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 4AA457F4E for ; Sun, 7 Sep 2014 12:02:15 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 34A338F8033 for ; Sun, 7 Sep 2014 10:02:12 -0700 (PDT) X-ASG-Debug-ID: 1410109330-04cbb05486ac5110001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id Yk7xD3g7AnUpTVCd for ; Sun, 07 Sep 2014 10:02:11 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id D379761A5851 for ; Sun, 7 Sep 2014 12:02:10 -0500 (CDT) Message-ID: <540C8F92.5050704@sandeen.net> Date: Sun, 07 Sep 2014 12:02:10 -0500 From: Eric Sandeen MIME-Version: 1.0 To: xfs@oss.sgi.com Subject: [PATCH 6/5] xfs_repair: don't re-add root dotdot if root dir was rebuilt References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> X-ASG-Orig-Subj: [PATCH 6/5] xfs_repair: don't re-add root dotdot if root dir was rebuilt In-Reply-To: <1410108065-18156-1-git-send-email-sandeen@redhat.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410109330 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9259 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- If we've rebuilt the root directory, ".." was taken care of, so clear need_root_dotdot. Otherwise it will be added twice, and a subsequent repair will say: entry ".." (ino 5824) in dir 5824 is a duplicate name, would junk entry Signed-off-by: Eric Sandeen --- (sorry for 6/5, this just popped out and is similar to the patch 3/5 I just sent, so probably worth doing at the same time. diff --git a/repair/phase6.c b/repair/phase6.c index cc36a9c..2e67c60 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -2294,6 +2297,9 @@ out_fix: */ if (*need_dot) add_inode_ref(irec, ino_offset); + /* If we rebuilt the root dir, dot dot is in good shape */ + if (ino == mp->m_sb.sb_rootino) + need_root_dotdot = 0; *num_illegal = 0; *need_dot = 0; } else { From sandeen@sandeen.net Sun Sep 7 16:26:20 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D34EE7F4E for ; Sun, 7 Sep 2014 16:26:20 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id B30D58F8033 for ; Sun, 7 Sep 2014 14:26:20 -0700 (PDT) X-ASG-Debug-ID: 1410125170-04bdf0109a7e6000001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id 7H0tln9dnRv5QS78 for ; Sun, 07 Sep 2014 14:26:10 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id D598B610C889; Sun, 7 Sep 2014 16:26:09 -0500 (CDT) Message-ID: <540CCD71.4020507@sandeen.net> Date: Sun, 07 Sep 2014 16:26:09 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Eric Sandeen , xfs@oss.sgi.com Subject: Re: [PATCH 5/5] xfs_repair: set proper ftype when moving to lost+found References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> <1410108065-18156-6-git-send-email-sandeen@redhat.com> X-ASG-Orig-Subj: Re: [PATCH 5/5] xfs_repair: set proper ftype when moving to lost+found In-Reply-To: <1410108065-18156-6-git-send-email-sandeen@redhat.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410125170 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9266 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/7/14 11:41 AM, Eric Sandeen wrote: > When we move files to lost+found, we're setting the > filetype to UNKNOWN. This leaves an inconsistency which > is discovered on a subsequent repair: > > would fix ftype mismatch (0/1) in directory/child inode 5838/5839 > > Setting the proper ftype at the time of the move > resolves this: Ah, arekm points out that Jan already sent a patch to do this: [PATCH] repair: Set ftype for entries in lost+found http://oss.sgi.com/archives/xfs/2014-07/msg00314.html Sorry, missed that. -Eric From david@fromorbit.com Sun Sep 7 18:39:17 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A30067F4E for ; Sun, 7 Sep 2014 18:39:17 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7C1C2304032 for ; Sun, 7 Sep 2014 16:39:17 -0700 (PDT) X-ASG-Debug-ID: 1410133153-04cbb05488acff20001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id qLJfDbKInF0S9oIa for ; Sun, 07 Sep 2014 16:39:14 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvcvAPTrDFR5LKYhPGdsb2JhbABZgw2BKoczqR8BAQEBAQEGmnCFaQEDAQEBgQoXBQEBAQE4N4QEAQU6HCMQCAMYCSUPBSUDBxoTiEG7NQEXGIVkiQhJB4MvgR0FnHGZICsvgQeBSAEBAQ Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 08 Sep 2014 09:09:13 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XQm34-0007qr-QS; Mon, 08 Sep 2014 09:39:10 +1000 Date: Mon, 8 Sep 2014 09:39:10 +1000 From: Dave Chinner To: stan hoeppner Cc: xfs@oss.sgi.com Subject: Re: storage, libaio, or XFS problem? 3.4.26 Message-ID: <20140907233910.GA30012@dastard> X-ASG-Orig-Subj: Re: storage, libaio, or XFS problem? 3.4.26 References: <20140828230817.GU20518@dastard> <2d2ce7bb38c00a7d35f4a324f6a36cbb@localhost> <20140829235538.GF20518@dastard> <20140831235749.GH20518@dastard> <5403E9B9.7040608@hardwarefreak.com> <20140901234529.GI20518@dastard> <5405FB19.2020208@hardwarefreak.com> <20140902221915.GK20518@dastard> <540BEBB7.7020306@hardwarefreak.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540BEBB7.7020306@hardwarefreak.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410133153 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9268 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sun, Sep 07, 2014 at 12:23:03AM -0500, stan hoeppner wrote: > I have some more information regarding the AIO issue. I fired up the > test harness and it ran for 30 hours at 706 MB/s avg write rate, 303 > MB/s per LUN, nearly flawlessly, less than 0.01% buffer loss, and avg IO > times were less than 0.5 seconds. Then the app crashed and I found the > following in dmesg. I had to "hard reset" the box due to the shrapnel. > There are no IO errors of any kind leading up to the forced shutdown. > I assume the inode update and streamRT-sa hung task traces are a result > of the forced shutdown, not a cause of it. In lieu of an xfs_repair > with a version newer than I'm able to install, any ideas what caused the > forced shutdown after 30 hours, given there are no errors preceding it? > > > Sep 6 06:33:33 Anguish-ssu-1 kernel: [288087.334863] XFS (dm-5): > xfs_do_force_shutdown(0x8) called from line 3732 of file > fs/xfs/xfs_bmap.c. Return address = 0xffffffffa02009a6 > Sep 6 06:33:42 Anguish-ssu-1 kernel: [288096.220920] XFS (dm-5): failed > to update timestamps for inode 0x2ffc9caae Hi Stan, can you need to turn off line wrapping for stuff you paste in? It's all but unreadable when it line wraps like this? Next, you need to turn /proc/sys/fs/xfs/error_level up to 11 so that it dumps a stack trace on corruption events. I don't have a (I can't remember what kernel version you are running) tree in front of me to convert that line number to something meaningful, so it's not a great help... Was there anything in the logs before the shutdown? i.e. can you paste the dmesg output from the start of the test (i.e. the mount of the fs) to the end? As it is, all the traces looke like this: > [] schedule+0x64/0x66 > [] rwsem_down_failed_common+0xdb/0x10d > [] rwsem_down_write_failed+0x13/0x15 > [] call_rwsem_down_write_failed+0x13/0x20 > [] ? down_write+0x25/0x27 > [] xfs_ilock+0x4f/0xb4 [xfs] > [] xfs_rw_ilock+0x2c/0x33 [xfs] > [] ? _raw_spin_unlock_irq+0x27/0x32 > [] xfs_file_aio_write_checks+0x41/0xfe [xfs] > [] xfs_file_dio_aio_write+0x103/0x1fc [xfs] > [] xfs_file_aio_write+0x152/0x1b5 [xfs] > [] ? xfs_file_buffered_aio_write+0x179/0x179 [xfs] > [] aio_rw_vect_retry+0x85/0x18a > [] ? aio_fsync+0x29/0x29 > [] aio_run_iocb+0x7b/0x149 > [] io_submit_one+0x199/0x1f3 > [] do_io_submit+0xfa/0x271 > [] sys_io_submit+0x10/0x12 > [] system_call_fastpath+0x16/0x1b Which implies that the shutdown didn't unlock the inode correctly. But without knowing what the call stack at the time of the shutdown was, I can't really tell... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Sun Sep 7 19:10:53 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D78C27F4E for ; Sun, 7 Sep 2014 19:10:53 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 751FBAC004 for ; Sun, 7 Sep 2014 17:10:50 -0700 (PDT) X-ASG-Debug-ID: 1410135047-04cb6c54fe845500001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id yfR4Qt1SZigC7M0n for ; Sun, 07 Sep 2014 17:10:47 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvcvAPHyDFR5LKYhPGdsb2JhbABZgw2BKoczqR8BAQEBAQEGmnCFaQEDAQEBgQoXBQEBAQE4N4QEAQUnExwjEAgDGAklDwUlAwcaE4hBuyUBFxiFZIlRB4MvgR0FnHGMKIx4Ky+CTwEBAQ Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 08 Sep 2014 09:40:46 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XQmXc-0007uk-FQ; Mon, 08 Sep 2014 10:10:44 +1000 Date: Mon, 8 Sep 2014 10:10:44 +1000 From: Dave Chinner To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 4/5] xfs_repair: don't ASSERT on corrupt ftype Message-ID: <20140908001044.GB30012@dastard> X-ASG-Orig-Subj: Re: [PATCH 4/5] xfs_repair: don't ASSERT on corrupt ftype References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> <1410108065-18156-5-git-send-email-sandeen@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1410108065-18156-5-git-send-email-sandeen@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410135047 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9268 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sun, Sep 07, 2014 at 11:41:04AM -0500, Eric Sandeen wrote: > xfs_dir3_dirent_get_ftype() gets the file type > off disk, but ASSERTs if it's invalid: > > ASSERT(type < XFS_DIR3_FT_MAX); > > This might be cut & paste from > xfs_dir3_dirent_put_ftype which should be checking > that it's not been passed bad values, but we > shouldn't ASSERT on bad values read from disk. > > Signed-off-by: Eric Sandeen > --- > include/xfs_da_format.h | 1 - > 1 files changed, 0 insertions(+), 1 deletions(-) > > diff --git a/include/xfs_da_format.h b/include/xfs_da_format.h > index 89a1a21..11f1420 100644 > --- a/include/xfs_da_format.h > +++ b/include/xfs_da_format.h > @@ -561,7 +561,6 @@ xfs_dir3_dirent_get_ftype( > if (xfs_sb_version_hasftype(&mp->m_sb)) { > __uint8_t type = dep->name[dep->namelen]; > > - ASSERT(type < XFS_DIR3_FT_MAX); > if (type < XFS_DIR3_FT_MAX) > return type; Needs to be fixed kernel-side first. Cheers, Dave. -- Dave Chinner david@fromorbit.com From sandeen@sandeen.net Sun Sep 7 20:02:26 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 92C9A7F4E for ; Sun, 7 Sep 2014 20:02:26 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 72EAC8F8033 for ; Sun, 7 Sep 2014 18:02:23 -0700 (PDT) X-ASG-Debug-ID: 1410138141-04bdf0109a7ea080001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id 9DkY5ZU4V97taWjI for ; Sun, 07 Sep 2014 18:02:21 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 43CBB610C889; Sun, 7 Sep 2014 20:02:21 -0500 (CDT) Message-ID: <540D001C.6020607@sandeen.net> Date: Sun, 07 Sep 2014 20:02:20 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Dave Chinner , Eric Sandeen CC: xfs@oss.sgi.com Subject: Re: [PATCH 4/5] xfs_repair: don't ASSERT on corrupt ftype References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> <1410108065-18156-5-git-send-email-sandeen@redhat.com> <20140908001044.GB30012@dastard> X-ASG-Orig-Subj: Re: [PATCH 4/5] xfs_repair: don't ASSERT on corrupt ftype In-Reply-To: <20140908001044.GB30012@dastard> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410138141 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9269 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/7/14 7:10 PM, Dave Chinner wrote: > On Sun, Sep 07, 2014 at 11:41:04AM -0500, Eric Sandeen wrote: ... >> diff --git a/include/xfs_da_format.h b/include/xfs_da_format.h >> index 89a1a21..11f1420 100644 >> --- a/include/xfs_da_format.h >> +++ b/include/xfs_da_format.h >> @@ -561,7 +561,6 @@ xfs_dir3_dirent_get_ftype( >> if (xfs_sb_version_hasftype(&mp->m_sb)) { >> __uint8_t type = dep->name[dep->namelen]; >> >> - ASSERT(type < XFS_DIR3_FT_MAX); >> if (type < XFS_DIR3_FT_MAX) >> return type; > > Needs to be fixed kernel-side first. xfs_dir3_dirent_get_ftype doesn't exist in kernelspace :) bleah, why do they have different names... Ok, will send. -Eric > Cheers, > > Dave. > From sandeen@redhat.com Sun Sep 7 20:06:43 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 087277F4E for ; Sun, 7 Sep 2014 20:06:43 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8C051AC005 for ; Sun, 7 Sep 2014 18:06:39 -0700 (PDT) X-ASG-Debug-ID: 1410138397-04cbb05485ad13f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id f7ta5HIZ1mzQg91A (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sun, 07 Sep 2014 18:06:38 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8816aPM004074 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Sun, 7 Sep 2014 21:06:36 -0400 Received: from liberator.sandeen.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8816ZeT015328 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Sun, 7 Sep 2014 21:06:36 -0400 Message-ID: <540D011B.2000807@redhat.com> Date: Sun, 07 Sep 2014 20:06:35 -0500 From: Eric Sandeen MIME-Version: 1.0 To: xfs-oss Subject: [PATCH] xfs: don't ASSERT on corrupt ftype Content-Type: text/plain; charset=utf-8; format=flowed X-ASG-Orig-Subj: [PATCH] xfs: don't ASSERT on corrupt ftype Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410138397 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xfs_dir3_data_get_ftype() and xfs_dir2_sf_check() get the file type off disk, but ASSERT if it's invalid: ASSERT(type < XFS_DIR3_FT_MAX); This might be cut & paste from the "put" functions, which should be checking that they've not been passed bad values, but we shouldn't ASSERT on bad values read from disk. Signed-off-by: Eric Sandeen --- diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index c9aee52..7e42fdf 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -270,7 +270,6 @@ xfs_dir3_data_get_ftype( { __uint8_t ftype = dep->name[dep->namelen]; - ASSERT(ftype < XFS_DIR3_FT_MAX); if (ftype >= XFS_DIR3_FT_MAX) return XFS_DIR3_FT_UNKNOWN; return ftype; diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c index 5079e05..ea89250 100644 --- a/fs/xfs/libxfs/xfs_dir2_sf.c +++ b/fs/xfs/libxfs/xfs_dir2_sf.c @@ -635,7 +635,6 @@ xfs_dir2_sf_check( offset = xfs_dir2_sf_get_offset(sfep) + dp->d_ops->data_entsize(sfep->namelen); - ASSERT(dp->d_ops->sf_get_ftype(sfep) < XFS_DIR3_FT_MAX); } ASSERT(i8count == sfp->i8count); ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size); From david@fromorbit.com Sun Sep 7 22:16:52 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 4E9AD7F4E for ; Sun, 7 Sep 2014 22:16:52 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 2DB938F8039 for ; Sun, 7 Sep 2014 20:16:49 -0700 (PDT) X-ASG-Debug-ID: 1410146206-04bdf0109a7eca50001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id CC3kgWbifR2mP6JX for ; Sun, 07 Sep 2014 20:16:47 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ArY4AAMfDVR5LKYhPGdsb2JhbABZgw2BKoczqSEBAgEBAQaacIVpAQMBAQGBDhcFAQEBATg3hAQBBScTHCMQCAMYCSUPBSUDBxoTiEG6dAEXGIVkiVEHhEwFnHGMKIx4Ky+CTwEBAQ Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail06.adl6.internode.on.net with ESMTP; 08 Sep 2014 12:46:46 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XQpRc-0008Et-3h; Mon, 08 Sep 2014 13:16:44 +1000 Date: Mon, 8 Sep 2014 13:16:44 +1000 From: Dave Chinner To: Eric Sandeen Cc: Eric Sandeen , xfs@oss.sgi.com Subject: Re: [PATCH 4/5] xfs_repair: don't ASSERT on corrupt ftype Message-ID: <20140908031644.GZ20518@dastard> X-ASG-Orig-Subj: Re: [PATCH 4/5] xfs_repair: don't ASSERT on corrupt ftype References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> <1410108065-18156-5-git-send-email-sandeen@redhat.com> <20140908001044.GB30012@dastard> <540D001C.6020607@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540D001C.6020607@sandeen.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1410146206 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9271 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sun, Sep 07, 2014 at 08:02:20PM -0500, Eric Sandeen wrote: > On 9/7/14 7:10 PM, Dave Chinner wrote: > >On Sun, Sep 07, 2014 at 11:41:04AM -0500, Eric Sandeen wrote: > > ... > > >>diff --git a/include/xfs_da_format.h b/include/xfs_da_format.h > >>index 89a1a21..11f1420 100644 > >>--- a/include/xfs_da_format.h > >>+++ b/include/xfs_da_format.h > >>@@ -561,7 +561,6 @@ xfs_dir3_dirent_get_ftype( > >> if (xfs_sb_version_hasftype(&mp->m_sb)) { > >> __uint8_t type = dep->name[dep->namelen]; > >> > >>- ASSERT(type < XFS_DIR3_FT_MAX); > >> if (type < XFS_DIR3_FT_MAX) > >> return type; > > > >Needs to be fixed kernel-side first. > > xfs_dir3_dirent_get_ftype doesn't exist in kernelspace :) > > bleah, why do they have different names... Ok, will send. Because kernel has changed, and we need to do yet another large kernel/user libxfs sync. I haven't found time to do that yet. Unless you want to volunteer for it.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From sandeen@sandeen.net Sun Sep 7 22:18:14 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id DC5F77F4E for ; Sun, 7 Sep 2014 22:18:14 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7A64AAC004 for ; Sun, 7 Sep 2014 20:18:11 -0700 (PDT) X-ASG-Debug-ID: 1410146289-04cbb05487ad39d0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id Mh3XGqy4WvM6hBgz for ; Sun, 07 Sep 2014 20:18:09 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 3716563D57C0; Sun, 7 Sep 2014 22:18:09 -0500 (CDT) Message-ID: <540D1FF1.4030601@sandeen.net> Date: Sun, 07 Sep 2014 22:18:09 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Dave Chinner CC: Eric Sandeen , xfs@oss.sgi.com Subject: Re: [PATCH 4/5] xfs_repair: don't ASSERT on corrupt ftype References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> <1410108065-18156-5-git-send-email-sandeen@redhat.com> <20140908001044.GB30012@dastard> <540D001C.6020607@sandeen.net> <20140908031644.GZ20518@dastard> X-ASG-Orig-Subj: Re: [PATCH 4/5] xfs_repair: don't ASSERT on corrupt ftype In-Reply-To: <20140908031644.GZ20518@dastard> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410146289 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9271 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/7/14 10:16 PM, Dave Chinner wrote: > On Sun, Sep 07, 2014 at 08:02:20PM -0500, Eric Sandeen wrote: >> On 9/7/14 7:10 PM, Dave Chinner wrote: ... >>> Needs to be fixed kernel-side first. >> >> xfs_dir3_dirent_get_ftype doesn't exist in kernelspace :) >> >> bleah, why do they have different names... Ok, will send. > > Because kernel has changed, and we need to do yet another large > kernel/user libxfs sync. > > I haven't found time to do that yet. Unless you want to volunteer > for it.... I could give it a shot. Do you usually do it commit-by-commit, diff-and-edit, or a big copy? -Eric From david@fromorbit.com Mon Sep 8 01:23:31 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 252037F4E for ; Mon, 8 Sep 2014 01:23:31 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id B784AAC001 for ; Sun, 7 Sep 2014 23:23:27 -0700 (PDT) X-ASG-Debug-ID: 1410157404-04bdf010977f09e0001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id bVgIa2gdF8MBdoZe for ; Sun, 07 Sep 2014 23:23:25 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ArU4ALlKDVR5LKYhPGdsb2JhbABXgw2BKoczqSQBAgEBAQaacIVpAQMBAQGBDhcFAQEBATg3hAQBBTocIxAIAxgJJQ8FJQMHGhOIQbp7ARcYhWSJUQeDL4EdBZxxjCiMeCsvgk8BAQE Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail06.adl6.internode.on.net with ESMTP; 08 Sep 2014 15:53:24 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XQsME-00007K-19; Mon, 08 Sep 2014 16:23:22 +1000 Date: Mon, 8 Sep 2014 16:23:22 +1000 From: Dave Chinner To: Eric Sandeen Cc: Eric Sandeen , xfs@oss.sgi.com Subject: Re: [PATCH 4/5] xfs_repair: don't ASSERT on corrupt ftype Message-ID: <20140908062321.GA20518@dastard> X-ASG-Orig-Subj: Re: [PATCH 4/5] xfs_repair: don't ASSERT on corrupt ftype References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> <1410108065-18156-5-git-send-email-sandeen@redhat.com> <20140908001044.GB30012@dastard> <540D001C.6020607@sandeen.net> <20140908031644.GZ20518@dastard> <540D1FF1.4030601@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540D1FF1.4030601@sandeen.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1410157405 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9275 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sun, Sep 07, 2014 at 10:18:09PM -0500, Eric Sandeen wrote: > On 9/7/14 10:16 PM, Dave Chinner wrote: > >On Sun, Sep 07, 2014 at 08:02:20PM -0500, Eric Sandeen wrote: > >>On 9/7/14 7:10 PM, Dave Chinner wrote: > > ... > > >>>Needs to be fixed kernel-side first. > >> > >>xfs_dir3_dirent_get_ftype doesn't exist in kernelspace :) > >> > >>bleah, why do they have different names... Ok, will send. > > > >Because kernel has changed, and we need to do yet another large > >kernel/user libxfs sync. > > > >I haven't found time to do that yet. Unless you want to volunteer > >for it.... > > I could give it a shot. Do you usually do it commit-by-commit, > diff-and-edit, or a big copy? This one is going to need multiple phases, and in a moment you're going to understand what all functions called into libxfs should have a "libxfs define wrapper": 1. sync up to kernel commit before error negation 2. make sure all external function calls have libxfs define wrappers 3. commit error negation patch and change sign of all libxfs define wrappers 4. apply kernel libxfs rename patch and restructure libxfs userspace and xfsprogs build to match 5. continue syncing kernel changes commit by commit. Given the scope of changes, and the fact that some of the changes have already been applied (i.e. bug fixes, finobt changes, etc) step #1 is not going to be a straight forward commit-by-commit. So I'm happy to do that as a bulk commit. Steps #2 and #3 are relatively straight forward, too, just a bit painful as we need to be sure we don't leak negative errors. Step #4 is the big one; we want to end up with the kernel fs/xfs/libxfs to be identical to the xfsprogs:/libxfs/ code and so in userspace we've got to move headers around and rejig includes and things like that. That's one I should probably do. And from there, step 5 should be a simple extract/sed/commit process of pulling patch by patch from the kernel changes that touch fs/xfs/libxfs.... So, really, the big step right now is #1... Cheers, Dave. -- Dave Chinner david@fromorbit.com From s.priebe@profihost.ag Mon Sep 8 03:36:01 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1D5667F4E for ; Mon, 8 Sep 2014 03:36:01 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 84E0BAC006 for ; Mon, 8 Sep 2014 01:36:00 -0700 (PDT) X-ASG-Debug-ID: 1410165357-04cb6c54ff84f9c0001-NocioJ Received: from mail-ph.de-nserver.de (mail-ph.de-nserver.de [85.158.179.214]) by cuda.sgi.com with ESMTP id 8nsJXNHI6YEaFaRR (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 08 Sep 2014 01:35:58 -0700 (PDT) X-Barracuda-Envelope-From: s.priebe@profihost.ag X-Barracuda-Apparent-Source-IP: 85.158.179.214 Received: (qmail 12091 invoked from network); 8 Sep 2014 10:35:57 +0200 X-Fcrdns: No Received: from phoffice.de-nserver.de (HELO [10.11.11.93]) (185.39.223.5) (smtp-auth username hostmaster@profihost.com, mechanism plain) by mail-ph.de-nserver.de (qpsmtpd/0.92) with (ECDHE-RSA-AES256-SHA encrypted) ESMTPSA; Mon, 08 Sep 2014 10:35:57 +0200 Message-ID: <540D6A6C.9090801@profihost.ag> Date: Mon, 08 Sep 2014 10:35:56 +0200 From: Stefan Priebe - Profihost AG User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.0 MIME-Version: 1.0 To: Dave Chinner , Brian Foster CC: "xfs@oss.sgi.com" Subject: Re: Is XFS suitable for 350 million files on 20TB storage? References: <540986B1.4080306@profihost.ag> <20140905123058.GA29710@bfoster.bfoster> <5409AF40.10801@profihost.ag> <20140905230528.GO20473@dastard> <540AB933.4030707@profihost.ag> <20140906150412.GB23506@bfoster.bfoster> <20140906225654.GB9955@dastard> X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? In-Reply-To: <20140906225654.GB9955@dastard> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-User-Auth: Auth by hostmaster@profihost.com through 185.39.223.5 X-Barracuda-Connect: mail-ph.de-nserver.de[85.158.179.214] X-Barracuda-Start-Time: 1410165358 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9277 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Thanks, upgraded to 3.16.2 and xfsprogs 3.2.1. Let's see how it behaves with finobt. Greets, Stefan Am 07.09.2014 um 00:56 schrieb Dave Chinner: > On Sat, Sep 06, 2014 at 11:04:13AM -0400, Brian Foster wrote: >> On Sat, Sep 06, 2014 at 09:35:15AM +0200, Stefan Priebe wrote: >>> Hi Dave, >>> >>> Am 06.09.2014 01:05, schrieb Dave Chinner: >>>> On Fri, Sep 05, 2014 at 02:40:32PM +0200, Stefan Priebe - Profihost AG wrote: >>>>> >>>>> Am 05.09.2014 um 14:30 schrieb Brian Foster: >>>>>> On Fri, Sep 05, 2014 at 11:47:29AM +0200, Stefan Priebe - Profihost AG wrote: >>>>>>> Hi, >>>>>>> >>>>>>> i have a backup system running 20TB of storage having 350 million files. >>>>>>> This was working fine for month. >>>>>>> >>>>>>> But now the free space is so heavily fragmented that i only see the >>>>>>> kworker with 4x 100% CPU and write speed beeing very slow. 15TB of the >>>>>>> 20TB are in use. >>>> >>>> What does perf tell you about the CPU being burnt? (i.e run perf top >>>> for 10-20s while that CPU burn is happening and paste the top 10 CPU >>>> consuming functions). >>> >>> here we go: >>> 15,79% [kernel] [k] xfs_inobt_get_rec >>> 14,57% [kernel] [k] xfs_btree_get_rec >>> 10,37% [kernel] [k] xfs_btree_increment >>> 7,20% [kernel] [k] xfs_btree_get_block >>> 6,13% [kernel] [k] xfs_btree_rec_offset >>> 4,90% [kernel] [k] xfs_dialloc_ag >>> 3,53% [kernel] [k] xfs_btree_readahead >>> 2,87% [kernel] [k] xfs_btree_rec_addr >>> 2,80% [kernel] [k] _xfs_buf_find >>> 1,94% [kernel] [k] intel_idle >>> 1,49% [kernel] [k] _raw_spin_lock >>> 1,13% [kernel] [k] copy_pte_range >>> 1,10% [kernel] [k] unmap_single_vma >>> >> >> The top 6 or so items look related to inode allocation, so that probably >> confirms the primary bottleneck as searching around for free inodes out >> of the existing inode chunks, precisely what the finobt is intended to >> resolve. That was introduced in 3.16 kernels, so unfortunately it is not >> available in 3.10. > > *nod* > > Again, the only workaround for this on a non-finobt fs is to greatly > increase the number of AGs so there's less records in each btree to > search. > > Cheers, > > Dave. > From david@fromorbit.com Mon Sep 8 04:47:19 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 564B67F4E for ; Mon, 8 Sep 2014 04:47:19 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 366668F8040 for ; Mon, 8 Sep 2014 02:47:16 -0700 (PDT) X-ASG-Debug-ID: 1410169633-04cb6c54fe851ba0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id epdsR31eE5pxGU4g for ; Mon, 08 Sep 2014 02:47:14 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AkkqAKZ6DVR5LKYh/2dsb2JhbABZgw2BKrBWAQIBAQEGmnCFaQEDAQEBgRQXeIQEAQU6HCMQCAMYCSUPBSUDIROIQbtTARcYhWSJCAdCB4MvgR0BBJxxlS2DcysvgQcBHoEpAQEB Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail07.adl2.internode.on.net with ESMTP; 08 Sep 2014 19:17:12 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XQvXH-0000aH-9T; Mon, 08 Sep 2014 19:46:59 +1000 Date: Mon, 8 Sep 2014 19:46:59 +1000 From: Dave Chinner To: Stefan Priebe - Profihost AG Cc: Brian Foster , "xfs@oss.sgi.com" Subject: Re: Is XFS suitable for 350 million files on 20TB storage? Message-ID: <20140908094659.GC30012@dastard> X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? References: <540986B1.4080306@profihost.ag> <20140905123058.GA29710@bfoster.bfoster> <5409AF40.10801@profihost.ag> <20140905230528.GO20473@dastard> <540AB933.4030707@profihost.ag> <20140906150412.GB23506@bfoster.bfoster> <20140906225654.GB9955@dastard> <540D6A6C.9090801@profihost.ag> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540D6A6C.9090801@profihost.ag> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1410169633 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9278 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Sep 08, 2014 at 10:35:56AM +0200, Stefan Priebe - Profihost AG wrote: > Thanks, > > upgraded to 3.16.2 and xfsprogs 3.2.1. Let's see how it behaves with finobt. You need to mkfs the filesystem to use finobt - it's not something that an upgrade will just switch on. i.e. # mkfs.xfs -m crc=1,finobt=1 Cheers, Dave. -- Dave Chinner david@fromorbit.com From s.priebe@profihost.ag Mon Sep 8 04:49:23 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E1A1C7F4E for ; Mon, 8 Sep 2014 04:49:23 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id CEBE68F8040 for ; Mon, 8 Sep 2014 02:49:23 -0700 (PDT) X-ASG-Debug-ID: 1410169761-04cb6c5500851ce0001-NocioJ Received: from mail-ph.de-nserver.de (mail-ph.de-nserver.de [85.158.179.214]) by cuda.sgi.com with ESMTP id N7c3WwZzxpPu9DWf (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 08 Sep 2014 02:49:22 -0700 (PDT) X-Barracuda-Envelope-From: s.priebe@profihost.ag X-Barracuda-Apparent-Source-IP: 85.158.179.214 Received: (qmail 3600 invoked from network); 8 Sep 2014 11:49:20 +0200 X-Fcrdns: No Received: from phoffice.de-nserver.de (HELO [10.11.11.93]) (185.39.223.5) (smtp-auth username hostmaster@profihost.com, mechanism plain) by mail-ph.de-nserver.de (qpsmtpd/0.92) with (ECDHE-RSA-AES256-SHA encrypted) ESMTPSA; Mon, 08 Sep 2014 11:49:20 +0200 Message-ID: <540D7BA0.6090107@profihost.ag> Date: Mon, 08 Sep 2014 11:49:20 +0200 From: Stefan Priebe - Profihost AG User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.0 MIME-Version: 1.0 To: Dave Chinner CC: Brian Foster , "xfs@oss.sgi.com" Subject: Re: Is XFS suitable for 350 million files on 20TB storage? References: <540986B1.4080306@profihost.ag> <20140905123058.GA29710@bfoster.bfoster> <5409AF40.10801@profihost.ag> <20140905230528.GO20473@dastard> <540AB933.4030707@profihost.ag> <20140906150412.GB23506@bfoster.bfoster> <20140906225654.GB9955@dastard> <540D6A6C.9090801@profihost.ag> <20140908094659.GC30012@dastard> X-ASG-Orig-Subj: Re: Is XFS suitable for 350 million files on 20TB storage? In-Reply-To: <20140908094659.GC30012@dastard> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-User-Auth: Auth by hostmaster@profihost.com through 185.39.223.5 X-Barracuda-Connect: mail-ph.de-nserver.de[85.158.179.214] X-Barracuda-Start-Time: 1410169762 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9278 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Am 08.09.2014 um 11:46 schrieb Dave Chinner: > On Mon, Sep 08, 2014 at 10:35:56AM +0200, Stefan Priebe - Profihost AG wrote: >> Thanks, >> >> upgraded to 3.16.2 and xfsprogs 3.2.1. Let's see how it behaves with finobt. > > You need to mkfs the filesystem to use finobt - it's not something > that an upgrade will just switch on. i.e. > > # mkfs.xfs -m crc=1,finobt=1 Sure i also did a reformat using "-m crc=1,finobt=1". Stefan > Cheers, > > Dave. > From david@fromorbit.com Mon Sep 8 05:48:12 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 6D0A17F4E for ; Mon, 8 Sep 2014 05:48:12 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 5AA668F8039 for ; Mon, 8 Sep 2014 03:48:09 -0700 (PDT) X-ASG-Debug-ID: 1410173283-04cbb05486adfb70001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id Y5AIPJYOAuCT0Ldf for ; Mon, 08 Sep 2014 03:48:03 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AjsgAMiIDVR5LKYh/2dsb2JhbABZgw2BKoIsrjAGmm+FaQEDAQEBgRQXeIQEAQU6HCMQCAMOCgklDwUlAyETiEG7MQEXGIVkiQRNB4RMBZxxlS2CG4FYKy+BB4FIAQEB Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail07.adl2.internode.on.net with ESMTP; 08 Sep 2014 20:18:02 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XQwU9-0000mv-Iv; Mon, 08 Sep 2014 20:47:49 +1000 Date: Mon, 8 Sep 2014 20:47:49 +1000 From: Dave Chinner To: Brian Foster Cc: fstests@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH 2/2] xfs/051: test buffer use after free race on I/O failure in XFS log recovery Message-ID: <20140908104749.GI30012@dastard> X-ASG-Orig-Subj: Re: [PATCH 2/2] xfs/051: test buffer use after free race on I/O failure in XFS log recovery References: <1409667761-50248-1-git-send-email-bfoster@redhat.com> <1409667761-50248-3-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1409667761-50248-3-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1410173283 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=MARKETING_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9279 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words On Tue, Sep 02, 2014 at 10:22:41AM -0400, Brian Foster wrote: > A buffer use after free race was discovered in the XFS log recovery > codepath if I/O failures occur during recovery. The I/O submission path > can abort the mount and release the only reference held on some buffers > before I/O completion processing (e.g., async workqueue processing) > might have completed. Badness ensues if the I/O completion path > subsequently attempts to access said buffers. ..... > > case goes to Alex Lyakas. > index 4d35df5..9784dea 100644 > --- a/tests/xfs/group > +++ b/tests/xfs/group > @@ -47,6 +47,7 @@ > 048 other auto quick > 049 rw auto quick > 050 quota auto quick > +051 dangerous I'm going to consider this auto/log/metadata rather than dangerous. Once the bug is fixed, we want to continue running this test as a regression test, and nobody does that with the dangerous group.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From bfoster@redhat.com Mon Sep 8 07:03:45 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 45F9F7F4E for ; Mon, 8 Sep 2014 07:03:45 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 261368F8033 for ; Mon, 8 Sep 2014 05:03:41 -0700 (PDT) X-ASG-Debug-ID: 1410177820-04bdf0109a7fc560001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 8ie6vAjgCl7F3FHD (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 08 Sep 2014 05:03:41 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s88C3dEw023957 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Mon, 8 Sep 2014 08:03:40 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s88C3dlV018647; Mon, 8 Sep 2014 08:03:39 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 899721256F8; Mon, 8 Sep 2014 08:03:38 -0400 (EDT) Date: Mon, 8 Sep 2014 08:03:38 -0400 From: Brian Foster To: Eric Sandeen Cc: xfs-oss Subject: Re: [PATCH] xfs: don't ASSERT on corrupt ftype Message-ID: <20140908120336.GA50018@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs: don't ASSERT on corrupt ftype References: <540D011B.2000807@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540D011B.2000807@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410177821 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Sun, Sep 07, 2014 at 08:06:35PM -0500, Eric Sandeen wrote: > xfs_dir3_data_get_ftype() and xfs_dir2_sf_check() get > the file type off disk, but ASSERT if it's invalid: > > ASSERT(type < XFS_DIR3_FT_MAX); > > This might be cut & paste from the "put" functions, > which should be checking that they've not been passed > bad values, but we shouldn't ASSERT on bad values > read from disk. > Does this lead to a problem of some kind in a valid configuration? > Signed-off-by: Eric Sandeen > --- > > diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c > index c9aee52..7e42fdf 100644 > --- a/fs/xfs/libxfs/xfs_da_format.c > +++ b/fs/xfs/libxfs/xfs_da_format.c > @@ -270,7 +270,6 @@ xfs_dir3_data_get_ftype( > { > __uint8_t ftype = dep->name[dep->namelen]; > - ASSERT(ftype < XFS_DIR3_FT_MAX); > if (ftype >= XFS_DIR3_FT_MAX) > return XFS_DIR3_FT_UNKNOWN; > return ftype; > diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c > index 5079e05..ea89250 100644 > --- a/fs/xfs/libxfs/xfs_dir2_sf.c > +++ b/fs/xfs/libxfs/xfs_dir2_sf.c > @@ -635,7 +635,6 @@ xfs_dir2_sf_check( > offset = > xfs_dir2_sf_get_offset(sfep) + > dp->d_ops->data_entsize(sfep->namelen); > - ASSERT(dp->d_ops->sf_get_ftype(sfep) < XFS_DIR3_FT_MAX); This one is a DEBUG mode only function and the comment suggests the intent is to assert on directory inconsistency..? Brian > } > ASSERT(i8count == sfp->i8count); > ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size); > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From david@fromorbit.com Mon Sep 8 08:05:29 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id AFDF97F51 for ; Mon, 8 Sep 2014 08:05:29 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8FD50304039 for ; Mon, 8 Sep 2014 06:05:26 -0700 (PDT) X-ASG-Debug-ID: 1410181520-04bdf010a07ff450001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id fVWRQPkfBqmnRqQO for ; Mon, 08 Sep 2014 06:05:21 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Aj0gAG6oDVR5LKYh/2dsb2JhbABZgw2BKoIsrjAGmm+FaQEDAQEBgREXeIQDAQEEAScTHCMFCwgDGAklDwUlAyETiDoHun8BFxiFZIlRB4RMBZxxlS2DcysvgQgkgSMBAQE Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail07.adl2.internode.on.net with ESMTP; 08 Sep 2014 22:35:20 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XQyd1-0001BF-5o; Mon, 08 Sep 2014 23:05:07 +1000 Date: Mon, 8 Sep 2014 23:05:07 +1000 From: Dave Chinner To: Eric Sandeen Cc: xfs-oss Subject: Re: [PATCH] xfs: don't ASSERT on corrupt ftype Message-ID: <20140908130507.GN30012@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs: don't ASSERT on corrupt ftype References: <540D011B.2000807@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540D011B.2000807@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1410181520 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9281 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sun, Sep 07, 2014 at 08:06:35PM -0500, Eric Sandeen wrote: > xfs_dir3_data_get_ftype() and xfs_dir2_sf_check() get > the file type off disk, but ASSERT if it's invalid: > > ASSERT(type < XFS_DIR3_FT_MAX); > > This might be cut & paste from the "put" functions, > which should be checking that they've not been passed > bad values, but we shouldn't ASSERT on bad values > read from disk. No, they weren't cut-n-paste from the put functions. They were actually designed for a metadata block where bad values would not be written to disk, and corrupted disk blocks would be detected by CRC validation failures. So on debug kernels it's quite appropriate to assert fail on a "should never, ever happen" condition. Then the v4 ftype feature bit was rammed in but none of the code got changed to reflect that the values in the ftype fields are not CRC protected on v4 filesystems.... > diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c > index 5079e05..ea89250 100644 > --- a/fs/xfs/libxfs/xfs_dir2_sf.c > +++ b/fs/xfs/libxfs/xfs_dir2_sf.c > @@ -635,7 +635,6 @@ xfs_dir2_sf_check( > offset = > xfs_dir2_sf_get_offset(sfep) + > dp->d_ops->data_entsize(sfep->namelen); > - ASSERT(dp->d_ops->sf_get_ftype(sfep) < XFS_DIR3_FT_MAX); > } > ASSERT(i8count == sfp->i8count); > ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size); That's a debug only function validating that the shortform directory is internally consistent. And as the comment says: /* * Check consistency of shortform directory, assert if bad. */ So that assert should remain because it's checking the in-memory state immediately before, during and after modifications are made to the directory, not when it has just been read of disk.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From bfoster@redhat.com Mon Sep 8 08:45:18 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 8E0407F4E for ; Mon, 8 Sep 2014 08:45:18 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7C698304039 for ; Mon, 8 Sep 2014 06:45:18 -0700 (PDT) X-ASG-Debug-ID: 1410183913-04cb6c54fe85b760001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id HzPDip6jJKyjY2JC (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 08 Sep 2014 06:45:14 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s88DjDOH001935 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Mon, 8 Sep 2014 09:45:13 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s88DjDQQ005008; Mon, 8 Sep 2014 09:45:13 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 3F38A1256F8; Mon, 8 Sep 2014 09:45:12 -0400 (EDT) Date: Mon, 8 Sep 2014 09:45:12 -0400 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/5] xfs_repair: clear bad flgs in process_dinode_int Message-ID: <20140908134510.GA52419@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 1/5] xfs_repair: clear bad flgs in process_dinode_int References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> <1410108065-18156-2-git-send-email-sandeen@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1410108065-18156-2-git-send-email-sandeen@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410183914 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Sun, Sep 07, 2014 at 11:41:01AM -0500, Eric Sandeen wrote: > process_dinode_int() reports bad flags if > dino->di_flags & ~XFS_DIFLAG_ANY - i.e. if > any flags are set outside the known set. But > then instead of clearing them, it does > flags &= ~XFS_DIFLAG_ANY which keeps *only* > the bad flags. This leads to persistent, > unrepairable errors of the form: > > "Bad flags set in inode XXX" > > Fix this. > > While we are at it, fix a couple lines which > look like they used to be continuation lines, > but are no longer. > > Signed-off-by: Eric Sandeen > --- Reviewed-by: Brian Foster > repair/dinode.c | 6 +++--- > 1 files changed, 3 insertions(+), 3 deletions(-) > > diff --git a/repair/dinode.c b/repair/dinode.c > index 8891e84..38a6562 100644 > --- a/repair/dinode.c > +++ b/repair/dinode.c > @@ -2456,7 +2456,7 @@ _("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"), > _("Bad flags set in inode %" PRIu64 "\n"), > lino); > } > - flags &= ~XFS_DIFLAG_ANY; > + flags &= XFS_DIFLAG_ANY; > } > > if (flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT)) { > @@ -2513,11 +2513,11 @@ _("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"), > } > if (!verify_mode && flags != be16_to_cpu(dino->di_flags)) { > if (!no_modify) { > - do_warn(_(", fixing bad flags.\n")); > + do_warn(_("fixing bad flags.\n")); > dino->di_flags = cpu_to_be16(flags); > *dirty = 1; > } else > - do_warn(_(", would fix bad flags.\n")); > + do_warn(_("would fix bad flags.\n")); > } > } > > -- > 1.7.1 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Mon Sep 8 08:45:22 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 5C3DC7F53 for ; Mon, 8 Sep 2014 08:45:22 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 3C43A304048 for ; Mon, 8 Sep 2014 06:45:22 -0700 (PDT) X-ASG-Debug-ID: 1410183920-04cbb05486ae6a50001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id be85qj5KNO6gcPNf (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 08 Sep 2014 06:45:21 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s88DjK2r001966 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Mon, 8 Sep 2014 09:45:20 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s88DjKDQ003079; Mon, 8 Sep 2014 09:45:20 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 3FF0D1256F8; Mon, 8 Sep 2014 09:45:19 -0400 (EDT) Date: Mon, 8 Sep 2014 09:45:19 -0400 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/5] xfs_repair: preserve error state in process_shortform_attr Message-ID: <20140908134518.GB52419@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 2/5] xfs_repair: preserve error state in process_shortform_attr References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> <1410108065-18156-3-git-send-email-sandeen@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1410108065-18156-3-git-send-email-sandeen@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410183921 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Sun, Sep 07, 2014 at 11:41:02AM -0500, Eric Sandeen wrote: > process_shortform_attr uses the "junkit" error to > track whether an error was found, but by assigning > it directly to the result of valuecheck, previous > errors are ignored, leading to unrepairable errors > of the form i.e. > > "entry has INCOMPLETE flag on in shortform attribute" > or > "entry contains illegal character in shortform attribute name" > > Signed-off-by: Eric Sandeen > --- Reviewed-by: Brian Foster > repair/attr_repair.c | 3 ++- > 1 files changed, 2 insertions(+), 1 deletions(-) > > diff --git a/repair/attr_repair.c b/repair/attr_repair.c > index a27a3ec..d60b664 100644 > --- a/repair/attr_repair.c > +++ b/repair/attr_repair.c > @@ -914,7 +914,8 @@ process_shortform_attr( > > /* Only check values for root security attributes */ > if (currententry->flags & XFS_ATTR_ROOT) > - junkit = valuecheck(mp, (char *)¤tentry->nameval[0], > + junkit |= valuecheck(mp, > + (char *)¤tentry->nameval[0], > NULL, currententry->namelen, > currententry->valuelen); > > -- > 1.7.1 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Mon Sep 8 08:45:28 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6FE847F57 for ; Mon, 8 Sep 2014 08:45:28 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5EB44304039 for ; Mon, 8 Sep 2014 06:45:28 -0700 (PDT) X-ASG-Debug-ID: 1410183926-04cb6c54fe85b790001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Hsi9BQaukiW9Hf9P (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 08 Sep 2014 06:45:27 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s88DjQJR012487 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Mon, 8 Sep 2014 09:45:26 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s88DjQNM005117; Mon, 8 Sep 2014 09:45:26 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 6D6161256F8; Mon, 8 Sep 2014 09:45:25 -0400 (EDT) Date: Mon, 8 Sep 2014 09:45:25 -0400 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 3/5] xfs_repair: fix dir refcount when '.' missing and dir is rebuilt Message-ID: <20140908134524.GC52419@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 3/5] xfs_repair: fix dir refcount when '.' missing and dir is rebuilt References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> <1410108065-18156-4-git-send-email-sandeen@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1410108065-18156-4-git-send-email-sandeen@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410183927 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Sun, Sep 07, 2014 at 11:41:03AM -0500, Eric Sandeen wrote: > In phase 6's longform_dir2_entry_check, if we never > find a '.' entry we never add a reference to that entry; > if we subsequently rebuild it, '.' gets added, but > no ref to it is ever made. This leads to Phase 7 doing > i.e.: > > Phase 7 - verify and correct link counts... > resetting inode 5184 nlinks from 2 to 1 > > and the next run will do: > > Phase 7 - verify and correct link counts... > resetting inode 5184 nlinks from 1 to 2 > > So if '.' was never found, but the directory got > rebuilt, manually add the ref for it. > > Signed-off-by: Eric Sandeen > --- > repair/phase6.c | 6 ++++++ > 1 files changed, 6 insertions(+), 0 deletions(-) > > diff --git a/repair/phase6.c b/repair/phase6.c > index f13069f..cc36a9c 100644 > --- a/repair/phase6.c > +++ b/repair/phase6.c > @@ -2288,6 +2288,12 @@ out_fix: > if (bplist[i]) > libxfs_putbuf(bplist[i]); > longform_dir2_rebuild(mp, ino, ip, irec, ino_offset, hashtab); > + /* > + * If we didn't find a dot, we never added a ref for it; > + * it's there now after the rebuild, so mark it as reached. > + */ > + if (*need_dot) > + add_inode_ref(irec, ino_offset); So if I follow this correctly, we iterate through the dir, add each name to the hashtable and handle the inode reference count in the first longform_dir2_entry_check() loop. If something is wrong, we call longform_dir2_rebuild() to rebuild the dir from the hashtable of names/inodes. We may or may not have added a reference for dot at that point, and need_dot is set appropriately. This seems Ok, but where is the dot entry actually added? Hmm, I see that we handle dot in the longform_dir2_rebuild() loop by just skipping over it... Brian > *num_illegal = 0; > *need_dot = 0; > } else { > -- > 1.7.1 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From sandeen@sandeen.net Mon Sep 8 08:49:51 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id CAB9F7F4E for ; Mon, 8 Sep 2014 08:49:51 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id A8B708F8035 for ; Mon, 8 Sep 2014 06:49:51 -0700 (PDT) X-ASG-Debug-ID: 1410184190-04cb6c54ff85bb30001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id d0LwgDLSbsY0jGOC for ; Mon, 08 Sep 2014 06:49:50 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 02A3263D71ED; Mon, 8 Sep 2014 08:49:50 -0500 (CDT) Message-ID: <540DB3FE.6010309@sandeen.net> Date: Mon, 08 Sep 2014 08:49:50 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Dave Chinner , Eric Sandeen CC: xfs-oss Subject: Re: [PATCH] xfs: don't ASSERT on corrupt ftype References: <540D011B.2000807@redhat.com> <20140908130507.GN30012@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs: don't ASSERT on corrupt ftype In-Reply-To: <20140908130507.GN30012@dastard> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410184190 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9282 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/8/14 8:05 AM, Dave Chinner wrote: > On Sun, Sep 07, 2014 at 08:06:35PM -0500, Eric Sandeen wrote: >> xfs_dir3_data_get_ftype() and xfs_dir2_sf_check() get >> the file type off disk, but ASSERT if it's invalid: >> >> ASSERT(type < XFS_DIR3_FT_MAX); >> >> This might be cut & paste from the "put" functions, >> which should be checking that they've not been passed >> bad values, but we shouldn't ASSERT on bad values >> read from disk. > > No, they weren't cut-n-paste from the put functions. They were > actually designed for a metadata block where bad values would not be > written to disk, and corrupted disk blocks would be detected by CRC > validation failures. So on debug kernels it's quite appropriate to > assert fail on a "should never, ever happen" condition. hohum, ok. > Then the v4 ftype feature bit was rammed in but none of the code got > changed to reflect that the values in the ftype fields are not CRC > protected on v4 filesystems.... > >> diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c >> index 5079e05..ea89250 100644 >> --- a/fs/xfs/libxfs/xfs_dir2_sf.c >> +++ b/fs/xfs/libxfs/xfs_dir2_sf.c >> @@ -635,7 +635,6 @@ xfs_dir2_sf_check( >> offset = >> xfs_dir2_sf_get_offset(sfep) + >> dp->d_ops->data_entsize(sfep->namelen); >> - ASSERT(dp->d_ops->sf_get_ftype(sfep) < XFS_DIR3_FT_MAX); >> } >> ASSERT(i8count == sfp->i8count); >> ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size); > > That's a debug only function validating that the shortform directory > is internally consistent. And as the comment says: > > /* > * Check consistency of shortform directory, assert if bad. > */ > > So that assert should remain because it's checking the in-memory > state immediately before, during and after modifications are made to > the directory, not when it has just been read of disk.... > > Cheers, > > Dave. > From sandeen@sandeen.net Mon Sep 8 09:02:31 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 02AA57F4E for ; Mon, 8 Sep 2014 09:02:31 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id E51068F8035 for ; Mon, 8 Sep 2014 07:02:27 -0700 (PDT) X-ASG-Debug-ID: 1410184946-04cbb05485ae7840001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id OamULleMqSepizuJ for ; Mon, 08 Sep 2014 07:02:26 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 5231063D71ED; Mon, 8 Sep 2014 09:02:26 -0500 (CDT) Message-ID: <540DB6F3.7090407@sandeen.net> Date: Mon, 08 Sep 2014 09:02:27 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Dave Chinner , Eric Sandeen CC: xfs-oss Subject: Re: [PATCH] xfs: don't ASSERT on corrupt ftype References: <540D011B.2000807@redhat.com> <20140908130507.GN30012@dastard> <540DB3FE.6010309@sandeen.net> X-ASG-Orig-Subj: Re: [PATCH] xfs: don't ASSERT on corrupt ftype In-Reply-To: <540DB3FE.6010309@sandeen.net> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410184946 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9282 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/8/14 8:49 AM, Eric Sandeen wrote: > On 9/8/14 8:05 AM, Dave Chinner wrote: >> On Sun, Sep 07, 2014 at 08:06:35PM -0500, Eric Sandeen wrote: >>> xfs_dir3_data_get_ftype() and xfs_dir2_sf_check() get >>> the file type off disk, but ASSERT if it's invalid: >>> >>> ASSERT(type < XFS_DIR3_FT_MAX); >>> >>> This might be cut & paste from the "put" functions, >>> which should be checking that they've not been passed >>> bad values, but we shouldn't ASSERT on bad values >>> read from disk. >> >> No, they weren't cut-n-paste from the put functions. They were >> actually designed for a metadata block where bad values would not be >> written to disk, and corrupted disk blocks would be detected by CRC >> validation failures. So on debug kernels it's quite appropriate to >> assert fail on a "should never, ever happen" condition. > > hohum, ok. So then presumably the reason there is no ASSERT in xfs_dir3_sfe_get_ftype (vs in xfs_dir3_data_get_ftype) is also purely intentional and part of the design, but I'm unable to divine that logic... can you help me out? I guess the only way forward is to create a 3rd set of ops, and have one for dir2, one for dir2-with-ftype, and one for dir3? Because in the op, there's no way to discern between the latter 2, and know if we're previously CRC-protected or not... -Eric From bfoster@redhat.com Mon Sep 8 09:25:33 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 133937F4E for ; Mon, 8 Sep 2014 09:25:33 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id F2C0C8F8035 for ; Mon, 8 Sep 2014 07:25:32 -0700 (PDT) X-ASG-Debug-ID: 1410186331-04cb6c54fd85db80001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id J0WEb8BHzTYUq6wN (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 08 Sep 2014 07:25:32 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s88EPVJd029818 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Mon, 8 Sep 2014 10:25:31 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s88EPUuD001886; Mon, 8 Sep 2014 10:25:30 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id C27B91256F8; Mon, 8 Sep 2014 10:25:29 -0400 (EDT) Date: Mon, 8 Sep 2014 10:25:29 -0400 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 3/5] xfs_repair: fix dir refcount when '.' missing and dir is rebuilt Message-ID: <20140908142529.GD52419@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 3/5] xfs_repair: fix dir refcount when '.' missing and dir is rebuilt References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> <1410108065-18156-4-git-send-email-sandeen@redhat.com> <20140908134524.GC52419@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140908134524.GC52419@bfoster.bfoster> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410186331 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Sep 08, 2014 at 09:45:25AM -0400, Brian Foster wrote: > On Sun, Sep 07, 2014 at 11:41:03AM -0500, Eric Sandeen wrote: > > In phase 6's longform_dir2_entry_check, if we never > > find a '.' entry we never add a reference to that entry; > > if we subsequently rebuild it, '.' gets added, but > > no ref to it is ever made. This leads to Phase 7 doing > > i.e.: > > > > Phase 7 - verify and correct link counts... > > resetting inode 5184 nlinks from 2 to 1 > > > > and the next run will do: > > > > Phase 7 - verify and correct link counts... > > resetting inode 5184 nlinks from 1 to 2 > > > > So if '.' was never found, but the directory got > > rebuilt, manually add the ref for it. > > > > Signed-off-by: Eric Sandeen > > --- > > repair/phase6.c | 6 ++++++ > > 1 files changed, 6 insertions(+), 0 deletions(-) > > > > diff --git a/repair/phase6.c b/repair/phase6.c > > index f13069f..cc36a9c 100644 > > --- a/repair/phase6.c > > +++ b/repair/phase6.c > > @@ -2288,6 +2288,12 @@ out_fix: > > if (bplist[i]) > > libxfs_putbuf(bplist[i]); > > longform_dir2_rebuild(mp, ino, ip, irec, ino_offset, hashtab); > > + /* > > + * If we didn't find a dot, we never added a ref for it; > > + * it's there now after the rebuild, so mark it as reached. > > + */ > > + if (*need_dot) > > + add_inode_ref(irec, ino_offset); > > So if I follow this correctly, we iterate through the dir, add each name > to the hashtable and handle the inode reference count in the first > longform_dir2_entry_check() loop. If something is wrong, we call > longform_dir2_rebuild() to rebuild the dir from the hashtable of > names/inodes. We may or may not have added a reference for dot at that > point, and need_dot is set appropriately. > > This seems Ok, but where is the dot entry actually added? Hmm, I see > that we handle dot in the longform_dir2_rebuild() loop by just skipping > over it... > It looks like this happens in process_dir_inode() after this whole check/rebuild sequence, directory format permitting. There's also an add_inode_ref() there. Perhaps the bug here is that we clear need_dot when we shouldn't..? Brian > Brian > > > > *num_illegal = 0; > > *need_dot = 0; > > } else { > > -- > > 1.7.1 > > > > _______________________________________________ > > xfs mailing list > > xfs@oss.sgi.com > > http://oss.sgi.com/mailman/listinfo/xfs > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From sandeen@sandeen.net Mon Sep 8 09:33:56 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 032B77F4E for ; Mon, 8 Sep 2014 09:33:56 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id D5AD88F8033 for ; Mon, 8 Sep 2014 07:33:55 -0700 (PDT) X-ASG-Debug-ID: 1410186834-04cb6c54fd85e170001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id A4RTVlCvzHSq4RiL for ; Mon, 08 Sep 2014 07:33:54 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 5C84163D71ED; Mon, 8 Sep 2014 09:33:54 -0500 (CDT) Message-ID: <540DBE53.7040600@sandeen.net> Date: Mon, 08 Sep 2014 09:33:55 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Brian Foster , Eric Sandeen CC: xfs@oss.sgi.com Subject: Re: [PATCH 3/5] xfs_repair: fix dir refcount when '.' missing and dir is rebuilt References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> <1410108065-18156-4-git-send-email-sandeen@redhat.com> <20140908134524.GC52419@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 3/5] xfs_repair: fix dir refcount when '.' missing and dir is rebuilt In-Reply-To: <20140908134524.GC52419@bfoster.bfoster> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410186834 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9283 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/8/14 8:45 AM, Brian Foster wrote: > On Sun, Sep 07, 2014 at 11:41:03AM -0500, Eric Sandeen wrote: >> In phase 6's longform_dir2_entry_check, if we never >> find a '.' entry we never add a reference to that entry; >> if we subsequently rebuild it, '.' gets added, but >> no ref to it is ever made. This leads to Phase 7 doing >> i.e.: >> >> Phase 7 - verify and correct link counts... >> resetting inode 5184 nlinks from 2 to 1 >> >> and the next run will do: >> >> Phase 7 - verify and correct link counts... >> resetting inode 5184 nlinks from 1 to 2 >> >> So if '.' was never found, but the directory got >> rebuilt, manually add the ref for it. >> >> Signed-off-by: Eric Sandeen >> --- >> repair/phase6.c | 6 ++++++ >> 1 files changed, 6 insertions(+), 0 deletions(-) >> >> diff --git a/repair/phase6.c b/repair/phase6.c >> index f13069f..cc36a9c 100644 >> --- a/repair/phase6.c >> +++ b/repair/phase6.c >> @@ -2288,6 +2288,12 @@ out_fix: >> if (bplist[i]) >> libxfs_putbuf(bplist[i]); >> longform_dir2_rebuild(mp, ino, ip, irec, ino_offset, hashtab); >> + /* >> + * If we didn't find a dot, we never added a ref for it; >> + * it's there now after the rebuild, so mark it as reached. >> + */ >> + if (*need_dot) >> + add_inode_ref(irec, ino_offset); > > So if I follow this correctly, we iterate through the dir, add each name > to the hashtable and handle the inode reference count in the first > longform_dir2_entry_check() loop. If something is wrong, we call > longform_dir2_rebuild() to rebuild the dir from the hashtable of > names/inodes. We may or may not have added a reference for dot at that > point, and need_dot is set appropriately. > > This seems Ok, but where is the dot entry actually added? Hmm, I see > that we handle dot in the longform_dir2_rebuild() loop by just skipping > over it... longform_dir2_rebuild calls this before the loop: /* * Initialize a directory with its "." and ".." entries. */ int xfs_dir_init() But it doesn't actually create .; this creates a shortform dir, and shortform dirs have no '.' - I guess the comment could use an update. In the loop we call xfs_dir_createname() for everything in the hash, eventually things don't fit in shortform and we do xfs_dir2_sf_to_block, which creates the dot: /* * Create entry for . */ dep = xfs_dir3_data_dot_entry_p(mp, hdr); dep->inumber = cpu_to_be64(dp->i_ino); dep->namelen = 1; dep->name[0] = '.'; -Eric From sandeen@sandeen.net Mon Sep 8 09:44:11 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 18A697F4E for ; Mon, 8 Sep 2014 09:44:11 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0581C8F8033 for ; Mon, 8 Sep 2014 07:44:10 -0700 (PDT) X-ASG-Debug-ID: 1410187449-04cbb05487ae9b60001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id XHJqPa9EayFaU5y3 for ; Mon, 08 Sep 2014 07:44:09 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 652C963D71ED; Mon, 8 Sep 2014 09:44:09 -0500 (CDT) Message-ID: <540DC0BA.1010802@sandeen.net> Date: Mon, 08 Sep 2014 09:44:10 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Brian Foster , Eric Sandeen CC: xfs@oss.sgi.com Subject: Re: [PATCH 3/5] xfs_repair: fix dir refcount when '.' missing and dir is rebuilt References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> <1410108065-18156-4-git-send-email-sandeen@redhat.com> <20140908134524.GC52419@bfoster.bfoster> <20140908142529.GD52419@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 3/5] xfs_repair: fix dir refcount when '.' missing and dir is rebuilt In-Reply-To: <20140908142529.GD52419@bfoster.bfoster> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410187449 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9283 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/8/14 9:25 AM, Brian Foster wrote: > On Mon, Sep 08, 2014 at 09:45:25AM -0400, Brian Foster wrote: >> On Sun, Sep 07, 2014 at 11:41:03AM -0500, Eric Sandeen wrote: >>> In phase 6's longform_dir2_entry_check, if we never >>> find a '.' entry we never add a reference to that entry; >>> if we subsequently rebuild it, '.' gets added, but >>> no ref to it is ever made. This leads to Phase 7 doing >>> i.e.: >>> >>> Phase 7 - verify and correct link counts... >>> resetting inode 5184 nlinks from 2 to 1 >>> >>> and the next run will do: >>> >>> Phase 7 - verify and correct link counts... >>> resetting inode 5184 nlinks from 1 to 2 >>> >>> So if '.' was never found, but the directory got >>> rebuilt, manually add the ref for it. >>> >>> Signed-off-by: Eric Sandeen >>> --- >>> repair/phase6.c | 6 ++++++ >>> 1 files changed, 6 insertions(+), 0 deletions(-) >>> >>> diff --git a/repair/phase6.c b/repair/phase6.c >>> index f13069f..cc36a9c 100644 >>> --- a/repair/phase6.c >>> +++ b/repair/phase6.c >>> @@ -2288,6 +2288,12 @@ out_fix: >>> if (bplist[i]) >>> libxfs_putbuf(bplist[i]); >>> longform_dir2_rebuild(mp, ino, ip, irec, ino_offset, hashtab); >>> + /* >>> + * If we didn't find a dot, we never added a ref for it; >>> + * it's there now after the rebuild, so mark it as reached. >>> + */ >>> + if (*need_dot) >>> + add_inode_ref(irec, ino_offset); >> >> So if I follow this correctly, we iterate through the dir, add each name >> to the hashtable and handle the inode reference count in the first >> longform_dir2_entry_check() loop. If something is wrong, we call >> longform_dir2_rebuild() to rebuild the dir from the hashtable of >> names/inodes. We may or may not have added a reference for dot at that >> point, and need_dot is set appropriately. >> >> This seems Ok, but where is the dot entry actually added? Hmm, I see >> that we handle dot in the longform_dir2_rebuild() loop by just skipping >> over it... >> > > It looks like this happens in process_dir_inode() after this whole > check/rebuild sequence, directory format permitting. There's also an > add_inode_ref() there. Perhaps the bug here is that we clear need_dot > when we shouldn't..? If we do that, the first run says: bad hash table for directory inode 5184 (no data entry): rebuilding rebuilding directory inode 5184 creating missing "." entry in dir ino 5184 and then the 2nd run says: multiple . entries in directory inode 5184: clearing entry so, no. ;) The issue is that add_inode_ref() is keeping track (in repair) of reached paths to the inode, in counted_nlinks. If we didn't find '.' originally, we didn't add that ref. When we do: longform_dir2_rebuild xfs_dir_init() // creates shortform xfs_dir_createname xfs_dir2_sf_to_block when it's big enough add '.' entry and then we've added the '.' but haven't added the reference repair needs internally. -Eric From stan@hardwarefreak.com Mon Sep 8 10:13:22 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B95A97F4E for ; Mon, 8 Sep 2014 10:13:22 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 55E96AC001 for ; Mon, 8 Sep 2014 08:13:19 -0700 (PDT) X-ASG-Debug-ID: 1410189194-04bdf0109a806ac0001-NocioJ Received: from greer.hardwarefreak.com (mo-65-41-216-221.sta.embarqhsd.net [65.41.216.221]) by cuda.sgi.com with ESMTP id gafaOsOgu5HDzTjH for ; Mon, 08 Sep 2014 08:13:14 -0700 (PDT) X-Barracuda-Envelope-From: stan@hardwarefreak.com X-Barracuda-Apparent-Source-IP: 65.41.216.221 X-Barracuda-User-Whitelist: xfs@oss.sgi.com Received: from [134.64.128.162] (unknown [192.65.45.20]) by greer.hardwarefreak.com (Postfix) with ESMTPA id D18576C0F6; Mon, 8 Sep 2014 10:13:13 -0500 (CDT) Message-ID: <540DC78C.4010607@hardwarefreak.com> Date: Mon, 08 Sep 2014 10:13:16 -0500 From: stan hoeppner User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Icedove/24.7.0 MIME-Version: 1.0 To: Dave Chinner CC: xfs@oss.sgi.com Subject: Re: storage, libaio, or XFS problem? 3.4.26 References: <20140828230817.GU20518@dastard> <2d2ce7bb38c00a7d35f4a324f6a36cbb@localhost> <20140829235538.GF20518@dastard> <20140831235749.GH20518@dastard> <5403E9B9.7040608@hardwarefreak.com> <20140901234529.GI20518@dastard> <5405FB19.2020208@hardwarefreak.com> <20140902221915.GK20518@dastard> <540BEBB7.7020306@hardwarefreak.com> <20140907233910.GA30012@dastard> X-ASG-Orig-Subj: Re: storage, libaio, or XFS problem? 3.4.26 In-Reply-To: <20140907233910.GA30012@dastard> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mo-65-41-216-221.sta.embarqhsd.net[65.41.216.221] X-Barracuda-Start-Time: 1410189194 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On 09/07/2014 06:39 PM, Dave Chinner wrote: > On Sun, Sep 07, 2014 at 12:23:03AM -0500, stan hoeppner wrote: >> I have some more information regarding the AIO issue. I fired up the >> test harness and it ran for 30 hours at 706 MB/s avg write rate, 303 >> MB/s per LUN, nearly flawlessly, less than 0.01% buffer loss, and avg IO >> times were less than 0.5 seconds. Then the app crashed and I found the >> following in dmesg. I had to "hard reset" the box due to the shrapnel. >> There are no IO errors of any kind leading up to the forced shutdown. >> I assume the inode update and streamRT-sa hung task traces are a result >> of the forced shutdown, not a cause of it. In lieu of an xfs_repair >> with a version newer than I'm able to install, any ideas what caused the >> forced shutdown after 30 hours, given there are no errors preceding it? >> >> >> Sep 6 06:33:33 Anguish-ssu-1 kernel: [288087.334863] XFS (dm-5): >> xfs_do_force_shutdown(0x8) called from line 3732 of file >> fs/xfs/xfs_bmap.c. Return address = 0xffffffffa02009a6 >> Sep 6 06:33:42 Anguish-ssu-1 kernel: [288096.220920] XFS (dm-5): failed >> to update timestamps for inode 0x2ffc9caae > > Hi Stan, can you need to turn off line wrapping for stuff you paste > in? It's all but unreadable when it line wraps like this? Sorry. I switched my daily desktop from Windows/Tbird to Wheezy/Icedove and I haven't tweaked it out much yet. I set hard wrap at 72 and that's the problem. I'll set flowed format and see if that helps. > Next, you need to turn /proc/sys/fs/xfs/error_level up to 11 so that > it dumps a stack trace on corruption events. I don't have a (I can't > remember what kernel version you are running) tree in front of me to > convert that line number to something meaningful, so it's not a > great help... error_level is now 11 on both systems and will survive reboots. It's kernel 3.4.26. > Was there anything in the logs before the shutdown? i.e. can you > paste the dmesg output from the start of the test (i.e. the mount of > the fs) to the end? They have this setup in a quasi production/test manner, which is frustrating. The two test rigs PXE/tftp boot and mount rootfs on NFS. Both systems remote log kern.log into to a single file on the boot server, so I grep for hostname. dmesg isn't logged remotely, and is lost after a reboot. So I don't have the mount entries for some reason. It seems kern.log doesn't get populated with all the stuff that goes into dmesg. I'll be sure to grab all of dmesg next time before rebooting. However, I don't recall any errors of any kind prior to the shutdown, which in itself is strange. > As it is, all the traces looke like this: > >> [] schedule+0x64/0x66 >> [] rwsem_down_failed_common+0xdb/0x10d >> [] rwsem_down_write_failed+0x13/0x15 >> [] call_rwsem_down_write_failed+0x13/0x20 >> [] ? down_write+0x25/0x27 >> [] xfs_ilock+0x4f/0xb4 [xfs] >> [] xfs_rw_ilock+0x2c/0x33 [xfs] >> [] ? _raw_spin_unlock_irq+0x27/0x32 >> [] xfs_file_aio_write_checks+0x41/0xfe [xfs] >> [] xfs_file_dio_aio_write+0x103/0x1fc [xfs] >> [] xfs_file_aio_write+0x152/0x1b5 [xfs] >> [] ? xfs_file_buffered_aio_write+0x179/0x179 [xfs] >> [] aio_rw_vect_retry+0x85/0x18a >> [] ? aio_fsync+0x29/0x29 >> [] aio_run_iocb+0x7b/0x149 >> [] io_submit_one+0x199/0x1f3 >> [] do_io_submit+0xfa/0x271 >> [] sys_io_submit+0x10/0x12 >> [] system_call_fastpath+0x16/0x1b > > Which implies that the shutdown didn't unlock the inode correctly. > But without knowing what the call stack at the time of the shutdown > was, I can't really tell... And error_level 11 should give us the call stack, correct? My current run without AIO should be completing in a few hours. I have one more non-AIO run to make after that. Takes about 6 hours after all files are populated. Then I'll start another AIO run and try to get you the info you need. May take 30 hours again, might take less than an hour. It's not consistent. Thanks, Stan From joe.landman@gmail.com Mon Sep 8 13:10:12 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 7DE277F4E for ; Mon, 8 Sep 2014 13:10:12 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1AF59AC00A for ; Mon, 8 Sep 2014 11:10:09 -0700 (PDT) X-ASG-Debug-ID: 1410199807-04bdf010a1813f50001-NocioJ Received: from mail-ig0-f174.google.com (mail-ig0-f174.google.com [209.85.213.174]) by cuda.sgi.com with ESMTP id qHzopjaDQo4FA4RK (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Mon, 08 Sep 2014 11:10:07 -0700 (PDT) X-Barracuda-Envelope-From: joe.landman@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.213.174 X-Barracuda-IPDD: Level1 [gmail.com/209.85.213.174] Received: by mail-ig0-f174.google.com with SMTP id a13so3215331igq.7 for ; Mon, 08 Sep 2014 11:10:07 -0700 (PDT) X-Barracuda-IPDD: Level1 [gmail.com/209.85.213.174] X-Barracuda-IPDD: Level1 [gmail.com/209.85.213.174] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject :content-type:content-transfer-encoding; bh=XWibc9LQJZRp4Hx6TVTHAVd9IUiy91NfxWgbA8XyKNw=; b=VnR8aCq69H4hISSy7AjQJotkG1uiX3IqUcOP1zC4EwGaz3uhGiylIT6rhR7HgR5esb mbhe++sYPUlz7+/o5EHo37lqJVbSXB27h8tSk7zUWGvVZ7gNT5SymZBy1cmAEtVx2Q/N aLTgNztqDp3ZyS9kae9Ntc4wFJsf3zxe1pZmVKDn6ITXuLtF68VKHXRqfbZOvfu40Lqn Axan5CDUdHGMHZcHYTTCskGGaVgA40YgiVQKfSfp3z//riQPyZXzxMymBsQ+ljIChyjY i8Q9h0AKRbkwgSxsFP/kJIjg6Gph9E+TSY8kWa3jLgIfO+Lu55+UvNs6t0Jb04WKvnBF msyQ== X-Received: by 10.42.199.11 with SMTP id eq11mr14539956icb.5.1410199807294; Mon, 08 Sep 2014 11:10:07 -0700 (PDT) Received: from [192.168.1.171] (50-197-102-113-static.hfc.comcastbusiness.net. [50.197.102.113]) by mx.google.com with ESMTPSA id x9sm11608103igl.10.2014.09.08.11.10.06 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 08 Sep 2014 11:10:06 -0700 (PDT) Message-ID: <540DF0FD.205@gmail.com> Date: Mon, 08 Sep 2014 14:10:05 -0400 From: Joe Landman User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.0 MIME-Version: 1.0 To: xfs@oss.sgi.com Subject: converting from external log to internal log ... is this possible? Content-Type: text/plain; charset=utf-8; format=flowed X-ASG-Orig-Subj: converting from external log to internal log ... is this possible? Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail-ig0-f174.google.com[209.85.213.174] X-Barracuda-Start-Time: 1410199807 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9287 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature Figured I'd ask, looked on the FAQ and didn't see anything there relevant to this. There is a hint of this in xfs_growfs, specifically the -i option, though it is noted that "[NOTE: This option is not implemented]". -- Joe Landman From sandeen@sandeen.net Mon Sep 8 13:41:57 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id DC8F97F4E for ; Mon, 8 Sep 2014 13:41:57 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id BCF7A304048 for ; Mon, 8 Sep 2014 11:41:54 -0700 (PDT) X-ASG-Debug-ID: 1410201712-04cb6c54fe86f410001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id fg157WLRfxr8qhM3 for ; Mon, 08 Sep 2014 11:41:52 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 8DF56637142E; Mon, 8 Sep 2014 13:41:51 -0500 (CDT) Message-ID: <540DF86D.8080705@sandeen.net> Date: Mon, 08 Sep 2014 13:41:49 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Joe Landman , xfs@oss.sgi.com Subject: Re: converting from external log to internal log ... is this possible? References: <540DF0FD.205@gmail.com> X-ASG-Orig-Subj: Re: converting from external log to internal log ... is this possible? In-Reply-To: <540DF0FD.205@gmail.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410201712 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9288 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/8/14 1:10 PM, Joe Landman wrote: > Figured I'd ask, looked on the FAQ and didn't see anything there > relevant to this. There is a hint of this in xfs_growfs, > specifically the -i option, though it is noted that "[NOTE: This > option is not implemented]". Yep, it's never been implemented. You could do it manually with some very careful xfs_db surgery, if you had enough contiguous freespace available, but it's not at all supported. Basically, no, you can't do it without getting very far under the hood and directly editing the disk. -Eric From david@fromorbit.com Mon Sep 8 17:01:06 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 477EC7F50 for ; Mon, 8 Sep 2014 17:01:06 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id D8801AC003 for ; Mon, 8 Sep 2014 15:01:02 -0700 (PDT) X-ASG-Debug-ID: 1410213659-04cbb05485b24470001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id lzLYB3cmJWeGZHWN for ; Mon, 08 Sep 2014 15:00:59 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 09 Sep 2014 07:30:39 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XR6zE-0002dE-RD; Tue, 09 Sep 2014 08:00:36 +1000 Date: Tue, 9 Sep 2014 08:00:36 +1000 From: Dave Chinner To: Eric Sandeen Cc: Eric Sandeen , xfs-oss Subject: Re: [PATCH] xfs: don't ASSERT on corrupt ftype Message-ID: <20140908220036.GO30012@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs: don't ASSERT on corrupt ftype References: <540D011B.2000807@redhat.com> <20140908130507.GN30012@dastard> <540DB3FE.6010309@sandeen.net> <540DB6F3.7090407@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540DB6F3.7090407@sandeen.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410213659 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9292 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Sep 08, 2014 at 09:02:27AM -0500, Eric Sandeen wrote: > On 9/8/14 8:49 AM, Eric Sandeen wrote: > >On 9/8/14 8:05 AM, Dave Chinner wrote: > >>On Sun, Sep 07, 2014 at 08:06:35PM -0500, Eric Sandeen wrote: > >>>xfs_dir3_data_get_ftype() and xfs_dir2_sf_check() get > >>>the file type off disk, but ASSERT if it's invalid: > >>> > >>> ASSERT(type < XFS_DIR3_FT_MAX); > >>> > >>>This might be cut & paste from the "put" functions, > >>>which should be checking that they've not been passed > >>>bad values, but we shouldn't ASSERT on bad values > >>>read from disk. > >> > >>No, they weren't cut-n-paste from the put functions. They were > >>actually designed for a metadata block where bad values would not be > >>written to disk, and corrupted disk blocks would be detected by CRC > >>validation failures. So on debug kernels it's quite appropriate to > >>assert fail on a "should never, ever happen" condition. > > > >hohum, ok. > > So then presumably the reason there is no ASSERT in xfs_dir3_sfe_get_ftype > (vs in xfs_dir3_data_get_ftype) is also purely intentional and > part of the design, but I'm unable to divine that logic... can you > help me out? Because that ASSERT check was put in xfs_dir2_sf_check(). Yeah, I know, not consistent, but the shortform code is quite different to the block/leaf/node code.... > I guess the only way forward is to create a 3rd set of ops, and have > one for dir2, one for dir2-with-ftype, and one for dir3? Because > in the op, there's no way to discern between the latter 2, and > know if we're previously CRC-protected or not... No, just kill the asset in xfs_dir3_data_get_ftype(). Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Sep 8 17:07:46 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 42F507F52 for ; Mon, 8 Sep 2014 17:07:46 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id D4E35AC001 for ; Mon, 8 Sep 2014 15:07:45 -0700 (PDT) X-ASG-Debug-ID: 1410214059-04bdf010a182c690001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id NGZC0cxpgMMkTiWQ for ; Mon, 08 Sep 2014 15:07:40 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgY6AJwnDlR5LKYhPGdsb2JhbABZgw2BKoIshQepMAEBAQEBAQaab4VpAQMBAQGBGBcFAQEBATg3hAQBBTocIxAIAxgJJQ8FJQMHGhOIQb1NARcYhWSJUQeETAWccZkgKy+CTwEBAQ Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 09 Sep 2014 07:37:39 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XR762-0002e6-Rv; Tue, 09 Sep 2014 08:07:38 +1000 Date: Tue, 9 Sep 2014 08:07:38 +1000 From: Dave Chinner To: Eric Sandeen Cc: Joe Landman , xfs@oss.sgi.com Subject: Re: converting from external log to internal log ... is this possible? Message-ID: <20140908220738.GP30012@dastard> X-ASG-Orig-Subj: Re: converting from external log to internal log ... is this possible? References: <540DF0FD.205@gmail.com> <540DF86D.8080705@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540DF86D.8080705@sandeen.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410214059 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9292 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Sep 08, 2014 at 01:41:49PM -0500, Eric Sandeen wrote: > On 9/8/14 1:10 PM, Joe Landman wrote: > >Figured I'd ask, looked on the FAQ and didn't see anything there > >relevant to this. There is a hint of this in xfs_growfs, > >specifically the -i option, though it is noted that "[NOTE: This > >option is not implemented]". > > Yep, it's never been implemented. You could do it manually with > some very careful xfs_db surgery, if you had enough contiguous > freespace available, but it's not at all supported. > > Basically, no, you can't do it without getting very far under > the hood and directly editing the disk. There's nothing amazingly difficult about implementing external-to-internal journal. First allocate the contiguous extent for the new log, then zero it, then freeze the filesystem to bring the external log down to a clean state, atomically modify the superblock on disk to point at the new log, then re-initialise all the log state to point at the new log, update the head and tail to new cycles at the start of the new log, and unfreeze.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From sandeen@sandeen.net Mon Sep 8 17:18:11 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E259E7F54 for ; Mon, 8 Sep 2014 17:18:11 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id CF8C58F8040 for ; Mon, 8 Sep 2014 15:18:08 -0700 (PDT) X-ASG-Debug-ID: 1410214686-04cbb05486b26b30001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id 5xFxKOpzoEqd4WNR for ; Mon, 08 Sep 2014 15:18:06 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 6EFF4637142E; Mon, 8 Sep 2014 17:18:06 -0500 (CDT) Message-ID: <540E2B1F.9070009@sandeen.net> Date: Mon, 08 Sep 2014 17:18:07 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Eric Sandeen , xfs-oss Subject: [PATCH V2] xfs: don't ASSERT on corrupt ftype References: <540D011B.2000807@redhat.com> X-ASG-Orig-Subj: [PATCH V2] xfs: don't ASSERT on corrupt ftype In-Reply-To: <540D011B.2000807@redhat.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410214686 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9292 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- xfs_dir3_data_get_ftype() gets the file type off disk, but ASSERTs if it's invalid: ASSERT(type < XFS_DIR3_FT_MAX); We shouldn't ASSERT on bad values read from disk. V3 dirs are CRC-protected, but V2 dirs + ftype are not. Signed-off-by: Eric Sandeen --- diff --git a/fs/xfs/libxfs/xfs_da_format.c b/fs/xfs/libxfs/xfs_da_format.c index c9aee52..7e42fdf 100644 --- a/fs/xfs/libxfs/xfs_da_format.c +++ b/fs/xfs/libxfs/xfs_da_format.c @@ -270,7 +270,6 @@ xfs_dir3_data_get_ftype( { __uint8_t ftype = dep->name[dep->namelen]; - ASSERT(ftype < XFS_DIR3_FT_MAX); if (ftype >= XFS_DIR3_FT_MAX) return XFS_DIR3_FT_UNKNOWN; return ftype; From dave@fromorbit.com Mon Sep 8 20:43:27 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id AC63F7F4E for ; Mon, 8 Sep 2014 20:43:27 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2CCF3AC001 for ; Mon, 8 Sep 2014 18:43:23 -0700 (PDT) X-ASG-Debug-ID: 1410226997-04cb6c54fe88f410001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id V61rOizSW5KIJVkj for ; Mon, 08 Sep 2014 18:43:18 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AlcXAD9aDlR5LKYhPGdsb2JhbABZgw2BKoczqTYBAQEBAQEGoXIXBQEBAQE4N4QxLzsYagMHLYhBlzmlOoV8jiQFqRmMeCsvgk8BAQE Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 09 Sep 2014 11:13:16 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XRASh-0003E4-21 for xfs@oss.sgi.com; Tue, 09 Sep 2014 11:43:15 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XRASh-000464-0g for xfs@oss.sgi.com; Tue, 09 Sep 2014 11:43:15 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH] xfs: xlog_cil_force_lsn doesn't always wait correctly Date: Tue, 9 Sep 2014 11:43:15 +1000 X-ASG-Orig-Subj: [PATCH] xfs: xlog_cil_force_lsn doesn't always wait correctly Message-Id: <1410226995-15714-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410226997 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9297 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner When running a tight mount/unmount loop on an older kernel, RedHat QE found that unmount would occasionally hang in xfs_buf_unpin_wait() on the superblock buffer. Tracing and other debug work by Eric Sandeen indicated that it was hanging on the writing of the superblock during unmount immediately after logging the superblock counters in a synchronous transaction. Further debug indicated that the synchronous transaction was not waiting for completion correctly, and we narrowed it down to xlog_cil_force_lsn() returning NULLCOMMITLSN and hence not pushing the transaction in the iclog buffer to disk correctly. While this unmount superblock write code is now very different in mainline kernels, the xlog_cil_force_lsn() code is identical, and it was bisected to the backport of commit f876e44 ("xfs: always do log forces via the workqueue"). This commit made the CIL push asynchronous for log forces and hence exposed a race condition that couldn't occur on a synchronous push. Essentially, the xlog_cil_force_lsn() relied implicitly on the fact that the sequence push would be complete by the time xlog_cil_push_now() returned, resulting in the context being pushed being in the committing list. When it was made asynchronous, it was recognised that there was a race condition in detecting whether an asynchronous push has started or not and code was added to handle it. Unfortunately, the fix was not quite right and left a race condition where it it would detect an empty CIL while a push was in progress before the context had been added to the committing list. This was incorrectly seen as a "nothing to do" condition and so would tell xfs_log_force_lsn() that there is nothing to wait for, and hence it would push the iclogbufs in memory. The fix is simple, but explaining the logic and the race condition is a lot more complex. The fix is to add the context to the committing list before we start emptying the CIL. This allows us to detect the difference between an empty "do nothing" push and a push that has not started by adding a discrete "emptying the CIL" state to avoid the transient, incorrect "empty" condition that the (unchanged) waiting code was seeing. Signed-off-by: Dave Chinner Tested-by: Eric Sandeen --- fs/xfs/xfs_log_cil.c | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index f6b79e5..f506c45 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c @@ -463,12 +463,40 @@ xlog_cil_push( spin_unlock(&cil->xc_push_lock); goto out_skip; } - spin_unlock(&cil->xc_push_lock); /* check for a previously pushed seqeunce */ - if (push_seq < cil->xc_ctx->sequence) + if (push_seq < cil->xc_ctx->sequence) { + spin_unlock(&cil->xc_push_lock); goto out_skip; + } + + /* + * We are now going to push this context, so add it to the committing + * list before we do anything else. This ensures that anyone waiting on + * this push can easily detect the difference between a "push in + * progress" and "CIL is empty, nothing to do". + * + * IOWs, a wait loop can now check for: + * the current sequence not being found on the committing list; + * an empty CIL; and + * an unchanged sequence number + * to detect a push that had nothing to do and therefore does not need + * waiting on. If the CIL is not empty, we get put on the committing + * list before emptying the CIL and bumping the sequence number. Hence + * an empty CIL and an unchanged sequence number means we jumped out + * above after doing nothing. + * + * Hence the waiter will either find the commit sequence on the + * committing list or the sequence number will be unchanged and the CIL + * still dirty. In that latter case, the push has not yet started, and + * so the waiter will have to continue trying to check the CIL + * committing list until it is found. In extreme cases of delay, the + * sequence may fully commit between the attempts the wait makes to wait + * on the commit sequence. + */ + list_add(&ctx->committing, &cil->xc_committing); + spin_unlock(&cil->xc_push_lock); /* * pull all the log vectors off the items in the CIL, and @@ -532,7 +560,6 @@ xlog_cil_push( */ spin_lock(&cil->xc_push_lock); cil->xc_current_sequence = new_ctx->sequence; - list_add(&ctx->committing, &cil->xc_committing); spin_unlock(&cil->xc_push_lock); up_write(&cil->xc_ctx_lock); @@ -855,13 +882,15 @@ restart: * Hence by the time we have got here it our sequence may not have been * pushed yet. This is true if the current sequence still matches the * push sequence after the above wait loop and the CIL still contains - * dirty objects. + * dirty objects. This is guaranteed by the push code first adding the + * context to the committing list before emptying the CIL. * - * When the push occurs, it will empty the CIL and atomically increment - * the currect sequence past the push sequence and move it into the - * committing list. Of course, if the CIL is clean at the time of the - * push, it won't have pushed the CIL at all, so in that case we should - * try the push for this sequence again from the start just in case. + * Hence if we don't find the context in the committing list and the + * current sequence number is unchanged then the CIL contents are + * significant. If the CIL is empty, if means there was nothing to push + * and that means there is nothing to wait for. If the CIL is not empty, + * it means we haven't yet started the push, because if it had started + * we would have found the context on the committing list. */ if (sequence == cil->xc_current_sequence && !list_empty(&cil->xc_cil)) { -- 2.0.0 From david@fromorbit.com Mon Sep 8 20:46:21 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 979E57F4E for ; Mon, 8 Sep 2014 20:46:21 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 82FD48F8040 for ; Mon, 8 Sep 2014 18:46:21 -0700 (PDT) X-ASG-Debug-ID: 1410227179-04cb6c54ff88f590001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id 7R1zCsNFeubEoMeN for ; Mon, 08 Sep 2014 18:46:19 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Agg6AG9bDlR5LKYhPGdsb2JhbABZgw2BKoIshQepNgEBAQEBAQaab4VpAQMBAQGBExcFAQEBATg3hAQBBTocIxAIAw4KCSUPBSUDBxoTiEG8VAEXGIVkiVEHhEwFjyuNRpkgKy8BgQUjgSYBAQE Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 09 Sep 2014 11:16:18 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XRAVd-0003Ex-Nx; Tue, 09 Sep 2014 11:46:17 +1000 Date: Tue, 9 Sep 2014 11:46:17 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: mark all internal workqueues as freezable Message-ID: <20140909014617.GT30012@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs: mark all internal workqueues as freezable References: <1408388523-3684-1-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1408388523-3684-1-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410227179 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9297 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Aug 18, 2014 at 03:02:03PM -0400, Brian Foster wrote: > Workqueues must be explicitly set as freezable to ensure they are frozen > in the assocated part of the hibernation/suspend sequence. Freezing of > workqueues and kernel threads is important to ensure that modifications > are not made on-disk after the hibernation image has been created. > Otherwise, the in-memory state can become inconsistent with what is on > disk and eventually lead to filesystem corruption. We have reports of > free space btree corruptions that occur immediately after restore from > hibernate that suggest the xfs-eofblocks workqueue could be causing > such problems if it races with hibernation. > > Mark all of the internal XFS workqueues as freezable to ensure nothing > changes on-disk once the freezer infrastructure freezes kernel threads > and creates the hibernation image. > > Signed-off-by: Brian Foster > Reported-by: Carlos E. R. Looks good. Reviewed-by: Dave Chinner -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Sep 8 20:47:24 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 552E17F4E for ; Mon, 8 Sep 2014 20:47:24 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 255428F8040 for ; Mon, 8 Sep 2014 18:47:24 -0700 (PDT) X-ASG-Debug-ID: 1410227241-04bdf0109a838010001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id NUlgtBhOQi1QJLqW for ; Mon, 08 Sep 2014 18:47:22 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Agg6AG9bDlR5LKYhPGdsb2JhbABZgw2BKoIshQepNgEBAQEBAQaab4VpAQMBAQGBExcFAQEBATg3hAQBBScTHCMQCAMYCSUPBSUDBxoTiEG8VAEXGIVkiHlYB4RMBY8rjUaZICsvgQaBSQEBAQ Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 09 Sep 2014 11:17:21 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XRAWe-0003F8-ED; Tue, 09 Sep 2014 11:47:20 +1000 Date: Tue, 9 Sep 2014 11:47:20 +1000 From: Dave Chinner To: Eric Sandeen Cc: Eric Sandeen , xfs-oss Subject: Re: [PATCH V2] xfs: add a few more verifier tests Message-ID: <20140909014720.GU30012@dastard> X-ASG-Orig-Subj: Re: [PATCH V2] xfs: add a few more verifier tests References: <53F2C103.8030607@redhat.com> <53F3A726.8080305@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <53F3A726.8080305@sandeen.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410227241 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9297 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Aug 19, 2014 at 02:36:06PM -0500, Eric Sandeen wrote: > These were exposed by fsfuzzer runs; without them we fail > in various exciting and sometimes convoluted ways when we > encounter disk corruption. > > Without the MAXLEVELS tests we tend to walk off the end of > an array in a loop like this: > > for (i = 0; i < cur->bc_nlevels; i++) { > if (cur->bc_bufs[i]) > > Without the dirblklog test we try to allocate more memory > than we could possibly hope for and loop forever: > > xfs_dabuf_map() > nfsb = mp->m_dir_geo->fsbcount; > irecs = kmem_zalloc(sizeof(irec) * nfsb, KM_SLEEP... > > As for the logbsize check, that's the convoluted one. > > If logbsize is specified at mount time, it's sanitized > in xfs_parseargs; in particular it makes sure that it's > not > XLOG_MAX_RECORD_BSIZE. > > If not specified at mount time, it comes from the superblock > via sb_logsunit; this is limited to 256k at mkfs time as well; > it's copied into m_logbsize in xfs_finish_flags(). > > However, if for some reason the on-disk value is corrupt and > too large, nothing catches it. It's a circuitous path, but > that size eventually finds its way to places that make the kernel > very unhappy, leading to oopses in xlog_pack_data() because we > use the size as an index into iclog->ic_data, but the array > is not necessarily that big. > > Anyway - bounds checking when we read from disk is a good thing! > > Signed-off-by: Eric Sandeen > -- Looks good. Reviewed-by: Dave Chinner -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Sep 8 20:56:07 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 86A407F4E for ; Mon, 8 Sep 2014 20:56:07 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 21977AC001 for ; Mon, 8 Sep 2014 18:56:06 -0700 (PDT) X-ASG-Debug-ID: 1410227764-04cbb05485b3b0d0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id u5pHYRkbYiKxhl0o for ; Mon, 08 Sep 2014 18:56:04 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtE5AMRdDlR5LKYhPGdsb2JhbABZgw1TV4IsrjIMAQEBAQEBBpkSgV2FaQEDAQEBgRQXBQEBAQE4N4QEAQU6HCMQCAMOCgklDwUlAwcaE4hBDrxFARcYhWSHQYIQB4RMBZVwhwGZICsvAYJOAQEB Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 09 Sep 2014 11:26:03 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XRAf3-0003GX-5m; Tue, 09 Sep 2014 11:56:01 +1000 Date: Tue, 9 Sep 2014 11:56:01 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH v2 0/2] xfs log recovery delay instrumentation Message-ID: <20140909015601.GV30012@dastard> X-ASG-Orig-Subj: Re: [PATCH v2 0/2] xfs log recovery delay instrumentation References: <1409666895-49799-1-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1409666895-49799-1-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410227764 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9297 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 02, 2014 at 10:08:13AM -0400, Brian Foster wrote: > Here's v2 of the log recovery delay instrumentation set. v1 is available > here: > > http://oss.sgi.com/archives/xfs/2014-08/msg00276.html > > After a brief conversation with Dave, we thought it best to tie in this > functionality with DEBUG mode to express/ensure that these attributes > are for debugging/hacking purposes only. Everything else should be > equivalent to v1. > > Brian > > v2: > - Enable /sys/fs/xfs/debug for DEBUG mode kernels only. > v1: http://oss.sgi.com/archives/xfs/2014-08/msg00276.html > > Brian Foster (2): > xfs: add debug sysfs attribute set > xfs: export log_recovery_delay to delay mount time log recovery These look good. I'm sure that as we add more attributes there will be opportunity for factoring/streamlining this code more, but right now I don't think that is necessary. Reviewed-by: Dave Chinner -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Sep 8 23:04:01 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id ABE0D7F4E for ; Mon, 8 Sep 2014 23:04:01 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9967F8F8039 for ; Mon, 8 Sep 2014 21:03:58 -0700 (PDT) X-ASG-Debug-ID: 1410235436-04cb6c5500892dc0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id qyaPEKoaldASaKxf for ; Mon, 08 Sep 2014 21:03:56 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Agg6AEt7DlR5LKYhPGdsb2JhbABZgw2BKoIshQepPQEBAQEBAQaab4VpAQMBAQGBEhcFAQEBATg3hAQBBTocIxAIAw4KCSUPBSUDBxoTiEG8LAEXGIVkiVEHgy+BHQWccZkgKy+CTwEBAQ Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 09 Sep 2014 13:33:55 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XRCem-0003ZH-RO; Tue, 09 Sep 2014 14:03:52 +1000 Date: Tue, 9 Sep 2014 14:03:52 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/4] xfs: track collapse via file offset rather than extent index Message-ID: <20140909040352.GC20518@dastard> X-ASG-Orig-Subj: Re: [PATCH 1/4] xfs: track collapse via file offset rather than extent index References: <1410092760-3451-1-git-send-email-bfoster@redhat.com> <1410092760-3451-2-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1410092760-3451-2-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410235436 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9299 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sun, Sep 07, 2014 at 08:25:57AM -0400, Brian Foster wrote: > The collapse range implementation uses a transaction per extent shift. > The progress of the overall operation is tracked via the current extent > index of the in-core extent list. This is racy because the ilock must be > dropped and reacquired for each transaction according to locking and log > reservation rules. Therefore, writeback to prior regions of the file is > possible and can change the extent count. This changes the extent to > which the current index refers and causes the collapse to fail mid > operation. To avoid this problem, the entire file is currently written > back before the collapse operation starts. > > To eliminate the need to flush the entire file, use the file offset > (fsb) to track the progress of the overall extent shift operation rather > than the extent index. Modify xfs_bmap_shift_extents() to > unconditionally convert the start_fsb parameter to an extent index and > return the file offset of the extent where the shift left off, if > further extents exist. The bulk of ths function can remain based on > extent index as ilock is held by the caller. xfs_collapse_file_space() > now uses the fsb output as the starting point for the subsequent shift. > > Signed-off-by: Brian Foster Looks good. There's a couple of small things I noticed, but they aren't worth redoing the patches again to fix. Reviewed-by: Dave Chinner -- Dave Chinner david@fromorbit.com From david@fromorbit.com Tue Sep 9 00:08:13 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id AA9687F4E for ; Tue, 9 Sep 2014 00:08:13 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6CB5B8F8033 for ; Mon, 8 Sep 2014 22:08:10 -0700 (PDT) X-ASG-Debug-ID: 1410239287-04bdf01097841b10001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id v7LcmAOZqxlutVJU for ; Mon, 08 Sep 2014 22:08:07 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Al0/AIaKDlR5LKYhPGdsb2JhbABZgw2BKoIsrkoGmm+FaQICAQEBgRAXBQEBAQE4N4QEAQUnExwjEAgDDgoJJQ8FJQMHGhOIQbweARcYhWSJUQeDL4EdBYYaiRKNRowojHorL4JPAQEB Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 09 Sep 2014 14:38:01 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XRDeq-0003hF-3a; Tue, 09 Sep 2014 15:08:00 +1000 Date: Tue, 9 Sep 2014 15:08:00 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/4] xfs: refactor xfs_bmap_shift_extents() into multiple functions Message-ID: <20140909050800.GD20518@dastard> X-ASG-Orig-Subj: Re: [PATCH 2/4] xfs: refactor xfs_bmap_shift_extents() into multiple functions References: <1410092760-3451-1-git-send-email-bfoster@redhat.com> <1410092760-3451-3-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1410092760-3451-3-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410239287 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9300 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sun, Sep 07, 2014 at 08:25:58AM -0400, Brian Foster wrote: > The extent shift mechanism in xfs_bmap_shift_extents() is complicated > and handles several different, non-deterministic scenarios. These > include extent shifts, extent merges and potential btree updates in > either of the former scenarios. > > Refactor the code to be more linear and readable. The loop logic in > xfs_bmap_shift_extents() and some initial error checking is adjusted > slightly. The associated btree lookup and update/delete operations are > condensed into single blocks of code. This reduces the number of > btree-specific blocks and facilitates the separation of the merge > operation into a new xfs_bmap_shift_extents_merge() helper. The merge > check is also separated into an inline. > > This is a code refactor only. The behavior of extent shift and collapse > range is not modified. > > Signed-off-by: Brian Foster > --- > fs/xfs/libxfs/xfs_bmap.c | 243 ++++++++++++++++++++++++++++++++--------------- > 1 file changed, 168 insertions(+), 75 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > index 4b3f1b9..449a016 100644 > --- a/fs/xfs/libxfs/xfs_bmap.c > +++ b/fs/xfs/libxfs/xfs_bmap.c > @@ -5404,6 +5404,120 @@ error0: > } > > /* > + * Determine whether an extent shift can be accomplished by a merge with the > + * extent that precedes the target hole of the shift. > + */ > +static inline bool > +xfs_bmap_shift_extents_can_merge( No need for "inline" for static functions. The compiler will do that as an optimisation if appropriate. > + struct xfs_bmbt_irec *left, /* preceding extent */ > + struct xfs_bmbt_irec *got, /* current extent to shift */ > + xfs_fileoff_t shift) /* shift fsb */ > +{ > + xfs_fileoff_t startoff; > + > + startoff = got->br_startoff - shift; > + > + /* > + * The extent, once shifted, must be adjacent in-file and on-disk with > + * the preceding extent. > + */ > + if ((left->br_startoff + left->br_blockcount != startoff) || > + (left->br_startblock + left->br_blockcount != got->br_startblock) || > + (left->br_state != got->br_state) || > + (left->br_blockcount + got->br_blockcount > MAXEXTLEN)) > + return false; > + > + return true; > +} > + > +/* > + * An extent shift adjusts the file offset of an extent to fill a preceding hole > + * in the file. If an extent shift would result in the extent being fully > + * adjacent to the extent that currently precedes the hole, we can merge with > + * the preceding extent rather than do the shift. > + * > + * This function assumes the caller has verified a shift-by-merge is possible > + * with the provided extents via xfs_bmap_shift_extents_can_merge(). > + */ > +static int > +xfs_bmap_shift_extents_merge( > + struct xfs_inode *ip, > + int whichfork, > + xfs_fileoff_t shift, /* shift fsb */ > + int current_ext, /* idx of gotp */ > + struct xfs_bmbt_rec_host *gotp, /* extent to shift */ > + struct xfs_bmbt_rec_host *leftp, /* preceding extent */ > + struct xfs_btree_cur *cur, > + int *logflags) /* output */ > +{ > + struct xfs_ifork *ifp; > + struct xfs_bmbt_irec got; > + struct xfs_bmbt_irec left; > + xfs_filblks_t blockcount; > + int error, i; > + > + ifp = XFS_IFORK_PTR(ip, whichfork); > + xfs_bmbt_get_all(gotp, &got); > + xfs_bmbt_get_all(leftp, &left); > + blockcount = left.br_blockcount + got.br_blockcount; > + > + ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); > + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); > + ASSERT(xfs_bmap_shift_extents_can_merge(&left, &got, shift)); > + > + /* > + * Merge the in-core extents. Note that the host record pointers and > + * current_ext index are invalid once the extent has been removed via > + * xfs_iext_remove(). > + */ > + xfs_bmbt_set_blockcount(leftp, blockcount); > + xfs_iext_remove(ip, current_ext, 1, 0); > + > + /* > + * Update the on-disk extent count, the btree if necessary and log the > + * inode. > + */ > + XFS_IFORK_NEXT_SET(ip, whichfork, > + XFS_IFORK_NEXTENTS(ip, whichfork) - 1); > + *logflags |= XFS_ILOG_CORE; > + if (cur) { > + /* lookup and remove the extent to merge */ > + error = xfs_bmbt_lookup_eq(cur, got.br_startoff, > + got.br_startblock, got.br_blockcount, &i); > + if (error) > + goto error; Probably shouldn't give the jump label the same name as a variable in the function. "out_error" is commonly used here. > + XFS_WANT_CORRUPTED_GOTO(i == 1, error); > + > + error = xfs_btree_delete(cur, &i); > + if (error) > + goto error; > + XFS_WANT_CORRUPTED_GOTO(i == 1, error); > + > + /* lookup and update size of the previous extent */ > + error = xfs_bmbt_lookup_eq(cur, left.br_startoff, > + left.br_startblock, left.br_blockcount, &i); > + if (error) > + goto error; > + XFS_WANT_CORRUPTED_GOTO(i == 1, error); > + > + left.br_blockcount = blockcount; > + > + error = xfs_bmbt_update(cur, left.br_startoff, > + left.br_startblock, left.br_blockcount, > + left.br_state); > + if (error) > + goto error; > + } else { > + *logflags |= XFS_ILOG_DEXT; > + } > + > + return 0; > + > +error: > + return error; This code is much clearer, though I'd get rid of further indents by changing the logic around like so: .... *logflags |= XFS_ILOG_CORE; if (!cur) { *logflags |= XFS_ILOG_DEXT; return 0; } /* lookup and remove the extent to merge */ error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock, got.br_blockcount, &i); if (error) goto out_error; ..... error = xfs_bmbt_update(cur, left.br_startoff, left.br_startblock, left.br_blockcount, left.br_state); out_error: return error; } > @@ -5493,30 +5617,42 @@ xfs_bmap_shift_extents( > */ > total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); > while (nexts++ < num_exts && current_ext < total_extents) { > - > - gotp = xfs_iext_get_ext(ifp, current_ext); > - xfs_bmbt_get_all(gotp, &got); > startoff = got.br_startoff - offset_shift_fsb; > > - /* > - * Before shifting extent into hole, make sure that the hole is > - * large enough to accommodate the shift. > - */ > + /* grab the left extent and check for a potential merge */ > if (current_ext > 0) { > - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, current_ext - 1), > - &left); > - if (startoff < left.br_startoff + left.br_blockcount) > + leftp = xfs_iext_get_ext(ifp, current_ext - 1); > + xfs_bmbt_get_all(leftp, &left); > + > + /* make sure hole is large enough for shift */ > + if (startoff < left.br_startoff + left.br_blockcount) { > error = -EINVAL; > - } else if (offset_shift_fsb > got.br_startoff) { > - /* > - * When first extent is shifted, offset_shift_fsb should > - * be less than the stating offset of the first extent. > - */ > - error = -EINVAL; > + goto del_cursor; > + } > + > + if (xfs_bmap_shift_extents_can_merge(&left, &got, > + offset_shift_fsb)) { > + error = xfs_bmap_shift_extents_merge(ip, whichfork, > + offset_shift_fsb, current_ext, gotp, > + leftp, cur, &logflags); > + if (error) > + goto del_cursor; > + > + /* > + * The extent was merged so adjust the extent > + * index and move onto the next. > + */ > + current_ext--; > + goto next; > + } > } > - if (error) > - goto del_cursor; > > + /* > + * We didn't merge the extent so do the shift. Update the start > + * offset in the in-core extent and btree, if necessary. > + */ > + xfs_bmbt_set_startoff(gotp, startoff); > + logflags |= XFS_ILOG_CORE; > if (cur) { > error = xfs_bmbt_lookup_eq(cur, got.br_startoff, > got.br_startblock, This doesn't do a lot to improve the code. It increases the level of indent and, IMO, makes it harder to read. It's a classic case of function names getting so long there's no space left for the code... So, how about s/xfs_bmap_shift_extents/xfs_bmse/ as a means of reducing the namespace verbosity? And, really, that whole loop body could be pushed into a separate function. i.e while (nexts++ < num_exts) { error = xfs_bmse_collapse_one(ip, ifp, cur, ¤t_ext, gotp, offset_shift_fsb, &logflags); if (error) goto del_cursor; /* check against total extent count, grab the next record */ total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); if (current_ext >= total_extents) break; gotp = xfs_iext_get_ext(ifp, current_ext); xfs_bmbt_get_all(gotp, &got); } That reduces all the jumps/error cases simply to return statements, allowing them to be ordered clearly to minimise the indent of the code. It also means that way the value of current_ext changes is obvious, rather than having the decrement/increment because of the "next iteration" handling in the loop always incrementing the value. Even the initial check outside the loop for: if (current_ext == 0 && got.br_startoff < offset_shift_fsb) { error = -EINVAL; goto del_cursor } could be driven inside xfs_bmse_collapse_one() as the first check that is done, and that would further simplify xfs_bmap_shift_extents(). i.e. xfs_bmse_collapse_one() { if (*current_ext == 0) { if (got.br_startoff < offset_shift_fsb) return -EINVAL; goto shift_extent; } /* get left, do merge checks */ .... if (!xfs_bmse_can_merge(&left, &got, offset_shift_fsb)) goto shift_extent; return xfs_bmse_merge(ip, whichfork, ...) shift_extent: (*current_ext)++; xfs_bmbt_set_startoff(gotp, startoff); logflags |= XFS_ILOG_CORE; if (!cur) *logflags |= XFS_ILOG_DEXT; return 0; } /* do btree shift */ .... return error; } This way we end up with a set of well defined operations, along with clear logic on how they are iterated to make do the overall shift operation. What do you think? Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Tue Sep 9 00:13:34 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 18B047F4E for ; Tue, 9 Sep 2014 00:13:34 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id DBD92304043 for ; Mon, 8 Sep 2014 22:13:30 -0700 (PDT) X-ASG-Debug-ID: 1410239608-04bdf0109a8428f0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id mIm1tSlXIFqOZtBn for ; Mon, 08 Sep 2014 22:13:28 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Al0/ALGLDlR5LKYhPGdsb2JhbABZgw2BKoIsrkoGmm+FaQICAQEBgRAXBQEBAQE4N4QEAQUnExwjEAgDDgoJJQ8FJQMHGhOIQbwgARcYhWSEBIVNB4MvgR0FhhqJEo1GmSIrL4JPAQEB Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 09 Sep 2014 14:43:27 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XRDk6-0003i4-N7; Tue, 09 Sep 2014 15:13:26 +1000 Date: Tue, 9 Sep 2014 15:13:26 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH 3/4] xfs: writeback and inval. file range to be shifted by collapse Message-ID: <20140909051326.GE20518@dastard> X-ASG-Orig-Subj: Re: [PATCH 3/4] xfs: writeback and inval. file range to be shifted by collapse References: <1410092760-3451-1-git-send-email-bfoster@redhat.com> <1410092760-3451-4-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1410092760-3451-4-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410239608 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9300 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sun, Sep 07, 2014 at 08:25:59AM -0400, Brian Foster wrote: > The collapse range operation currently writes the entire file before > starting the collapse to avoid changes in the in-core extent list due to > writeback causing the extent count to change. Now that collapse range is > fsb based rather than extent index based it can sustain changes in the > extent list during the shift sequence without disruption. > > Modify xfs_collapse_file_space() to writeback and invalidate pages > associated with the range of the file to be shifted. > xfs_free_file_space() currently has similar behavior, but the space free > need only affect the region of the file that is freed and this could > change in the future. > > Also update the comments to reflect the current implementation. We > retain the eofblocks trim permanently as a best option for dealing with > delalloc extents. We don't shift delalloc extents because this scenario > only occurs with post-eof preallocation (since data must be flushed such > that the cache can be invalidated and data can be shifted). That means > said space must also be initialized before being shifted into the > accessible region of the file only to be immediately truncated off as > the last part of the collapse. In other words, the eofblocks trim will > happen anyways, we just run it first to ensure the file remains in a > consistent state throughout the collapse. > > Finally, BUG() in the event of a delalloc extent during the extent shift > such that a failure is obvious. The implementation explicitly does not > support delalloc extents and the caller is expected to prevent this > scenario in advance as is done by collapse. > > Signed-off-by: Brian Foster > --- > fs/xfs/libxfs/xfs_bmap.c | 2 ++ > fs/xfs/xfs_bmap_util.c | 32 +++++++++++++++++++------------- > 2 files changed, 21 insertions(+), 13 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > index 449a016..1dd04c2 100644 > --- a/fs/xfs/libxfs/xfs_bmap.c > +++ b/fs/xfs/libxfs/xfs_bmap.c > @@ -5617,6 +5617,8 @@ xfs_bmap_shift_extents( > */ > total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); > while (nexts++ < num_exts && current_ext < total_extents) { > + /* can't handle delalloc extents */ > + BUG_ON(isnullstartblock(got.br_startblock)); XFS_WANT_CORRUPTED_GOTO() would be better, I think. Otherwise OK. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Tue Sep 9 00:14:54 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 810A37F52 for ; Tue, 9 Sep 2014 00:14:54 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 607FE8F8049 for ; Mon, 8 Sep 2014 22:14:54 -0700 (PDT) X-ASG-Debug-ID: 1410239692-04bdf010a0842bf0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id I58hVrfE4r8RDGj9 for ; Mon, 08 Sep 2014 22:14:52 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Alw/ALGLDlR5LKYhPGdsb2JhbABZgw2BKoIsrkoGmm+FaQICAQEBgRAXBQEBAQE4N4QEAQU6HCMQCAMOCgklDwUlAwcaE4hBvCABFxiFZIlRB4MvgR0FjyyNRpkiKy+CTwEBAQ Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 09 Sep 2014 14:44:51 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XRDlS-0003iH-TA; Tue, 09 Sep 2014 15:14:50 +1000 Date: Tue, 9 Sep 2014 15:14:50 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH 4/4] xfs: only writeback and truncate pages for the freed range Message-ID: <20140909051450.GF20518@dastard> X-ASG-Orig-Subj: Re: [PATCH 4/4] xfs: only writeback and truncate pages for the freed range References: <1410092760-3451-1-git-send-email-bfoster@redhat.com> <1410092760-3451-5-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1410092760-3451-5-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410239692 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9300 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sun, Sep 07, 2014 at 08:26:00AM -0400, Brian Foster wrote: > xfs_free_file_space() only affects the range of the file for which space > is being freed. It currently writes and truncates the page cache from > the start offset of the free to EOF. > > Modify xfs_free_file_space() to write back and truncate page cache of > just the range being freed. > > Signed-off-by: Brian Foster looks good. Reviewed-by: Dave Chinner -- Dave Chinner david@fromorbit.com From bfoster@redhat.com Tue Sep 9 09:29:20 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 28F897F3F for ; Tue, 9 Sep 2014 09:29:20 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 79C0FAC004 for ; Tue, 9 Sep 2014 07:29:16 -0700 (PDT) X-ASG-Debug-ID: 1410272951-04cbb05487b71cf0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id iO60noJrO4HE8T6a (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 09 Sep 2014 07:29:11 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s89ET9aS025319 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 9 Sep 2014 10:29:10 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s89DixX0000407; Tue, 9 Sep 2014 09:44:59 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 86F681256F8; Tue, 9 Sep 2014 09:44:58 -0400 (EDT) Date: Tue, 9 Sep 2014 09:44:58 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: xlog_cil_force_lsn doesn't always wait correctly Message-ID: <20140909134458.GA35182@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs: xlog_cil_force_lsn doesn't always wait correctly References: <1410226995-15714-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1410226995-15714-1-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410272951 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Sep 09, 2014 at 11:43:15AM +1000, Dave Chinner wrote: > From: Dave Chinner > > When running a tight mount/unmount loop on an older kernel, RedHat > QE found that unmount would occasionally hang in > xfs_buf_unpin_wait() on the superblock buffer. Tracing and other > debug work by Eric Sandeen indicated that it was hanging on the > writing of the superblock during unmount immediately after logging > the superblock counters in a synchronous transaction. Further debug > indicated that the synchronous transaction was not waiting for > completion correctly, and we narrowed it down to > xlog_cil_force_lsn() returning NULLCOMMITLSN and hence not pushing > the transaction in the iclog buffer to disk correctly. > > While this unmount superblock write code is now very different in > mainline kernels, the xlog_cil_force_lsn() code is identical, and it > was bisected to the backport of commit f876e44 ("xfs: always do log > forces via the workqueue"). This commit made the CIL push > asynchronous for log forces and hence exposed a race condition that > couldn't occur on a synchronous push. > > Essentially, the xlog_cil_force_lsn() relied implicitly on the fact > that the sequence push would be complete by the time > xlog_cil_push_now() returned, resulting in the context being pushed > being in the committing list. When it was made asynchronous, it was > recognised that there was a race condition in detecting whether an > asynchronous push has started or not and code was added to handle > it. > > Unfortunately, the fix was not quite right and left a race condition > where it it would detect an empty CIL while a push was in progress > before the context had been added to the committing list. This was > incorrectly seen as a "nothing to do" condition and so would tell > xfs_log_force_lsn() that there is nothing to wait for, and hence it > would push the iclogbufs in memory. > > The fix is simple, but explaining the logic and the race condition > is a lot more complex. The fix is to add the context to the > committing list before we start emptying the CIL. This allows us to > detect the difference between an empty "do nothing" push and a push > that has not started by adding a discrete "emptying the CIL" state > to avoid the transient, incorrect "empty" condition that the > (unchanged) waiting code was seeing. > > Signed-off-by: Dave Chinner > Tested-by: Eric Sandeen > --- The pusher side queues the work, acquires xc_push_lock, walks the committing list and then does this: if (sequence == cil->xc_current_sequence && !list_empty(&cil->xc_cil)) { spin_unlock(&cil->xc_push_lock); goto restart; } ... which is effectively peeking into the cil state to see if the push actually needed to do anything. The purpose is to identify the case where the push hasn't occurred and the previous committing list traversal was insufficient. The "pushee" side drains the cil, updates the current sequence and adds the ctx to the committing list. The time between the cil drain and list_add() creates a window where, according to the logic above, the cil push looks like it wasn't going to do anything from the pusher perspective. The latter two bits occur under xc_push_lock (spinlock), so perhaps that widens a window to make this slightly more reproducible. The pushee work is all done under xc_ctx_lock, so generally this is an issue because the pusher doesn't acquire xc_ctx_lock, and thus the cil drain and ctx update are not seen as atomic. I presume this is lockless by design, so taking the lock is not a desired solution. Therefore, the order of changes to data structures that the pusher peeks into is updated on the pushee side to add to the committing list, drain the cil and update the current sequence number. For the pusher side, this means the committing list walk and logic above (all under xc_push_lock) either sees the ctx on the list or not. If the ctx is on the list, then we waited for it and there is no race. If the ctx is not on the list, it is either populated and waiting to be added to the list (e.g., we hold xc_push_lock) or empty and there's nothing to do (regardless of whether the pusher side has run or not). That seems sound to me. It would be nice of we could somehow make this explicitly more simple rather than dependent on complex ordering (e.g., a push completion or something of that sort), but that's for another time. One nit below... > fs/xfs/xfs_log_cil.c | 47 ++++++++++++++++++++++++++++++++++++++--------- > 1 file changed, 38 insertions(+), 9 deletions(-) > > diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c > index f6b79e5..f506c45 100644 > --- a/fs/xfs/xfs_log_cil.c > +++ b/fs/xfs/xfs_log_cil.c > @@ -463,12 +463,40 @@ xlog_cil_push( > spin_unlock(&cil->xc_push_lock); > goto out_skip; > } > - spin_unlock(&cil->xc_push_lock); > > > /* check for a previously pushed seqeunce */ > - if (push_seq < cil->xc_ctx->sequence) > + if (push_seq < cil->xc_ctx->sequence) { > + spin_unlock(&cil->xc_push_lock); > goto out_skip; > + } > + Looks like out_skip could unlock xc_push_lock now. Reviewed-by: Brian Foster > + /* > + * We are now going to push this context, so add it to the committing > + * list before we do anything else. This ensures that anyone waiting on > + * this push can easily detect the difference between a "push in > + * progress" and "CIL is empty, nothing to do". > + * > + * IOWs, a wait loop can now check for: > + * the current sequence not being found on the committing list; > + * an empty CIL; and > + * an unchanged sequence number > + * to detect a push that had nothing to do and therefore does not need > + * waiting on. If the CIL is not empty, we get put on the committing > + * list before emptying the CIL and bumping the sequence number. Hence > + * an empty CIL and an unchanged sequence number means we jumped out > + * above after doing nothing. > + * > + * Hence the waiter will either find the commit sequence on the > + * committing list or the sequence number will be unchanged and the CIL > + * still dirty. In that latter case, the push has not yet started, and > + * so the waiter will have to continue trying to check the CIL > + * committing list until it is found. In extreme cases of delay, the > + * sequence may fully commit between the attempts the wait makes to wait > + * on the commit sequence. > + */ > + list_add(&ctx->committing, &cil->xc_committing); > + spin_unlock(&cil->xc_push_lock); > > /* > * pull all the log vectors off the items in the CIL, and > @@ -532,7 +560,6 @@ xlog_cil_push( > */ > spin_lock(&cil->xc_push_lock); > cil->xc_current_sequence = new_ctx->sequence; > - list_add(&ctx->committing, &cil->xc_committing); > spin_unlock(&cil->xc_push_lock); > up_write(&cil->xc_ctx_lock); > > @@ -855,13 +882,15 @@ restart: > * Hence by the time we have got here it our sequence may not have been > * pushed yet. This is true if the current sequence still matches the > * push sequence after the above wait loop and the CIL still contains > - * dirty objects. > + * dirty objects. This is guaranteed by the push code first adding the > + * context to the committing list before emptying the CIL. > * > - * When the push occurs, it will empty the CIL and atomically increment > - * the currect sequence past the push sequence and move it into the > - * committing list. Of course, if the CIL is clean at the time of the > - * push, it won't have pushed the CIL at all, so in that case we should > - * try the push for this sequence again from the start just in case. > + * Hence if we don't find the context in the committing list and the > + * current sequence number is unchanged then the CIL contents are > + * significant. If the CIL is empty, if means there was nothing to push > + * and that means there is nothing to wait for. If the CIL is not empty, > + * it means we haven't yet started the push, because if it had started > + * we would have found the context on the committing list. > */ > if (sequence == cil->xc_current_sequence && > !list_empty(&cil->xc_cil)) { > -- > 2.0.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Tue Sep 9 10:04:38 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2D4FB7F3F for ; Tue, 9 Sep 2014 10:04:38 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0D54A8F8033 for ; Tue, 9 Sep 2014 08:04:34 -0700 (PDT) X-ASG-Debug-ID: 1410275069-04cb6c54fd8df010001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id qV06eSObmJmuHtt1 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 09 Sep 2014 08:04:30 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s89F4Sev007494 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 9 Sep 2014 11:04:28 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s89F4R3j008375; Tue, 9 Sep 2014 11:04:27 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 99AFD1256F8; Tue, 9 Sep 2014 11:04:26 -0400 (EDT) Date: Tue, 9 Sep 2014 11:04:26 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/4] xfs: refactor xfs_bmap_shift_extents() into multiple functions Message-ID: <20140909150426.GC35182@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 2/4] xfs: refactor xfs_bmap_shift_extents() into multiple functions References: <1410092760-3451-1-git-send-email-bfoster@redhat.com> <1410092760-3451-3-git-send-email-bfoster@redhat.com> <20140909050800.GD20518@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140909050800.GD20518@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410275070 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Sep 09, 2014 at 03:08:00PM +1000, Dave Chinner wrote: > On Sun, Sep 07, 2014 at 08:25:58AM -0400, Brian Foster wrote: > > The extent shift mechanism in xfs_bmap_shift_extents() is complicated > > and handles several different, non-deterministic scenarios. These > > include extent shifts, extent merges and potential btree updates in > > either of the former scenarios. > > > > Refactor the code to be more linear and readable. The loop logic in > > xfs_bmap_shift_extents() and some initial error checking is adjusted > > slightly. The associated btree lookup and update/delete operations are > > condensed into single blocks of code. This reduces the number of > > btree-specific blocks and facilitates the separation of the merge > > operation into a new xfs_bmap_shift_extents_merge() helper. The merge > > check is also separated into an inline. > > > > This is a code refactor only. The behavior of extent shift and collapse > > range is not modified. > > > > Signed-off-by: Brian Foster > > --- > > fs/xfs/libxfs/xfs_bmap.c | 243 ++++++++++++++++++++++++++++++++--------------- > > 1 file changed, 168 insertions(+), 75 deletions(-) > > > > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > > index 4b3f1b9..449a016 100644 > > --- a/fs/xfs/libxfs/xfs_bmap.c > > +++ b/fs/xfs/libxfs/xfs_bmap.c > > @@ -5404,6 +5404,120 @@ error0: > > } > > > > /* > > + * Determine whether an extent shift can be accomplished by a merge with the > > + * extent that precedes the target hole of the shift. > > + */ > > +static inline bool > > +xfs_bmap_shift_extents_can_merge( > > No need for "inline" for static functions. The compiler will do that > as an optimisation if appropriate. > Ok. > > + struct xfs_bmbt_irec *left, /* preceding extent */ > > + struct xfs_bmbt_irec *got, /* current extent to shift */ > > + xfs_fileoff_t shift) /* shift fsb */ > > +{ > > + xfs_fileoff_t startoff; > > + > > + startoff = got->br_startoff - shift; > > + > > + /* > > + * The extent, once shifted, must be adjacent in-file and on-disk with > > + * the preceding extent. > > + */ > > + if ((left->br_startoff + left->br_blockcount != startoff) || > > + (left->br_startblock + left->br_blockcount != got->br_startblock) || > > + (left->br_state != got->br_state) || > > + (left->br_blockcount + got->br_blockcount > MAXEXTLEN)) > > + return false; > > + > > + return true; > > +} > > + > > +/* > > + * An extent shift adjusts the file offset of an extent to fill a preceding hole > > + * in the file. If an extent shift would result in the extent being fully > > + * adjacent to the extent that currently precedes the hole, we can merge with > > + * the preceding extent rather than do the shift. > > + * > > + * This function assumes the caller has verified a shift-by-merge is possible > > + * with the provided extents via xfs_bmap_shift_extents_can_merge(). > > + */ > > +static int > > +xfs_bmap_shift_extents_merge( > > + struct xfs_inode *ip, > > + int whichfork, > > + xfs_fileoff_t shift, /* shift fsb */ > > + int current_ext, /* idx of gotp */ > > + struct xfs_bmbt_rec_host *gotp, /* extent to shift */ > > + struct xfs_bmbt_rec_host *leftp, /* preceding extent */ > > + struct xfs_btree_cur *cur, > > + int *logflags) /* output */ > > +{ > > + struct xfs_ifork *ifp; > > + struct xfs_bmbt_irec got; > > + struct xfs_bmbt_irec left; > > + xfs_filblks_t blockcount; > > + int error, i; > > + > > + ifp = XFS_IFORK_PTR(ip, whichfork); > > + xfs_bmbt_get_all(gotp, &got); > > + xfs_bmbt_get_all(leftp, &left); > > + blockcount = left.br_blockcount + got.br_blockcount; > > + > > + ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); > > + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); > > + ASSERT(xfs_bmap_shift_extents_can_merge(&left, &got, shift)); > > + > > + /* > > + * Merge the in-core extents. Note that the host record pointers and > > + * current_ext index are invalid once the extent has been removed via > > + * xfs_iext_remove(). > > + */ > > + xfs_bmbt_set_blockcount(leftp, blockcount); > > + xfs_iext_remove(ip, current_ext, 1, 0); > > + > > + /* > > + * Update the on-disk extent count, the btree if necessary and log the > > + * inode. > > + */ > > + XFS_IFORK_NEXT_SET(ip, whichfork, > > + XFS_IFORK_NEXTENTS(ip, whichfork) - 1); > > + *logflags |= XFS_ILOG_CORE; > > + if (cur) { > > + /* lookup and remove the extent to merge */ > > + error = xfs_bmbt_lookup_eq(cur, got.br_startoff, > > + got.br_startblock, got.br_blockcount, &i); > > + if (error) > > + goto error; > > Probably shouldn't give the jump label the same name as a variable > in the function. "out_error" is commonly used here. > Ok. > > + XFS_WANT_CORRUPTED_GOTO(i == 1, error); > > + > > + error = xfs_btree_delete(cur, &i); > > + if (error) > > + goto error; > > + XFS_WANT_CORRUPTED_GOTO(i == 1, error); > > + > > + /* lookup and update size of the previous extent */ > > + error = xfs_bmbt_lookup_eq(cur, left.br_startoff, > > + left.br_startblock, left.br_blockcount, &i); > > + if (error) > > + goto error; > > + XFS_WANT_CORRUPTED_GOTO(i == 1, error); > > + > > + left.br_blockcount = blockcount; > > + > > + error = xfs_bmbt_update(cur, left.br_startoff, > > + left.br_startblock, left.br_blockcount, > > + left.br_state); > > + if (error) > > + goto error; > > + } else { > > + *logflags |= XFS_ILOG_DEXT; > > + } > > + > > + return 0; > > + > > +error: > > + return error; > > This code is much clearer, though I'd get rid of further > indents by changing the logic around like so: > Yeah, good idea. > .... > *logflags |= XFS_ILOG_CORE; > if (!cur) { > *logflags |= XFS_ILOG_DEXT; > return 0; > } > > /* lookup and remove the extent to merge */ > error = xfs_bmbt_lookup_eq(cur, got.br_startoff, > got.br_startblock, got.br_blockcount, &i); > if (error) > goto out_error; > ..... > > error = xfs_bmbt_update(cur, left.br_startoff, > left.br_startblock, left.br_blockcount, > left.br_state); > out_error: > return error; > } > > > @@ -5493,30 +5617,42 @@ xfs_bmap_shift_extents( > > */ > > total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); > > while (nexts++ < num_exts && current_ext < total_extents) { > > - > > - gotp = xfs_iext_get_ext(ifp, current_ext); > > - xfs_bmbt_get_all(gotp, &got); > > startoff = got.br_startoff - offset_shift_fsb; > > > > - /* > > - * Before shifting extent into hole, make sure that the hole is > > - * large enough to accommodate the shift. > > - */ > > + /* grab the left extent and check for a potential merge */ > > if (current_ext > 0) { > > - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, current_ext - 1), > > - &left); > > - if (startoff < left.br_startoff + left.br_blockcount) > > + leftp = xfs_iext_get_ext(ifp, current_ext - 1); > > + xfs_bmbt_get_all(leftp, &left); > > + > > + /* make sure hole is large enough for shift */ > > + if (startoff < left.br_startoff + left.br_blockcount) { > > error = -EINVAL; > > - } else if (offset_shift_fsb > got.br_startoff) { > > - /* > > - * When first extent is shifted, offset_shift_fsb should > > - * be less than the stating offset of the first extent. > > - */ > > - error = -EINVAL; > > + goto del_cursor; > > + } > > + > > + if (xfs_bmap_shift_extents_can_merge(&left, &got, > > + offset_shift_fsb)) { > > + error = xfs_bmap_shift_extents_merge(ip, whichfork, > > + offset_shift_fsb, current_ext, gotp, > > + leftp, cur, &logflags); > > + if (error) > > + goto del_cursor; > > + > > + /* > > + * The extent was merged so adjust the extent > > + * index and move onto the next. > > + */ > > + current_ext--; > > + goto next; > > + } > > } > > - if (error) > > - goto del_cursor; > > > > + /* > > + * We didn't merge the extent so do the shift. Update the start > > + * offset in the in-core extent and btree, if necessary. > > + */ > > + xfs_bmbt_set_startoff(gotp, startoff); > > + logflags |= XFS_ILOG_CORE; > > if (cur) { > > error = xfs_bmbt_lookup_eq(cur, got.br_startoff, > > got.br_startblock, > > This doesn't do a lot to improve the code. It increases the level of > indent and, IMO, makes it harder to read. It's a classic case of > function names getting so long there's no space left for the code... > > So, how about s/xfs_bmap_shift_extents/xfs_bmse/ as a means of > reducing the namespace verbosity? And, really, that whole loop body > could be pushed into a separate function. i.e > > while (nexts++ < num_exts) { > error = xfs_bmse_collapse_one(ip, ifp, cur, ¤t_ext, gotp, > offset_shift_fsb, &logflags); > if (error) > goto del_cursor; > > /* check against total extent count, grab the next record */ > total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); > if (current_ext >= total_extents) > break; > gotp = xfs_iext_get_ext(ifp, current_ext); > xfs_bmbt_get_all(gotp, &got); > } > > That reduces all the jumps/error cases simply to return statements, > allowing them to be ordered clearly to minimise the indent of > the code. It also means that way the value of current_ext changes is > obvious, rather than having the decrement/increment because of the > "next iteration" handling in the loop always incrementing the value. > > Even the initial check outside the loop for: > > if (current_ext == 0 && got.br_startoff < offset_shift_fsb) { > error = -EINVAL; > goto del_cursor > } > > could be driven inside xfs_bmse_collapse_one() as the first check that > is done, and that would further simplify xfs_bmap_shift_extents(). > i.e. > > xfs_bmse_collapse_one() > { > if (*current_ext == 0) { > if (got.br_startoff < offset_shift_fsb) > return -EINVAL; > goto shift_extent; > } > > /* get left, do merge checks */ > .... > if (!xfs_bmse_can_merge(&left, &got, offset_shift_fsb)) > goto shift_extent; > > return xfs_bmse_merge(ip, whichfork, ...) > > shift_extent: > (*current_ext)++; > xfs_bmbt_set_startoff(gotp, startoff); > logflags |= XFS_ILOG_CORE; > if (!cur) > *logflags |= XFS_ILOG_DEXT; > return 0; > } > > /* do btree shift */ > .... > return error; > } > > This way we end up with a set of well defined operations, along > with clear logic on how they are iterated to make do the overall > shift operation. > > What do you think? > That all sounds pretty good to me. I may incorporate the aforementioned updates to the merge bits to this patch and create a new patch for the subsequent refactor of the loop body. E.g., this patch becomes "... refactor extent merge into new function." But I'll play with it and see what falls out... thanks for the feedback. Brian > Cheers, > > Dave. > > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Tue Sep 9 10:17:02 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id EBE8E7F3F for ; Tue, 9 Sep 2014 10:17:02 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id BB67E304048 for ; Tue, 9 Sep 2014 08:17:02 -0700 (PDT) X-ASG-Debug-ID: 1410275821-04bdf0109a891390001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 3U7TaoniPoGn56GI (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 09 Sep 2014 08:17:01 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s89FGxfR007313 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 9 Sep 2014 11:16:59 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s89FGwPW014596; Tue, 9 Sep 2014 11:16:58 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id AB6B21256F8; Tue, 9 Sep 2014 11:16:57 -0400 (EDT) Date: Tue, 9 Sep 2014 11:16:57 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 3/4] xfs: writeback and inval. file range to be shifted by collapse Message-ID: <20140909151657.GD35182@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 3/4] xfs: writeback and inval. file range to be shifted by collapse References: <1410092760-3451-1-git-send-email-bfoster@redhat.com> <1410092760-3451-4-git-send-email-bfoster@redhat.com> <20140909051326.GE20518@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140909051326.GE20518@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410275821 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Sep 09, 2014 at 03:13:26PM +1000, Dave Chinner wrote: > On Sun, Sep 07, 2014 at 08:25:59AM -0400, Brian Foster wrote: > > The collapse range operation currently writes the entire file before > > starting the collapse to avoid changes in the in-core extent list due to > > writeback causing the extent count to change. Now that collapse range is > > fsb based rather than extent index based it can sustain changes in the > > extent list during the shift sequence without disruption. > > > > Modify xfs_collapse_file_space() to writeback and invalidate pages > > associated with the range of the file to be shifted. > > xfs_free_file_space() currently has similar behavior, but the space free > > need only affect the region of the file that is freed and this could > > change in the future. > > > > Also update the comments to reflect the current implementation. We > > retain the eofblocks trim permanently as a best option for dealing with > > delalloc extents. We don't shift delalloc extents because this scenario > > only occurs with post-eof preallocation (since data must be flushed such > > that the cache can be invalidated and data can be shifted). That means > > said space must also be initialized before being shifted into the > > accessible region of the file only to be immediately truncated off as > > the last part of the collapse. In other words, the eofblocks trim will > > happen anyways, we just run it first to ensure the file remains in a > > consistent state throughout the collapse. > > > > Finally, BUG() in the event of a delalloc extent during the extent shift > > such that a failure is obvious. The implementation explicitly does not > > support delalloc extents and the caller is expected to prevent this > > scenario in advance as is done by collapse. > > > > Signed-off-by: Brian Foster > > --- > > fs/xfs/libxfs/xfs_bmap.c | 2 ++ > > fs/xfs/xfs_bmap_util.c | 32 +++++++++++++++++++------------- > > 2 files changed, 21 insertions(+), 13 deletions(-) > > > > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > > index 449a016..1dd04c2 100644 > > --- a/fs/xfs/libxfs/xfs_bmap.c > > +++ b/fs/xfs/libxfs/xfs_bmap.c > > @@ -5617,6 +5617,8 @@ xfs_bmap_shift_extents( > > */ > > total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); > > while (nexts++ < num_exts && current_ext < total_extents) { > > + /* can't handle delalloc extents */ > > + BUG_ON(isnullstartblock(got.br_startblock)); > > XFS_WANT_CORRUPTED_GOTO() would be better, I think. > Ok. I suppose we'll shutdown the fs if the transaction was dirtied by that point anyways. I want to make sure the failure is explicit more than anything, as opposed to an unclear and non-guaranteed lookup failure in the event of a btree, so that works for me. Brian > Otherwise OK. > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From lrhorer@mygrande.net Tue Sep 9 10:21:39 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B7FDA7F3F for ; Tue, 9 Sep 2014 10:21:39 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id A52D68F8033 for ; Tue, 9 Sep 2014 08:21:39 -0700 (PDT) X-ASG-Debug-ID: 1410276098-04cb6c55008e5420001-NocioJ Received: from mail02.lsn.net (mail02.lsn.net [66.90.130.128]) by cuda.sgi.com with ESMTP id xlASPbMt4ehFJtFP for ; Tue, 09 Sep 2014 08:21:38 -0700 (PDT) X-Barracuda-Envelope-From: lrhorer@mygrande.net X-Barracuda-Apparent-Source-IP: 66.90.130.128 Received: from [192.168.1.121] (24-155-170-173.dyn.grandenetworks.net [24.155.170.173]) (authenticated bits=0) by mail02.lsn.net (8.14.4/8.13.6) with ESMTP id s89FLbvW016316 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Tue, 9 Sep 2014 10:21:38 -0500 X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.98.4 at av02.lsn.net Message-ID: <540F1B01.3020700@mygrande.net> Date: Tue, 09 Sep 2014 10:21:37 -0500 From: Leslie Rhorer User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: xfs@oss.sgi.com Subject: Corrupted files Content-Type: text/plain; charset=ISO-8859-1; format=flowed X-ASG-Orig-Subj: Corrupted files Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail02.lsn.net[66.90.130.128] X-Barracuda-Start-Time: 1410276098 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9311 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hello, I have an issue with my primary RAID array. I have 13T of data on the array, and I suffered a major array failure. I was able to rebuild the array, but some data was lost. Of course I have backups, so after running xfs_repair, I ran an rsync job to recover the lost data. Most of it was recovered, but there are several files that cannot be read, deleted, or overwritten. I have tried running xfs_repair several times, but any attempt to access these files continuously reports "cannot stat XXXXXXXX: Structure needs cleaning". I don't need to try to recover the data directly, as it does reside on the backup, but I need to clear the file structure so I can write the files back to the filesystem. How do I proceed? From scaron@umich.edu Tue Sep 9 10:50:34 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 6B38E7F3F for ; Tue, 9 Sep 2014 10:50:34 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 3B42A8F8040 for ; Tue, 9 Sep 2014 08:50:34 -0700 (PDT) X-ASG-Debug-ID: 1410277831-04bdf0109a897ec0001-NocioJ Received: from mail-qc0-f182.google.com (mail-qc0-f182.google.com [209.85.216.182]) by cuda.sgi.com with ESMTP id MHQF2yBbRRG3iizJ (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Tue, 09 Sep 2014 08:50:32 -0700 (PDT) X-Barracuda-Envelope-From: scaron@umich.edu X-Barracuda-Apparent-Source-IP: 209.85.216.182 Received: by mail-qc0-f182.google.com with SMTP id x13so4563568qcv.27 for ; Tue, 09 Sep 2014 08:50:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=6Jk96zXZgVhiP8yAZ0S0bvg8qEf3S6I5j9Lj5rwVHJE=; b=OE4Fg0XDCOf6Sfr74kbTq5rYPYeucfQAYch5Uca3GeD08GAmMCMC1jAT/eg8okGJ0g AGYzPmusFykl6J+n7dvvSpV+tdNVUDZwpntOYOzX5oKuLYTMD2uXOFmHfKEuK2hqKpk3 8utlck7T0acUsU07lp5FoD/uMUEdhWWdFYF9aD98k3Eq0fUkgJ1304Ebc7KUIgV/AK4U 5Do5RCSGHNrfvvaaJCxfj0yKKsJH99yeSezBz1ChVZPb1mpfWC6h7Sn+atQq1rXlq/DS weGc/Loo7vVWPf8ubyuSoj+FVt6e3HU26iz3HMKMWkFXBjESblm7LroR8IPxxEfK6lIu tEfg== X-Gm-Message-State: ALoCoQlKlZUuiwBf6Gslsqv9oatJEchZuhZG1axAVduIqX+IKzAa2N/SawaLvVw7tjZa5zZIlI4j MIME-Version: 1.0 X-Received: by 10.140.17.9 with SMTP id 9mr14074783qgc.47.1410277828312; Tue, 09 Sep 2014 08:50:28 -0700 (PDT) Received: by 10.224.8.132 with HTTP; Tue, 9 Sep 2014 08:50:28 -0700 (PDT) In-Reply-To: <540F1B01.3020700@mygrande.net> References: <540F1B01.3020700@mygrande.net> Date: Tue, 9 Sep 2014 11:50:28 -0400 Message-ID: Subject: Re: Corrupted files From: Sean Caron X-ASG-Orig-Subj: Re: Corrupted files To: Leslie Rhorer , Sean Caron Cc: "xfs@oss.sgi.com" Content-Type: multipart/alternative; boundary=001a11c0b36afdf0b70502a3e41a X-Barracuda-Connect: mail-qc0-f182.google.com[209.85.216.182] X-Barracuda-Start-Time: 1410277831 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9311 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message --001a11c0b36afdf0b70502a3e41a Content-Type: text/plain; charset=UTF-8 Hi Leslie, If you have a full backup, I would STRONGLY recommend just wiping your old filesystem and restoring your backups on top of a totally fresh XFS, rather than repairing the original filesystem and then filling in the blanks with backups using a file-diff tool like rsync. You will probably hear various opinions here about xfs_repair; my personal opinion is that xfs_repair is a program made available for the unwary to further scramble their data and make a hash of the filesystem... In my first-hand experience managing ~7 PB of XFS storage and growing, I have NEVER found xfs_repair (yes, even the "newest version") to ever do anything positive. It's basically a data scrambler. At this point, you will never achieve anything near what I'd consider a production-grade, trustworthy data repository. Any further runs of xfs_repair will either do nothing, or make the situation worse. Fortunately you followed best practice and kept backups so you don't really need xfs_repair anyway, right? Best, Sean P.S. No backups? Still don't even think about running xfs_repair. ESPECIALLY don't think about running xfs_repair. Try mounting ro; if that doesn't work, mount ro with noreplaylog and scavenge what you can. Write off the rest. That's the cost of doing business without backups. Running xfs_repair (especially as a first-line step) will only make it worse, and especially on big filesystems, the run time can extend to weeks... Don't keep your users down any longer than you need to, running a program that won't really help you. Just scavenge it, reformat and turn it back around. On Tue, Sep 9, 2014 at 11:21 AM, Leslie Rhorer wrote: > > Hello, > > I have an issue with my primary RAID array. I have 13T of data on > the array, and I suffered a major array failure. I was able to rebuild the > array, but some data was lost. Of course I have backups, so after running > xfs_repair, I ran an rsync job to recover the lost data. Most of it was > recovered, but there are several files that cannot be read, deleted, or > overwritten. I have tried running xfs_repair several times, but any > attempt to access these files continuously reports "cannot stat XXXXXXXX: > Structure needs cleaning". I don't need to try to recover the data > directly, as it does reside on the backup, but I need to clear the file > structure so I can write the files back to the filesystem. How do I > proceed? > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs > --001a11c0b36afdf0b70502a3e41a Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi Leslie,

If you have a full backup, I= would STRONGLY recommend just wiping your old filesystem and restoring you= r backups on top of a totally fresh XFS, rather than repairing the original= filesystem and then filling in the blanks with backups using a file-diff t= ool like rsync.

You will probably hear various opi= nions here about xfs_repair; my personal opinion is that xfs_repair is a pr= ogram made available for the unwary to further scramble their data and make= a hash of the filesystem... In my first-hand experience managing ~7 PB of = XFS storage and growing, I have NEVER found xfs_repair (yes, even the "= ;newest version") to ever do anything positive. It's basically a d= ata scrambler.

At this point, you will never achie= ve anything near what I'd consider a production-grade, trustworthy data= repository. Any further runs of xfs_repair will either do nothing, or make= the situation worse. Fortunately you followed best practice and kept backu= ps so you don't really need xfs_repair anyway, right?

Best,

Sean

P.S. N= o backups? Still don't even think about running xfs_repair. ESPECIALLY = don't think about running xfs_repair. Try mounting ro; if that doesn= 9;t work, mount ro with noreplaylog and scavenge what you can. Write off th= e rest. That's the cost of doing business without backups. Running xfs_= repair (especially as a first-line step) will only make it worse, and espec= ially on big filesystems, the run time can extend to weeks... Don't kee= p your users down any longer than you need to, running a program that won&#= 39;t really help you. Just scavenge it, reformat and turn it back around.





On Tue, Sep 9, 2014 at= 11:21 AM, Leslie Rhorer <lrhorer@mygrande.net> wrote:

Hello,

=C2=A0 =C2=A0 =C2=A0 =C2=A0 I have an issue with my primary RAID array.=C2= =A0 I have 13T of data on the array, and I suffered a major array failure.= =C2=A0 I was able to rebuild the array, but some data was lost.=C2=A0 Of co= urse I have backups, so after running xfs_repair, I ran an rsync job to rec= over the lost data.=C2=A0 Most of it was recovered, but there are several f= iles that cannot be read, deleted, or overwritten.=C2=A0 I have tried runni= ng xfs_repair several times, but any attempt to access these files continuo= usly reports "cannot stat XXXXXXXX: Structure needs cleaning".=C2= =A0 I don't need to try to recover the data directly, as it does reside= on the backup, but I need to clear the file structure so I can write the f= iles back to the filesystem.=C2=A0 How do I proceed?

_______________________________________________
xfs mailing list
xfs@oss.sgi.com http:= //oss.sgi.com/mailman/listinfo/xfs

--001a11c0b36afdf0b70502a3e41a-- From scaron@umich.edu Tue Sep 9 11:04:05 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 07FD47F3F for ; Tue, 9 Sep 2014 11:04:05 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 66A54AC003 for ; Tue, 9 Sep 2014 09:04:01 -0700 (PDT) X-ASG-Debug-ID: 1410278638-04cbb05488b86f60001-NocioJ Received: from mail-qc0-f178.google.com (mail-qc0-f178.google.com [209.85.216.178]) by cuda.sgi.com with ESMTP id YyqEJqwJ5g15dRGx (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Tue, 09 Sep 2014 09:03:59 -0700 (PDT) X-Barracuda-Envelope-From: scaron@umich.edu X-Barracuda-Apparent-Source-IP: 209.85.216.178 Received: by mail-qc0-f178.google.com with SMTP id x13so17476707qcv.37 for ; Tue, 09 Sep 2014 09:03:56 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=9v/UVTMRdzXiUBvQB5G10Xod3NqMv+4icDiwAgRDfek=; b=CLdPX1GkZohuLi3W0FPkmZ/APfjfnuwiXJeA7YYmFcuxQbnaiN5njFC5AhiNTGMTb1 85qYo2Cl88yUtHJqW6M4EcrP2GD2FL5KIqCHjQn7w3/2Jr58QVqCJ/okKF2jIxf2MjUb f8LTsPSnCQAcRQCcRBjLWymiENnkkj5sRozSixaLEpNjubH7KbtOTbo460Yk7L45+/a+ EYEO66ivQTJxEJLg4Uy6wC4dXDg3eDZfxUuo7FqQ/ntc7xdXaJpDNNGam2039+l/qxT9 XLQlwPYkF+AyeejSwjkW5VYc0aSegCPLS9IKSbz1zDgi62ZVNS4T3og6UISK9XwdcbYU fD3A== X-Gm-Message-State: ALoCoQkhAhDIv1xZ3PU+3QJclq4irv2D+P723Jk/fvkO31ModFjwPUhmD1xToUEoy/SUVZ1hSt9y MIME-Version: 1.0 X-Received: by 10.224.167.72 with SMTP id p8mr52986634qay.62.1410278636082; Tue, 09 Sep 2014 09:03:56 -0700 (PDT) Received: by 10.224.8.132 with HTTP; Tue, 9 Sep 2014 09:03:56 -0700 (PDT) In-Reply-To: References: <540F1B01.3020700@mygrande.net> Date: Tue, 9 Sep 2014 12:03:56 -0400 Message-ID: Subject: Re: Corrupted files From: Sean Caron X-ASG-Orig-Subj: Re: Corrupted files To: Leslie Rhorer , Sean Caron Cc: "xfs@oss.sgi.com" Content-Type: multipart/alternative; boundary=089e0149c46e2367870502a41522 X-Barracuda-Connect: mail-qc0-f178.google.com[209.85.216.178] X-Barracuda-Start-Time: 1410278638 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_SA210e, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9311 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 BSF_SC5_SA210e Custom Rule SA210e --089e0149c46e2367870502a41522 Content-Type: text/plain; charset=UTF-8 OK, let me retract just a tiny fraction of what I said originally; thinking about it further, there was _one_ time I was able to use xfs_repair to successfully recover a "lightly bruised" XFS and return it to service. But in that case, the fault was very minor and I always check first with: xfs_repair [-L] -n -v and give the output a good looking over before proceeding further. If it won't run without zeroing the log, you can take that as a sign that things are getting dire.. I wouldn't bother to run xfs_repair "for real" if the trial output looked even slightly non-trivial, in cases of underlying array failure or massive filesystem corruption, and I'd never run it without mounting and scavenging first (unless I had a very recent full backup). Barring rare cases, xfs_repair is bad juju. Best, Sean On Tue, Sep 9, 2014 at 11:50 AM, Sean Caron wrote: > Hi Leslie, > > If you have a full backup, I would STRONGLY recommend just wiping your old > filesystem and restoring your backups on top of a totally fresh XFS, rather > than repairing the original filesystem and then filling in the blanks with > backups using a file-diff tool like rsync. > > You will probably hear various opinions here about xfs_repair; my personal > opinion is that xfs_repair is a program made available for the unwary to > further scramble their data and make a hash of the filesystem... In my > first-hand experience managing ~7 PB of XFS storage and growing, I have > NEVER found xfs_repair (yes, even the "newest version") to ever do anything > positive. It's basically a data scrambler. > > At this point, you will never achieve anything near what I'd consider a > production-grade, trustworthy data repository. Any further runs of > xfs_repair will either do nothing, or make the situation worse. Fortunately > you followed best practice and kept backups so you don't really need > xfs_repair anyway, right? > > Best, > > Sean > > P.S. No backups? Still don't even think about running xfs_repair. > ESPECIALLY don't think about running xfs_repair. Try mounting ro; if that > doesn't work, mount ro with noreplaylog and scavenge what you can. Write > off the rest. That's the cost of doing business without backups. Running > xfs_repair (especially as a first-line step) will only make it worse, and > especially on big filesystems, the run time can extend to weeks... Don't > keep your users down any longer than you need to, running a program that > won't really help you. Just scavenge it, reformat and turn it back around. > > > > > > On Tue, Sep 9, 2014 at 11:21 AM, Leslie Rhorer > wrote: > >> >> Hello, >> >> I have an issue with my primary RAID array. I have 13T of data >> on the array, and I suffered a major array failure. I was able to rebuild >> the array, but some data was lost. Of course I have backups, so after >> running xfs_repair, I ran an rsync job to recover the lost data. Most of >> it was recovered, but there are several files that cannot be read, deleted, >> or overwritten. I have tried running xfs_repair several times, but any >> attempt to access these files continuously reports "cannot stat XXXXXXXX: >> Structure needs cleaning". I don't need to try to recover the data >> directly, as it does reside on the backup, but I need to clear the file >> structure so I can write the files back to the filesystem. How do I >> proceed? >> >> _______________________________________________ >> xfs mailing list >> xfs@oss.sgi.com >> http://oss.sgi.com/mailman/listinfo/xfs >> > > --089e0149c46e2367870502a41522 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
OK, let me retract just a tiny fraction of what I said ori= ginally; thinking about it further, there was _one_ time I was able to use = xfs_repair to successfully recover a "lightly bruised" XFS and re= turn it to service. But in that case, the fault was very minor and I always= check first with:

xfs_repair [-L] -n -v <filesystem&= gt;

and give the output a good looking over before= proceeding further.

If it won't run without z= eroing the log, you can take that as a sign that things are getting dire.. = I wouldn't bother to run xfs_repair "for real" if the trial o= utput looked even slightly non-trivial, in cases of underlying array failur= e or massive filesystem corruption, and I'd never run it without mounti= ng and scavenging first (unless I had a very recent full backup). Barring r= are cases, xfs_repair is bad juju.

Best,

Sean






On Tue, Sep 9, 2014 at 11:50 AM, Sean Caron <scaron@umich.= edu> wrote:
Hi Leslie,

If you have a full backup, I would STRONGLY= recommend just wiping your old filesystem and restoring your backups on to= p of a totally fresh XFS, rather than repairing the original filesystem and= then filling in the blanks with backups using a file-diff tool like rsync.=

You will probably hear various opinions here abou= t xfs_repair; my personal opinion is that xfs_repair is a program made avai= lable for the unwary to further scramble their data and make a hash of the = filesystem... In my first-hand experience managing ~7 PB of XFS storage and= growing, I have NEVER found xfs_repair (yes, even the "newest version= ") to ever do anything positive. It's basically a data scrambler.<= /div>

At this point, you will never achieve anything nea= r what I'd consider a production-grade, trustworthy data repository. An= y further runs of xfs_repair will either do nothing, or make the situation = worse. Fortunately you followed best practice and kept backups so you don&#= 39;t really need xfs_repair anyway, right?

Best,

Sean

P.S. No backups? Stil= l don't even think about running xfs_repair. ESPECIALLY don't think= about running xfs_repair. Try mounting ro; if that doesn't work, mount= ro with noreplaylog and scavenge what you can. Write off the rest. That= 9;s the cost of doing business without backups. Running xfs_repair (especia= lly as a first-line step) will only make it worse, and especially on big fi= lesystems, the run time can extend to weeks... Don't keep your users do= wn any longer than you need to, running a program that won't really hel= p you. Just scavenge it, reformat and turn it back around.





On Tue, Sep 9, 2014 at 11:21 AM, Leslie Rhorer <lrhorer@mygrande.net= > wrote:

Hello,

=C2=A0 =C2=A0 =C2=A0 =C2=A0 I have an issue with my primary RAID array.=C2= =A0 I have 13T of data on the array, and I suffered a major array failure.= =C2=A0 I was able to rebuild the array, but some data was lost.=C2=A0 Of co= urse I have backups, so after running xfs_repair, I ran an rsync job to rec= over the lost data.=C2=A0 Most of it was recovered, but there are several f= iles that cannot be read, deleted, or overwritten.=C2=A0 I have tried runni= ng xfs_repair several times, but any attempt to access these files continuo= usly reports "cannot stat XXXXXXXX: Structure needs cleaning".=C2= =A0 I don't need to try to recover the data directly, as it does reside= on the backup, but I need to clear the file structure so I can write the f= iles back to the filesystem.=C2=A0 How do I proceed?

_______________________________________________
xfs mailing list
xfs@oss.sgi.com http:= //oss.sgi.com/mailman/listinfo/xfs


--089e0149c46e2367870502a41522-- From eflorac@intellique.com Tue Sep 9 11:08:03 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 9F8EF7F3F for ; Tue, 9 Sep 2014 11:08:03 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2A793AC006 for ; Tue, 9 Sep 2014 09:08:03 -0700 (PDT) X-ASG-Debug-ID: 1410278881-04cb6c54ff8f4490001-NocioJ Received: from mail1.g1.pair.com (mail1.g1.pair.com [66.39.3.162]) by cuda.sgi.com with ESMTP id 9IlGkmcz2bS5bPsq (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 09 Sep 2014 09:08:01 -0700 (PDT) X-Barracuda-Envelope-From: eflorac@intellique.com X-Barracuda-Apparent-Source-IP: 66.39.3.162 Received: from localhost (localhost [127.0.0.1]) by mail1.g1.pair.com (Postfix) with SMTP id 04B4D2CA9B; Tue, 9 Sep 2014 12:08:01 -0400 (EDT) Received: from harpe.intellique.com (labo.djinux.com [82.225.196.72]) by mail1.g1.pair.com (Postfix) with ESMTPSA id BE6FF2C759; Tue, 9 Sep 2014 12:07:59 -0400 (EDT) Date: Tue, 9 Sep 2014 18:08:04 +0200 From: Emmanuel Florac To: Leslie Rhorer Cc: xfs@oss.sgi.com Subject: Re: Corrupted files Message-ID: <20140909180804.5cd65fe4@harpe.intellique.com> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: <540F1B01.3020700@mygrande.net> References: <540F1B01.3020700@mygrande.net> Organization: Intellique X-Mailer: Claws Mail 3.10.0 (GTK+ 2.24.20; i486-slackware-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail1.g1.pair.com[66.39.3.162] X-Barracuda-Start-Time: 1410278881 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9311 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Le Tue, 09 Sep 2014 10:21:37 -0500 Leslie Rhorer =C3=A9crivait: > I have tried running xfs_repair several times,=20 > but any attempt to access these files continuously reports "cannot > stat XXXXXXXX: Structure needs cleaning".=20 I won't agree with Sean here(1). Most of the time xfs_repair ends with the expected result; however many distros (particularly centOS) provide positively ancient versions. You'd better grab a recent version (3.1 or better). (1) in particular on the "run for weeks" part. I've never had xfs_repair take more than a couple of hours, even on badly damaged filesystems in the hundred of terabytes range. --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From david@fromorbit.com Tue Sep 9 17:04:17 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 12F6D7F51 for ; Tue, 9 Sep 2014 17:04:17 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id D91308F8033 for ; Tue, 9 Sep 2014 15:04:13 -0700 (PDT) X-ASG-Debug-ID: 1410300249-04bdf0109a8cb8d0001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id Ijq8iyavoCHuZLlp for ; Tue, 09 Sep 2014 15:04:10 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AmM/AC14D1R5LKYhPGdsb2JhbABPCoMNgSqCLK5mBppvhWkCAgEBAYEMFwUBAQEBODeEAwEBBAEnExwjBQsIAw4HAwklDwUlAwcaExuIHwe9SQEXGIVkiHVcB4RMBY8siQGERYwojHorL4JPAQEB Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail05.adl6.internode.on.net with ESMTP; 10 Sep 2014 07:34:01 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XRTW4-0006UE-1b; Wed, 10 Sep 2014 08:04:00 +1000 Date: Wed, 10 Sep 2014 08:04:00 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: xlog_cil_force_lsn doesn't always wait correctly Message-ID: <20140909220359.GG20518@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs: xlog_cil_force_lsn doesn't always wait correctly References: <1410226995-15714-1-git-send-email-david@fromorbit.com> <20140909134458.GA35182@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140909134458.GA35182@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1410300249 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9322 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 09, 2014 at 09:44:58AM -0400, Brian Foster wrote: > On Tue, Sep 09, 2014 at 11:43:15AM +1000, Dave Chinner wrote: > > From: Dave Chinner > > > > When running a tight mount/unmount loop on an older kernel, RedHat > > QE found that unmount would occasionally hang in > > xfs_buf_unpin_wait() on the superblock buffer. Tracing and other > > debug work by Eric Sandeen indicated that it was hanging on the > > writing of the superblock during unmount immediately after logging > > the superblock counters in a synchronous transaction. Further debug > > indicated that the synchronous transaction was not waiting for > > completion correctly, and we narrowed it down to > > xlog_cil_force_lsn() returning NULLCOMMITLSN and hence not pushing > > the transaction in the iclog buffer to disk correctly. > > > > While this unmount superblock write code is now very different in > > mainline kernels, the xlog_cil_force_lsn() code is identical, and it > > was bisected to the backport of commit f876e44 ("xfs: always do log > > forces via the workqueue"). This commit made the CIL push > > asynchronous for log forces and hence exposed a race condition that > > couldn't occur on a synchronous push. > > > > Essentially, the xlog_cil_force_lsn() relied implicitly on the fact > > that the sequence push would be complete by the time > > xlog_cil_push_now() returned, resulting in the context being pushed > > being in the committing list. When it was made asynchronous, it was > > recognised that there was a race condition in detecting whether an > > asynchronous push has started or not and code was added to handle > > it. > > > > Unfortunately, the fix was not quite right and left a race condition > > where it it would detect an empty CIL while a push was in progress > > before the context had been added to the committing list. This was > > incorrectly seen as a "nothing to do" condition and so would tell > > xfs_log_force_lsn() that there is nothing to wait for, and hence it > > would push the iclogbufs in memory. > > > > The fix is simple, but explaining the logic and the race condition > > is a lot more complex. The fix is to add the context to the > > committing list before we start emptying the CIL. This allows us to > > detect the difference between an empty "do nothing" push and a push > > that has not started by adding a discrete "emptying the CIL" state > > to avoid the transient, incorrect "empty" condition that the > > (unchanged) waiting code was seeing. > > > > Signed-off-by: Dave Chinner > > Tested-by: Eric Sandeen > > --- > > The pusher side queues the work, acquires xc_push_lock, walks the > committing list and then does this: > > if (sequence == cil->xc_current_sequence && > !list_empty(&cil->xc_cil)) { > spin_unlock(&cil->xc_push_lock); > goto restart; > } > > ... which is effectively peeking into the cil state to see if the push > actually needed to do anything. The purpose is to identify the case > where the push hasn't occurred and the previous committing list > traversal was insufficient. > > The "pushee" side drains the cil, updates the current sequence and adds > the ctx to the committing list. The time between the cil drain and > list_add() creates a window where, according to the logic above, the cil > push looks like it wasn't going to do anything from the pusher > perspective. The latter two bits occur under xc_push_lock (spinlock), so > perhaps that widens a window to make this slightly more reproducible. > > The pushee work is all done under xc_ctx_lock, so generally this is an > issue because the pusher doesn't acquire xc_ctx_lock, and thus the cil > drain and ctx update are not seen as atomic. I presume this is lockless > by design, so taking the lock is not a desired solution. > > Therefore, the order of changes to data structures that the pusher peeks > into is updated on the pushee side to add to the committing list, drain > the cil and update the current sequence number. > > For the pusher side, this means the committing list walk and logic above > (all under xc_push_lock) either sees the ctx on the list or not. If the > ctx is on the list, then we waited for it and there is no race. If the > ctx is not on the list, it is either populated and waiting to be added > to the list (e.g., we hold xc_push_lock) or empty and there's nothing to > do (regardless of whether the pusher side has run or not). > > That seems sound to me. It would be nice of we could somehow make this > explicitly more simple rather than dependent on complex ordering (e.g., > a push completion or something of that sort), but that's for another > time. One nit below... Yeah, it's complex and order dependent. I think I broke Eric trying to explain it to him when debugging it. ;) But the complexity is a side effect of the push lock being a critically hot lock and so anything we can do to avoid needing to hold it for longer or take it more often is worth the complexity. If you can think of a way that is simpler and doesn't introduce new contention points between pushers, forces and commits then I'm all ears ;) .... > Looks like out_skip could unlock xc_push_lock now. Probably can be, but I'll leave it as is right now. > Reviewed-by: Brian Foster Thanks! -Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Tue Sep 9 17:06:53 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 7C0BD7F51 for ; Tue, 9 Sep 2014 17:06:53 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 59ECB8F8050 for ; Tue, 9 Sep 2014 15:06:53 -0700 (PDT) X-ASG-Debug-ID: 1410300407-04bdf010978cbda0001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id T7o6TtrQuPCrZplm for ; Tue, 09 Sep 2014 15:06:48 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AjMxAFp5D1R5LKYhPGdsb2JhbAA/GoMNU1eCLIstozkGmRSBW4VpBAIBgQwXBQEBAQE4N4QEAQU6HCMQCAMOCgklDwUlAwcaE4hBDja9BAEXGIVkiGZrB4RMBZVxhwGZIisvAYJOAQEB Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail05.adl6.internode.on.net with ESMTP; 10 Sep 2014 07:36:46 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XRTYj-0006UW-F8; Wed, 10 Sep 2014 08:06:45 +1000 Date: Wed, 10 Sep 2014 08:06:45 +1000 From: Dave Chinner To: Leslie Rhorer Cc: xfs@oss.sgi.com Subject: Re: Corrupted files Message-ID: <20140909220645.GH20518@dastard> X-ASG-Orig-Subj: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540F1B01.3020700@mygrande.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1410300407 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9322 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 BSF_SC0_SA085 Custom Rule SA085 On Tue, Sep 09, 2014 at 10:21:37AM -0500, Leslie Rhorer wrote: > > Hello, > > I have an issue with my primary RAID array. I have 13T of data on > the array, and I suffered a major array failure. I was able to > rebuild the array, but some data was lost. Of course I have > backups, so after running xfs_repair, I ran an rsync job to recover > the lost data. Most of it was recovered, but there are several > files that cannot be read, deleted, or overwritten. I have tried > running xfs_repair several times, but any attempt to access these > files continuously reports "cannot stat XXXXXXXX: Structure needs > cleaning". I don't need to try to recover the data directly, as it > does reside on the backup, but I need to clear the file structure so > I can write the files back to the filesystem. How do I proceed? Fristly, more infomration is required, namely versions and actual error messages: http://xfs.org/index.php/XFS_FAQ#Q:_What_information_should_I_include_when_reporting_a_problem.3F dmesg, in particular, should tell use what the corruption being encountered is when stat fails. Cheers, Dave. -- Dave Chinner david@fromorbit.com From sandeen@sandeen.net Tue Sep 9 17:24:55 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 27EE17F52 for ; Tue, 9 Sep 2014 17:24:55 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id D8A858F8050 for ; Tue, 9 Sep 2014 15:24:54 -0700 (PDT) X-ASG-Debug-ID: 1410301492-04bdf010a18cf8b0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id Fl7GSJZW8Ud95wo3 for ; Tue, 09 Sep 2014 15:24:52 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 558A2637142F; Tue, 9 Sep 2014 17:24:52 -0500 (CDT) Message-ID: <540F7E37.7020500@sandeen.net> Date: Tue, 09 Sep 2014 17:24:55 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Sean Caron , Leslie Rhorer CC: "xfs@oss.sgi.com" Subject: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410301492 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9324 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/9/14 11:03 AM, Sean Caron wrote: >Barring rare cases, xfs_repair is bad juju. No, it's not. It is the appropriate tool to use for filesystem repair. But it is not the appropriate tool for recovery from mangled storage. I've actually been running a filesystem fuzzer over xfs images, randomly corrupting data and testing repair, 1000s of times over. It does remarkably well. If you scramble your raid, which means your block device is no longer an xfs filesystem, but is instead a random tangle of bits and pieces of other things, of course xfs_repair won't do well, but it's not the right tool for the job at that stage. -Eric From BATV+3dc40a38233d374cc22f+4034+infradead.org+hch@bombadil.srs.infradead.org Tue Sep 9 17:29:00 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 1F30F7F55 for ; Tue, 9 Sep 2014 17:29:00 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id E25C78F8049 for ; Tue, 9 Sep 2014 15:28:59 -0700 (PDT) X-ASG-Debug-ID: 1410301737-04bdf0109a8d0210001-NocioJ Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) by cuda.sgi.com with ESMTP id Ei01gzYMXHvkDek2 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 09 Sep 2014 15:28:57 -0700 (PDT) X-Barracuda-Envelope-From: BATV+3dc40a38233d374cc22f+4034+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XRTuD-000791-0g; Tue, 09 Sep 2014 22:28:57 +0000 Date: Tue, 9 Sep 2014 15:28:56 -0700 From: Christoph Hellwig To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/5] xfs_repair: clear bad flgs in process_dinode_int Message-ID: <20140909222856.GA27349@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 1/5] xfs_repair: clear bad flgs in process_dinode_int References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> <1410108065-18156-2-git-send-email-sandeen@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1410108065-18156-2-git-send-email-sandeen@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: bombadil.infradead.org[198.137.202.9] X-Barracuda-Start-Time: 1410301737 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9324 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sun, Sep 07, 2014 at 11:41:01AM -0500, Eric Sandeen wrote: > process_dinode_int() reports bad flags if > dino->di_flags & ~XFS_DIFLAG_ANY - i.e. if > any flags are set outside the known set. But > then instead of clearing them, it does > flags &= ~XFS_DIFLAG_ANY which keeps *only* > the bad flags. This leads to persistent, > unrepairable errors of the form: You know you can use up to 75 characters per line for your commit messages, don't you? :) Otherwise looks good, Reviewed-by: Christoph Hellwig From BATV+3dc40a38233d374cc22f+4034+infradead.org+hch@bombadil.srs.infradead.org Tue Sep 9 17:29:58 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A58487F57 for ; Tue, 9 Sep 2014 17:29:58 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 93F17304032 for ; Tue, 9 Sep 2014 15:29:55 -0700 (PDT) X-ASG-Debug-ID: 1410301794-04cbb05488be3850001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id 0vFOSuAmbNYwFtyM (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 09 Sep 2014 15:29:54 -0700 (PDT) X-Barracuda-Envelope-From: BATV+3dc40a38233d374cc22f+4034+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XRTv8-0007Qo-0U; Tue, 09 Sep 2014 22:29:54 +0000 Date: Tue, 9 Sep 2014 15:29:53 -0700 From: Christoph Hellwig To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/5] xfs_repair: preserve error state in process_shortform_attr Message-ID: <20140909222953.GB27349@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 2/5] xfs_repair: preserve error state in process_shortform_attr References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> <1410108065-18156-3-git-send-email-sandeen@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1410108065-18156-3-git-send-email-sandeen@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1410301794 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9324 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Sun, Sep 07, 2014 at 11:41:02AM -0500, Eric Sandeen wrote: > process_shortform_attr uses the "junkit" error to > track whether an error was found, but by assigning > it directly to the result of valuecheck, previous > errors are ignored, leading to unrepairable errors > of the form i.e. > > "entry has INCOMPLETE flag on in shortform attribute" > or > "entry contains illegal character in shortform attribute name" > > Signed-off-by: Eric Sandeen Looks good, Reviewed-by: Christoph Hellwig From sandeen@sandeen.net Tue Sep 9 17:33:28 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 576E57F57 for ; Tue, 9 Sep 2014 17:33:28 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 438638F8052 for ; Tue, 9 Sep 2014 15:33:28 -0700 (PDT) X-ASG-Debug-ID: 1410302007-04cbb05488be5980001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id oBNv9QD5nDH3PmIk for ; Tue, 09 Sep 2014 15:33:27 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 1ECE5637142F; Tue, 9 Sep 2014 17:33:27 -0500 (CDT) Message-ID: <540F803A.9060901@sandeen.net> Date: Tue, 09 Sep 2014 17:33:30 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Christoph Hellwig , Eric Sandeen CC: xfs@oss.sgi.com Subject: Re: [PATCH 1/5] xfs_repair: clear bad flgs in process_dinode_int References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> <1410108065-18156-2-git-send-email-sandeen@redhat.com> <20140909222856.GA27349@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 1/5] xfs_repair: clear bad flgs in process_dinode_int In-Reply-To: <20140909222856.GA27349@infradead.org> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410302007 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9324 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/9/14 5:28 PM, Christoph Hellwig wrote: > On Sun, Sep 07, 2014 at 11:41:01AM -0500, Eric Sandeen wrote: >> process_dinode_int() reports bad flags if >> dino->di_flags & ~XFS_DIFLAG_ANY - i.e. if >> any flags are set outside the known set. But >> then instead of clearing them, it does >> flags &= ~XFS_DIFLAG_ANY which keeps *only* >> the bad flags. This leads to persistent, >> unrepairable errors of the form: > > You know you can use up to 75 characters per line for your commit messages, > don't you? :) hah, it's not automated at all, I guess my visual perception of the window is shrinking. Dave, feel free to fix on commit if inclined :) -Eric From scaron@umich.edu Tue Sep 9 17:57:13 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C98AB7F57 for ; Tue, 9 Sep 2014 17:57:12 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7585EAC003 for ; Tue, 9 Sep 2014 15:57:09 -0700 (PDT) X-ASG-Debug-ID: 1410303427-04bdf0109a8d5470001-NocioJ Received: from mail-qc0-f182.google.com (mail-qc0-f182.google.com [209.85.216.182]) by cuda.sgi.com with ESMTP id IbT8KSxm9sOCjWX1 (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Tue, 09 Sep 2014 15:57:07 -0700 (PDT) X-Barracuda-Envelope-From: scaron@umich.edu X-Barracuda-Apparent-Source-IP: 209.85.216.182 Received: by mail-qc0-f182.google.com with SMTP id x13so5209900qcv.13 for ; Tue, 09 Sep 2014 15:57:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=v+R2e8KHgNCMwweTWaaJ8TbutjxBz7LS8Qsi7QRIqig=; b=dlzVBt2IISFU8+3XRpFrGwE182yqNXnsl4MpT2oON3fFU82o0Tkau9pDIWOwOSn20J Tg7bNIItqkQiLGb/NcxRLByCk++xbJmFOlS3w/4Nl0e8pTh9qsEwXJFNdMW89fDLZDNw SHmYjEpI8Cz7mp+6NQsXb6SEvNSk3t7oOkeTmqV6keMp0Lm+hdjGmU/75dmPCByjRhSS jB2Je5WDOAk++7TMDJ5KTqgS5Y7ke18+arQozOM4tXdGhhwznr2+eipbTfkeUsXGGUgk JQsg8sVKFIMwZuJz/AMTUjA5bBh7gBqKDGx4bwshsYeP5h4Lo8z5JlOpYBWeAjWfRqbV +Bug== X-Gm-Message-State: ALoCoQlx0TRbTJXlwRp9DQZcGoglqYLtCFU2qHQlP4VC47YaEx75AwpjqTJst0vyygOzu9vf5PVf MIME-Version: 1.0 X-Received: by 10.224.167.72 with SMTP id p8mr56271486qay.62.1410303426933; Tue, 09 Sep 2014 15:57:06 -0700 (PDT) Received: by 10.224.8.132 with HTTP; Tue, 9 Sep 2014 15:57:06 -0700 (PDT) In-Reply-To: <540F7E37.7020500@sandeen.net> References: <540F1B01.3020700@mygrande.net> <540F7E37.7020500@sandeen.net> Date: Tue, 9 Sep 2014 18:57:06 -0400 Message-ID: Subject: Re: Corrupted files From: Sean Caron X-ASG-Orig-Subj: Re: Corrupted files To: Eric Sandeen , Sean Caron Cc: Leslie Rhorer , "xfs@oss.sgi.com" Content-Type: multipart/alternative; boundary=089e0149c46ec9caa80502a9da0e X-Barracuda-Connect: mail-qc0-f182.google.com[209.85.216.182] X-Barracuda-Start-Time: 1410303427 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9325 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message --089e0149c46ec9caa80502a9da0e Content-Type: text/plain; charset=UTF-8 Hey, just sharing some hard-won (believe me) professional experience. I have seen xfs_repair take a bad situation and make it worse many times. I don't know that a filesystem fuzzer or any other simulation can ever provide true simulation of users absolutely pounding the tar out of a system. There seems to be a real disconnect between what developers are able to test and observe directly, and what happens in the production environment in a very high-throughput environment. Best, Sean On Tue, Sep 9, 2014 at 6:24 PM, Eric Sandeen wrote: > On 9/9/14 11:03 AM, Sean Caron wrote: > > Barring rare cases, xfs_repair is bad juju. >> > > No, it's not. It is the appropriate tool to use for filesystem repair. > > But it is not the appropriate tool for recovery from mangled storage. > > I've actually been running a filesystem fuzzer over xfs images, randomly > corrupting data and testing repair, 1000s of times over. It does > remarkably well. > > If you scramble your raid, which means your block device is no longer > an xfs filesystem, but is instead a random tangle of bits and pieces of > other things, of course xfs_repair won't do well, but it's not the right > tool for the job at that stage. > > -Eric > --089e0149c46ec9caa80502a9da0e Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hey, just sharing some hard-won (believe me) professional = experience. I have seen xfs_repair take a bad situation and make it worse m= any times. I don't know that a filesystem fuzzer or any other simulatio= n can ever provide true simulation of users absolutely pounding the tar out= of a system. There seems to be a real disconnect between what developers a= re able to test and observe directly, and what happens in the production en= vironment in a very high-throughput environment.

Be= st,

Sean


On Tue, Sep 9, 2014 at 6:2= 4 PM, Eric Sandeen <sandeen@sandeen.net> wrote:
On 9/9/14 11:03 AM, Sean Caron wro= te:

Barring rare cases, xfs_repair is bad juju.

No, it's not.=C2=A0 It is the appropriate tool to use for filesystem re= pair.

But it is not the appropriate tool for recovery from mangled storage.

I've actually been running a filesystem fuzzer over xfs images, randoml= y
corrupting data and testing repair, 1000s of times over.=C2=A0 It does
remarkably well.

If you scramble your raid, which means your block device is no longer
an xfs filesystem, but is instead a random tangle of bits and pieces of
other things, of course xfs_repair won't do well, but it's not the = right
tool for the job at that stage.

-Eric

--089e0149c46ec9caa80502a9da0e-- From david@fromorbit.com Tue Sep 9 18:48:22 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id DE2B47F61 for ; Tue, 9 Sep 2014 18:48:22 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id BDF17304048 for ; Tue, 9 Sep 2014 16:48:19 -0700 (PDT) X-ASG-Debug-ID: 1410306497-04bdf0109a8ddda0001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id duQh2DAxXFWfwFQS for ; Tue, 09 Sep 2014 16:48:17 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtYlAOWQD1R5LKYhPGdsb2JhbABZgw2BKoIsrmwGmm+FaQQCAYEGFwUBAQEBODeEBAEFJxMcIxAIAxgJJQ8FJQMHGhOIQb04ARcYhWSIbxEBUAeETAEEnHKMKIx6Ky+BD4FAAQEB Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail05.adl6.internode.on.net with ESMTP; 10 Sep 2014 09:18:16 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XRV8x-0006jG-VR; Wed, 10 Sep 2014 09:48:16 +1000 Date: Wed, 10 Sep 2014 09:48:15 +1000 From: Dave Chinner To: Eric Sandeen Cc: Christoph Hellwig , Eric Sandeen , xfs@oss.sgi.com Subject: Re: [PATCH 1/5] xfs_repair: clear bad flgs in process_dinode_int Message-ID: <20140909234815.GX30012@dastard> X-ASG-Orig-Subj: Re: [PATCH 1/5] xfs_repair: clear bad flgs in process_dinode_int References: <1410108065-18156-1-git-send-email-sandeen@redhat.com> <1410108065-18156-2-git-send-email-sandeen@redhat.com> <20140909222856.GA27349@infradead.org> <540F803A.9060901@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540F803A.9060901@sandeen.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1410306497 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9326 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 09, 2014 at 05:33:30PM -0500, Eric Sandeen wrote: > On 9/9/14 5:28 PM, Christoph Hellwig wrote: > >On Sun, Sep 07, 2014 at 11:41:01AM -0500, Eric Sandeen wrote: > >>process_dinode_int() reports bad flags if > >>dino->di_flags & ~XFS_DIFLAG_ANY - i.e. if > >>any flags are set outside the known set. But > >>then instead of clearing them, it does > >>flags &= ~XFS_DIFLAG_ANY which keeps *only* > >>the bad flags. This leads to persistent, > >>unrepairable errors of the form: > > > >You know you can use up to 75 characters per line for your commit messages, > >don't you? :) > > hah, it's not automated at all, I guess my visual perception > of the window is shrinking. Dave, feel free to fix on commit if > inclined :) I mostly do already - I tend to reflow commit messages to 68 characters (same width I use for email) when I see something like this. Cheers, Dave. -- Dave Chinner david@fromorbit.com From dgc@oss.sgi.com Tue Sep 9 19:00:04 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=NO_RELAYS autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: by oss.sgi.com (Postfix, from userid 10266) id 544657F66; Tue, 9 Sep 2014 19:00:04 -0500 (CDT) From: xfs@oss.sgi.com To: xfs@oss.sgi.com Subject: [XFS updates] XFS development tree branch, xfs-misc-fixes-for-3.18-1, created. v3.16-11807-gab6978c X-Git-Refname: refs/heads/xfs-misc-fixes-for-3.18-1 X-Git-Reftype: branch X-Git-Oldrev: 0000000000000000000000000000000000000000 X-Git-Newrev: ab6978c295b074eb2ba4b06fdf206c7ab4f293e5 Message-Id: <20140910000004.544657F66@oss.sgi.com> Date: Tue, 9 Sep 2014 19:00:03 -0500 (CDT) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "XFS development tree". The branch, xfs-misc-fixes-for-3.18-1 has been created at ab6978c295b074eb2ba4b06fdf206c7ab4f293e5 (commit) - Log ----------------------------------------------------------------- commit ab6978c295b074eb2ba4b06fdf206c7ab4f293e5 Author: Eric Sandeen Date: Tue Sep 9 11:59:12 2014 +1000 xfs: remove rbpp check from xfs_rtmodify_summary_int rbpp is always passed into xfs_rtmodify_summary and xfs_rtget_summary, so there is no need to test for it in xfs_rtmodify_summary_int. Signed-off-by: Eric Sandeen Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner commit afabfd30d05264ff493c24bce310b6a5350f099b Author: Eric Sandeen Date: Tue Sep 9 11:58:42 2014 +1000 xfs: combine xfs_rtmodify_summary and xfs_rtget_summary xfs_rtmodify_summary and xfs_rtget_summary are almost identical; fold them into xfs_rtmodify_summary_int(), with wrappers for each of the original calls. The _int function modifies if a delta is passed, and returns a summary pointer if *sum is passed. Signed-off-by: Eric Sandeen Reviewed-by: Brian Foster Signed-off-by: Dave Chinner commit b16ed7c114b8cca45fa87b675c431f43ff90c179 Author: Eric Sandeen Date: Tue Sep 9 11:58:07 2014 +1000 xfs: combine xfs_dir_canenter into xfs_dir_createname xfs_dir_canenter and xfs_dir_createname are almost identical. Fold the former into the latter, with a helpful wrapper for the former. If createname is called without an inode number, it now only checks for space, and does not actually add the entry. Signed-off-by: Eric Sandeen Reviewed-by: Brian Foster Signed-off-by: Dave Chinner commit 94f3cad555d66048906deade06a764f7ea2c6e4d Author: Eric Sandeen Date: Tue Sep 9 11:57:52 2014 +1000 xfs: check resblks before calling xfs_dir_canenter Move the resblks test out of the xfs_dir_canenter, and into the caller. This makes a little more sense on the face of it; xfs_dir_canenter immediately returns if resblks !=0; and given some of the comments preceding the calls: * Check for ability to enter directory entry, if no space reserved. even more so. It also facilitates the next patch. Signed-off-by: Eric Sandeen Reviewed-by: Christoph Hellwig Reviewed-by: Brian Foster Signed-off-by: Dave Chinner commit 970fd3f04d5949a4b5f6d0a5fea8e4b6797a5992 Author: Eric Sandeen Date: Tue Sep 9 11:57:29 2014 +1000 xfs: deduplicate xlog_do_recovery_pass() In xlog_do_recovery_pass(), there are 2 distinct cases: non-wrapped and wrapped log recovery. If we find a wrapped log, we recover around the end of the log, and then handle the rest of recovery exactly as in the non-wrapped case - using exactly the same (duplicated) code. Rather than having the same code in both cases, we can get the wrapped portion out of the way first if needed, and then recover the non-wrapped portion of the log. There should be no functional change here, just code reorganization & deduplication. The patch looks a bit bigger than it really is; the last hunk is whitespace changes (un-indenting). Tested with xfstests "check -g log" on a stock configuration. Signed-off-by: Eric Sandeen Reviewed-by: Brian Foster Signed-off-by: Dave Chinner commit 59f9c004320704179913fa7c57645017ccf1b5c3 Author: Eric Sandeen Date: Tue Sep 9 11:57:10 2014 +1000 xfs: lseek: the "whence" argument is called "whence" For some reason, the older commit: 965c8e5 lseek: the "whence" argument is called "whence" lseek: the "whence" argument is called "whence" But the kernel decided to call it "origin" instead. Fix most of the sites. left out xfs. So fix xfs. Signed-off-by: Eric Sandeen Reviewed-by: Brian Foster Reviewed-by: Jie Liu Signed-off-by: Dave Chinner commit 49c69591c80648c14ff87525e97ee6ebe3a343cb Author: Eric Sandeen Date: Tue Sep 9 11:56:48 2014 +1000 xfs: combine xfs_seek_hole & xfs_seek_data xfs_seek_hole & xfs_seek_data are remarkably similar; so much so that they can be combined, saving a fair bit of semi-complex code duplication. The following patch passes generic/285 and generic/286, which specifically test seek behavior. Signed-off-by: Eric Sandeen Reviewed-by: Brian Foster Reviewed-by: Jie Liu Signed-off-by: Dave Chinner commit 2e2271787419a12496bf5da5c3028a9c73c9697f Author: Brian Foster Date: Tue Sep 9 11:56:13 2014 +1000 xfs: export log_recovery_delay to delay mount time log recovery XFS log recovery has been discovered to have race conditions with buffers when I/O errors occur. External tools are available to simulate I/O errors to XFS, but this alone is not sufficient for testing log recovery. XFS unconditionally resets the inactive region of the log prior to log recovery to avoid confusion over processing any partially written log records that might have been written before an unclean shutdown. Therefore, unconditional write I/O failures at mount time are caught by the reset sequence rather than log recovery and hinder the ability to test the latter. The device-mapper dm-flakey module uses an up/down timer to define a cycle for when to fail I/Os. Create a pre log recovery delay tunable that can be used to coordinate XFS log recovery with I/O errors simulated by dm-flakey. This facilitates coordination in userspace that allows the reset of stale log blocks to succeed and writes due to log recovery to fail. For example, define a dm-flakey instance with an uptime long enough to allow log reset to succeed and a log recovery delay long enough to allow the dm-flakey uptime to expire. The 'log_recovery_delay' sysfs tunable is exported under /sys/fs/xfs/debug and is only enabled for kernels compiled in XFS debug mode. The value is exported in units of seconds and allows for a delay of up to 60 seconds. Note that this is for XFS debug and test instrumentation purposes only and should not be used by applications. No delay is enabled by default. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner commit 65b65735fede29b516fed1d8c2391e8bc373b805 Author: Brian Foster Date: Tue Sep 9 11:52:42 2014 +1000 xfs: add debug sysfs attribute set Create a top-level debug directory for global debug sysfs attributes. This directory is added and removed on XFS module initialization and removal respectively for DEBUG mode kernels only. It typically resides at /sys/fs/xfs/debug. It is located at the top level of the xfs sysfs hierarchy as attributes might define global behavior or behavior that must be configured before an xfs mount is available (e.g., log recovery behavior). Define the global debug kobject that represents the debug sysfs directory and add generic attribute show/store helpers to support future attributes. No debug attributes are exported as of yet. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner commit e1b05723ed834090caab56866adc05bce31c9bdd Author: Eric Sandeen Date: Tue Sep 9 11:47:24 2014 +1000 xfs: add a few more verifier tests These were exposed by fsfuzzer runs; without them we fail in various exciting and sometimes convoluted ways when we encounter disk corruption. Without the MAXLEVELS tests we tend to walk off the end of an array in a loop like this: for (i = 0; i < cur->bc_nlevels; i++) { if (cur->bc_bufs[i]) Without the dirblklog test we try to allocate more memory than we could possibly hope for and loop forever: xfs_dabuf_map() nfsb = mp->m_dir_geo->fsbcount; irecs = kmem_zalloc(sizeof(irec) * nfsb, KM_SLEEP... As for the logbsize check, that's the convoluted one. If logbsize is specified at mount time, it's sanitized in xfs_parseargs; in particular it makes sure that it's not > XLOG_MAX_RECORD_BSIZE. If not specified at mount time, it comes from the superblock via sb_logsunit; this is limited to 256k at mkfs time as well; it's copied into m_logbsize in xfs_finish_flags(). However, if for some reason the on-disk value is corrupt and too large, nothing catches it. It's a circuitous path, but that size eventually finds its way to places that make the kernel very unhappy, leading to oopses in xlog_pack_data() because we use the size as an index into iclog->ic_data, but the array is not necessarily that big. Anyway - bounds checking when we read from disk is a good thing! Signed-off-by: Eric Sandeen Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner commit 8018ec083c72443cc74fd2d08eb7c5dddc13af53 Author: Brian Foster Date: Tue Sep 9 11:44:46 2014 +1000 xfs: mark all internal workqueues as freezable Workqueues must be explicitly set as freezable to ensure they are frozen in the assocated part of the hibernation/suspend sequence. Freezing of workqueues and kernel threads is important to ensure that modifications are not made on-disk after the hibernation image has been created. Otherwise, the in-memory state can become inconsistent with what is on disk and eventually lead to filesystem corruption. We have reports of free space btree corruptions that occur immediately after restore from hibernate that suggest the xfs-eofblocks workqueue could be causing such problems if it races with hibernation. Mark all of the internal XFS workqueues as freezable to ensure nothing changes on-disk once the freezer infrastructure freezes kernel threads and creates the hibernation image. Signed-off-by: Brian Foster Reported-by: Carlos E. R. Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner ----------------------------------------------------------------------- hooks/post-receive -- XFS development tree From dgc@oss.sgi.com Tue Sep 9 19:00:21 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=NO_RELAYS autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: by oss.sgi.com (Postfix, from userid 10266) id BA0737F6B; Tue, 9 Sep 2014 19:00:21 -0500 (CDT) From: xfs@oss.sgi.com To: xfs@oss.sgi.com Subject: [XFS updates] XFS development tree branch, for-next, updated. xfs-for-linus-3.17-rc3-12-ga4241ae X-Git-Refname: refs/heads/for-next X-Git-Reftype: branch X-Git-Oldrev: 41b9d7263ea1e270019c5d04fa0ab15db50b9725 X-Git-Newrev: a4241aebe924136d6838fd516da6daa727fcd728 Message-Id: <20140910000021.BA0737F6B@oss.sgi.com> Date: Tue, 9 Sep 2014 19:00:21 -0500 (CDT) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "XFS development tree". The branch, for-next has been updated a4241ae Merge branch 'xfs-misc-fixes-for-3.18-1' into for-next ab6978c xfs: remove rbpp check from xfs_rtmodify_summary_int afabfd3 xfs: combine xfs_rtmodify_summary and xfs_rtget_summary b16ed7c xfs: combine xfs_dir_canenter into xfs_dir_createname 94f3cad xfs: check resblks before calling xfs_dir_canenter 970fd3f xfs: deduplicate xlog_do_recovery_pass() 59f9c00 xfs: lseek: the "whence" argument is called "whence" 49c6959 xfs: combine xfs_seek_hole & xfs_seek_data 2e22717 xfs: export log_recovery_delay to delay mount time log recovery 65b6573 xfs: add debug sysfs attribute set e1b0572 xfs: add a few more verifier tests 8018ec0 xfs: mark all internal workqueues as freezable from 41b9d7263ea1e270019c5d04fa0ab15db50b9725 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a4241aebe924136d6838fd516da6daa727fcd728 Merge: 41b9d72 ab6978c Author: Dave Chinner Date: Tue Sep 9 13:25:31 2014 +1000 Merge branch 'xfs-misc-fixes-for-3.18-1' into for-next ----------------------------------------------------------------------- Summary of changes: fs/xfs/libxfs/xfs_alloc.c | 4 + fs/xfs/libxfs/xfs_dir2.c | 67 +++------------- fs/xfs/libxfs/xfs_dir2.h | 2 +- fs/xfs/libxfs/xfs_ialloc.c | 2 + fs/xfs/libxfs/xfs_rtbitmap.c | 49 ++++++++---- fs/xfs/libxfs/xfs_sb.c | 2 + fs/xfs/xfs_buf.c | 2 +- fs/xfs/xfs_file.c | 178 +++++++++++++------------------------------ fs/xfs/xfs_globals.c | 4 + fs/xfs/xfs_inode.c | 24 +++--- fs/xfs/xfs_log_recover.c | 93 ++++++++++------------ fs/xfs/xfs_mru_cache.c | 3 +- fs/xfs/xfs_rtalloc.c | 55 +------------ fs/xfs/xfs_rtalloc.h | 4 + fs/xfs/xfs_super.c | 38 ++++++--- fs/xfs/xfs_symlink.c | 8 +- fs/xfs/xfs_sysctl.h | 5 ++ fs/xfs/xfs_sysfs.c | 74 ++++++++++++++++++ fs/xfs/xfs_sysfs.h | 1 + 19 files changed, 290 insertions(+), 325 deletions(-) hooks/post-receive -- XFS development tree From lrhorer@mygrande.net Tue Sep 9 19:48:51 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 8B3467F53 for ; Tue, 9 Sep 2014 19:48:51 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 79B248F804B for ; Tue, 9 Sep 2014 17:48:48 -0700 (PDT) X-ASG-Debug-ID: 1410310123-04cbb05485c0cc70001-NocioJ Received: from mail04.lsn.net (mail04.lsn.net [66.90.130.138]) by cuda.sgi.com with ESMTP id Nc165FHZIFheKILV for ; Tue, 09 Sep 2014 17:48:44 -0700 (PDT) X-Barracuda-Envelope-From: lrhorer@mygrande.net X-Barracuda-Apparent-Source-IP: 66.90.130.138 Received: from [192.168.1.121] (24-155-170-173.dyn.grandenetworks.net [24.155.170.173]) (authenticated bits=0) by mail04.lsn.net (8.14.4/8.13.6) with ESMTP id s8A0mfoK005347 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Tue, 9 Sep 2014 19:48:42 -0500 X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.98.4 at av02.lsn.net Message-ID: <540F9FE9.7070500@mygrande.net> Date: Tue, 09 Sep 2014 19:48:41 -0500 From: Leslie Rhorer User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: Eric Sandeen , Sean Caron CC: "xfs@oss.sgi.com" Subject: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> <540F7E37.7020500@sandeen.net> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: <540F7E37.7020500@sandeen.net> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail04.lsn.net[66.90.130.138] X-Barracuda-Start-Time: 1410310124 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9327 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/9/2014 5:24 PM, Eric Sandeen wrote: > On 9/9/14 11:03 AM, Sean Caron wrote: > >> Barring rare cases, xfs_repair is bad juju. > > No, it's not. It is the appropriate tool to use for filesystem repair. > > But it is not the appropriate tool for recovery from mangled storage. It's not all that mangled. Out of over 52,000 files on the backup server array, only 5758 were missing from the primary array, and most of those were lost by the corruption of just a couple of directories, where every file in the directory was lost with the directory itself. Several directories and a scattering of individual files were deleted with intent prior to the failure but not yet purged from the backup. Most were small files - only 29 were larger than 1G. All of those 5758 were easily recovered. The only ones remaining at issue are 3 files which cannot be read, written or deleted. The rest have been read and checksums sucessfully computed and compared. With only 50K files in question, I am confidant any checksum collisions are of insignificant probability. Someone is going to have to do a lot of talking to convince me rsync can read two copies of what should be the same data and come up with the same checksum value for both, but other applications would be able to successfully read one of the files and not the other. I really don't think Draconian measures are required. Even if it turns out they are, the existence of the backup allows for a good deal of fiddling with the main filesystem before one is compelled to give up and start fresh. This especially since a small amount of the data on the main array had not yet been backed up to the secondary array. These e-mails, for example. The rsync job that backs up the main array runs every morning at 04:00, so files created that day were not backed up, and for safety I have changed the backup array file system to read-only, so nothing created since is backed up. > I've actually been running a filesystem fuzzer over xfs images, randomly > corrupting data and testing repair, 1000s of times over. It does > remarkably well. > > If you scramble your raid, which means your block device is no longer > an xfs filesystem, but is instead a random tangle of bits and pieces of > other things, of course xfs_repair won't do well, but it's not the right > tool for the job at that stage. This is nowhere near that stage. A few sectors here and there were lost because 3 drives were kicked from the array while write operations were underway. I had to force re-assemble the array, which lost some data. The vast majority of the data is clearly intact, including most of the file system structures. Far less than 1% of the data was lost or corrupted. From roger@filmlight.ltd.uk Tue Sep 9 20:00:26 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 39F4A7F4E for ; Tue, 9 Sep 2014 20:00:26 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id AE4D4AC003 for ; Tue, 9 Sep 2014 18:00:22 -0700 (PDT) X-ASG-Debug-ID: 1410310819-04cbb05488c122f0001-NocioJ Received: from b.mx.filmlight.ltd.uk (b.mx.filmlight.ltd.uk [77.107.81.251]) by cuda.sgi.com with SMTP id DmsLs4GQghQDK0CG for ; Tue, 09 Sep 2014 18:00:20 -0700 (PDT) X-Barracuda-Envelope-From: roger@filmlight.ltd.uk X-Barracuda-Apparent-Source-IP: 77.107.81.251 Received: (dqd 16199 invoked from network); 10 Sep 2014 01:00:19 -0000 Received: from cpc2-stev6-2-0-cust318.9-2.cable.virginm.net (HELO ?192.168.0.247?) (roger@213.107.89.63) by b.mx.filmlight.ltd.uk with SMTP; 10 Sep 2014 01:00:19 -0000 Content-Type: multipart/alternative; boundary="Apple-Mail=_883806B7-225F-4F7A-8C28-339A49FE81DA" Mime-Version: 1.0 (Mac OS X Mail 6.6 \(1510\)) Subject: Re: Corrupted files From: Roger Willcocks X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: Date: Wed, 10 Sep 2014 02:00:18 +0100 Cc: Roger Willcocks , Eric Sandeen , Leslie Rhorer , "xfs@oss.sgi.com" Message-Id: <62B15E94-1944-457F-B298-89EDEE3EC70D@filmlight.ltd.uk> References: <540F1B01.3020700@mygrande.net> <540F7E37.7020500@sandeen.net> To: Sean Caron X-Mailer: Apple Mail (2.1510) X-Barracuda-Connect: b.mx.filmlight.ltd.uk[77.107.81.251] X-Barracuda-Start-Time: 1410310820 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_SA210e, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9327 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 BSF_SC5_SA210e Custom Rule SA210e --Apple-Mail=_883806B7-225F-4F7A-8C28-339A49FE81DA Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii I normally watch quietly from the sidelines but I think it's important = to get some balance here; our customers between them run many hundreds = of multi-terabyte arrays and when something goes badly awry it generally = falls to me to sort it out. In my experience xfs_repair does exactly = what it says on the tin. I can recall only a couple of instances where we elected to reformat and = reload from backups and they were both due to human error: somebody = deleted the wrong raid unit when doing routine maintenance, and then = tried to fix it up hemselves. In theory of course xfs_repair shouldn't be needed if the write barriers = work properly (it's a journalled filesystem), but low-level corruption = does creep in due to power failures / kernel crashes and it's this which = xfs_repair is intended to address; not massive data corruption due to = failed hardware or careless users. -- Roger On 9 Sep 2014, at 23:57, Sean Caron wrote: > Hey, just sharing some hard-won (believe me) professional experience. = I have seen xfs_repair take a bad situation and make it worse many = times. I don't know that a filesystem fuzzer or any other simulation can = ever provide true simulation of users absolutely pounding the tar out of = a system. There seems to be a real disconnect between what developers = are able to test and observe directly, and what happens in the = production environment in a very high-throughput environment. >=20 > Best, >=20 > Sean >=20 >=20 > On Tue, Sep 9, 2014 at 6:24 PM, Eric Sandeen = wrote: > On 9/9/14 11:03 AM, Sean Caron wrote: >=20 > Barring rare cases, xfs_repair is bad juju. >=20 > No, it's not. It is the appropriate tool to use for filesystem = repair. >=20 > But it is not the appropriate tool for recovery from mangled storage. >=20 > I've actually been running a filesystem fuzzer over xfs images, = randomly > corrupting data and testing repair, 1000s of times over. It does > remarkably well. >=20 > If you scramble your raid, which means your block device is no longer > an xfs filesystem, but is instead a random tangle of bits and pieces = of > other things, of course xfs_repair won't do well, but it's not the = right > tool for the job at that stage. >=20 > -Eric >=20 > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs --Apple-Mail=_883806B7-225F-4F7A-8C28-339A49FE81DA Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=us-ascii scaron@umich.edu> = wrote:

Hey, just sharing some hard-won (believe = me) professional experience. I have seen xfs_repair take a bad situation = and make it worse many times. I don't know that a filesystem fuzzer or = any other simulation can ever provide true simulation of users = absolutely pounding the tar out of a system. There seems to be a real = disconnect between what developers are able to test and observe = directly, and what happens in the production environment in a very = high-throughput = environment.

Best,

Sean


On Tue, Sep 9, 2014 at 6:24 PM, Eric Sandeen <sandeen@sandeen.net> = wrote:
On = 9/9/14 11:03 AM, Sean Caron wrote:

Barring rare cases, xfs_repair is bad juju.

No, it's not.  It is the appropriate tool to use for filesystem = repair.

But it is not the appropriate tool for recovery from mangled = storage.

I've actually been running a filesystem fuzzer over xfs images, = randomly
corrupting data and testing repair, 1000s of times over.  It = does
remarkably well.

If you scramble your raid, which means your block device is no = longer
an xfs filesystem, but is instead a random tangle of bits and pieces = of
other things, of course xfs_repair won't do well, but it's not the = right
tool for the job at that stage.

-Eric

_______________________________________________
xfs mailing = list
xfs@oss.sgi.com
http://oss.sgi.com/= mailman/listinfo/xfs

= --Apple-Mail=_883806B7-225F-4F7A-8C28-339A49FE81DA-- From roger@filmlight.ltd.uk Tue Sep 9 20:10:56 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 6F1A07F4E for ; Tue, 9 Sep 2014 20:10:56 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 5D9DC8F804B for ; Tue, 9 Sep 2014 18:10:53 -0700 (PDT) X-ASG-Debug-ID: 1410311448-04cbb05486c17af0001-NocioJ Received: from b.mx.filmlight.ltd.uk (b.mx.filmlight.ltd.uk [77.107.81.251]) by cuda.sgi.com with SMTP id OCkD43DeugKAzfdg for ; Tue, 09 Sep 2014 18:10:48 -0700 (PDT) X-Barracuda-Envelope-From: roger@filmlight.ltd.uk X-Barracuda-Apparent-Source-IP: 77.107.81.251 Received: (dqd 11134 invoked from network); 10 Sep 2014 01:10:48 -0000 Received: from cpc2-stev6-2-0-cust318.9-2.cable.virginm.net (HELO ?192.168.0.247?) (roger@213.107.89.63) by b.mx.filmlight.ltd.uk with SMTP; 10 Sep 2014 01:10:48 -0000 Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 6.6 \(1510\)) Subject: Re: Corrupted files From: Roger Willcocks X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: <540F9FE9.7070500@mygrande.net> Date: Wed, 10 Sep 2014 02:10:47 +0100 Cc: Roger Willcocks , Eric Sandeen , Sean Caron , "xfs@oss.sgi.com" Content-Transfer-Encoding: quoted-printable Message-Id: <3E40936B-A1F2-424D-B0B3-54B6C7B50B13@filmlight.ltd.uk> References: <540F1B01.3020700@mygrande.net> <540F7E37.7020500@sandeen.net> <540F9FE9.7070500@mygrande.net> To: Leslie Rhorer X-Mailer: Apple Mail (2.1510) X-Barracuda-Connect: b.mx.filmlight.ltd.uk[77.107.81.251] X-Barracuda-Start-Time: 1410311448 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9327 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 BSF_SC0_SA085 Custom Rule SA085 On 10 Sep 2014, at 01:48, Leslie Rhorer wrote: > The only ones remaining at issue are 3 files which cannot be read, = written or deleted. The most straightforward fix would be to note down the inode numbers of = the three fies and then use xfs_db to clear the inodes; then run = xfs_repair again. See: = http://xfs.org/index.php/XFS_FAQ#Q:_How_to_get_around_a_bad_inode_repair_i= s_unable_to_clean_up but before that try running the latest (3.2.1 I think) xfs_repair. -- Roger From lrhorer@mygrande.net Tue Sep 9 20:13:48 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 8D9277F50 for ; Tue, 9 Sep 2014 20:13:48 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 798C28F8054 for ; Tue, 9 Sep 2014 18:13:48 -0700 (PDT) X-ASG-Debug-ID: 1410311626-04cb6c5500941df0001-NocioJ Received: from mail02.lsn.net (mail02.lsn.net [66.90.130.128]) by cuda.sgi.com with ESMTP id SvcGQwoZg67WfuBk for ; Tue, 09 Sep 2014 18:13:46 -0700 (PDT) X-Barracuda-Envelope-From: lrhorer@mygrande.net X-Barracuda-Apparent-Source-IP: 66.90.130.128 Received: from [192.168.1.121] (24-155-170-173.dyn.grandenetworks.net [24.155.170.173]) (authenticated bits=0) by mail02.lsn.net (8.14.4/8.13.6) with ESMTP id s8A1CcZU030778 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Tue, 9 Sep 2014 20:12:39 -0500 X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.98.4 at av01.lsn.net Message-ID: <540FA586.9090308@mygrande.net> Date: Tue, 09 Sep 2014 20:12:38 -0500 From: Leslie Rhorer User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: Dave Chinner CC: xfs@oss.sgi.com Subject: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: <20140909220645.GH20518@dastard> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail02.lsn.net[66.90.130.128] X-Barracuda-Start-Time: 1410311626 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9327 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 BSF_SC0_SA085 Custom Rule SA085 On 9/9/2014 5:06 PM, Dave Chinner wrote: > Fristly, more infomration is required, namely versions and actual > error messages: Indubitably: RAID-Server:/# xfs_repair -V xfs_repair version 3.1.7 RAID-Server:/# uname -r 3.2.0-4-amd64 4.0 GHz FX-8350 eight core processor RAID-Server:/# cat /proc/meminfo /proc/mounts /proc/partitions MemTotal: 8099916 kB MemFree: 5786420 kB Buffers: 112684 kB Cached: 457020 kB SwapCached: 0 kB Active: 521800 kB Inactive: 457268 kB Active(anon): 276648 kB Inactive(anon): 140180 kB Active(file): 245152 kB Inactive(file): 317088 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 12623740 kB SwapFree: 12623740 kB Dirty: 20 kB Writeback: 0 kB AnonPages: 409488 kB Mapped: 47576 kB Shmem: 7464 kB Slab: 197100 kB SReclaimable: 112644 kB SUnreclaim: 84456 kB KernelStack: 2560 kB PageTables: 8468 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 16673696 kB Committed_AS: 1010172 kB VmallocTotal: 34359738367 kB VmallocUsed: 339140 kB VmallocChunk: 34359395308 kB HardwareCorrupted: 0 kB AnonHugePages: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 65532 kB DirectMap2M: 5120000 kB DirectMap1G: 3145728 kB rootfs / rootfs rw 0 0 sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0 proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0 udev /dev devtmpfs rw,relatime,size=10240k,nr_inodes=1002653,mode=755 0 0 devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0 tmpfs /run tmpfs rw,nosuid,noexec,relatime,size=809992k,mode=755 0 0 /dev/disk/by-uuid/fa5c404a-bfcb-43de-87ed-e671fda1ba99 / ext4 rw,relatime,errors=remount-ro,user_xattr,barrier=1,data=ordered 0 0 tmpfs /run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k 0 0 tmpfs /run/shm tmpfs rw,nosuid,nodev,noexec,relatime,size=4144720k 0 0 /dev/md1 /boot ext2 rw,relatime,errors=continue 0 0 rpc_pipefs /var/lib/nfs/rpc_pipefs rpc_pipefs rw,relatime 0 0 Backup:/Backup /Backup nfs rw,relatime,vers=3,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.1.51,mountvers=3,mountport=39597,mountproto=tcp,local_lock=none,addr=192.168.1.51 0 0 Backup:/var/www /var/www/backup nfs rw,relatime,vers=3,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.1.51,mountvers=3,mountport=39597,mountproto=tcp,local_lock=none,addr=192.168.1.51 0 0 /dev/md0 /RAID xfs rw,relatime,attr2,delaylog,sunit=2048,swidth=12288,noquota 0 0 major minor #blocks name 8 0 125034840 sda 8 1 96256 sda1 8 2 112305152 sda2 8 3 12632064 sda3 8 16 125034840 sdb 8 17 96256 sdb1 8 18 112305152 sdb2 8 19 12632064 sdb3 8 48 3907018584 sdd 8 32 3907018584 sdc 8 64 1465138584 sde 8 80 1465138584 sdf 8 96 1465138584 sdg 8 112 3907018584 sdh 8 128 3907018584 sdi 8 144 3907018584 sdj 8 160 3907018584 sdk 9 1 96192 md1 9 2 112239488 md2 9 3 12623744 md3 9 0 23441319936 md0 9 10 4395021312 md10 RAID-Server:/# cat /proc/mdstat Personalities : [raid6] [raid5] [raid4] [raid1] [raid0] md10 : active raid0 sdf[0] sde[2] sdg[1] 4395021312 blocks super 1.2 512k chunks md0 : active raid6 md10[12] sdc[13] sdk[10] sdj[11] sdi[15] sdh[8] sdd[9] 23441319936 blocks super 1.2 level 6, 1024k chunk, algorithm 2 [8/7] [UUU_UUUU] bitmap: 29/30 pages [116KB], 65536KB chunk md3 : active (auto-read-only) raid1 sda3[0] sdb3[1] 12623744 blocks super 1.2 [3/2] [UU_] bitmap: 1/1 pages [4KB], 65536KB chunk md2 : active raid1 sda2[0] sdb2[1] 112239488 blocks super 1.2 [3/2] [UU_] bitmap: 1/1 pages [4KB], 65536KB chunk md1 : active raid1 sda1[0] sdb1[1] 96192 blocks [3/2] [UU_] bitmap: 1/1 pages [4KB], 65536KB chunk unused devices: Six of the drives are 4T spindles (a mixture of makes and models). The three drives comprising MD10 are WD 1.5T green drives. These are in place to take over the function of one of the kicked 4T drives. Md1, 2, and 3 are not data drives and are not suffering any issue. I'm not sure what is meant by "write cache status" in this context. The machine has been rebooted more than once during recovery and the FS has been umounted and xfs_repair run several times. I don't know for what the acronym BBWC stands. RAID-Server:/# xfs_info /dev/md0 meta-data=/dev/md0 isize=256 agcount=43, agsize=137356288 blks = sectsz=512 attr=2 data = bsize=4096 blocks=5860329984, imaxpct=5 = sunit=256 swidth=1536 blks naming =version 2 bsize=4096 ascii-ci=0 log =internal bsize=4096 blocks=521728, version=2 = sectsz=512 sunit=8 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 The system performs just fine, other than the aforementioned, with loads in excess of 3Gbps. That is internal only. The LAN link is ony 1Gbps, so no external request exceeds about 950Mbps. > http://xfs.org/index.php/XFS_FAQ#Q:_What_information_should_I_include_when_reporting_a_problem.3F > > dmesg, in particular, should tell use what the corruption being > encountered is when stat fails. RAID-Server:/# ls "/RAID/DVD/Big Sleep, The (1945)/VIDEO_TS/VTS_01_1.VOB" ls: cannot access /RAID/DVD/Big Sleep, The (1945)/VIDEO_TS/VTS_01_1.VOB: Structure needs cleaning RAID-Server:/# dmesg | tail -n 30 ... [192173.363981] XFS (md0): corrupt dinode 41006, extent total = 1, nblocks = 0. [192173.363988] ffff8802338b8e00: 49 4e 81 b6 02 02 00 00 00 00 03 e8 00 00 03 e8 IN.............. [192173.363996] XFS (md0): Internal error xfs_iformat(1) at line 319 of file /build/linux-eKuxrT/linux-3.2.60/fs/xfs/xfs_inode.c. Caller 0xffffffffa0509318 [192173.363999] [192173.364062] Pid: 10813, comm: ls Not tainted 3.2.0-4-amd64 #1 Debian 3.2.60-1+deb7u3 [192173.364065] Call Trace: [192173.364097] [] ? xfs_corruption_error+0x54/0x6f [xfs] [192173.364134] [] ? xfs_iread+0x9f/0x177 [xfs] [192173.364170] [] ? xfs_iformat+0xe3/0x462 [xfs] [192173.364204] [] ? xfs_iread+0x9f/0x177 [xfs] [192173.364240] [] ? xfs_iread+0x9f/0x177 [xfs] [192173.364268] [] ? xfs_iget+0x37c/0x56c [xfs] [192173.364300] [] ? xfs_lookup+0xa4/0xd3 [xfs] [192173.364328] [] ? xfs_vn_lookup+0x3f/0x7e [xfs] [192173.364344] [] ? d_alloc_and_lookup+0x3a/0x60 [192173.364357] [] ? walk_component+0x219/0x406 [192173.364370] [] ? path_lookupat+0x7c/0x2bd [192173.364383] [] ? should_resched+0x5/0x23 [192173.364396] [] ? _cond_resched+0x7/0x1c [192173.364408] [] ? do_path_lookup+0x1c/0x87 [192173.364420] [] ? user_path_at_empty+0x47/0x7b [192173.364434] [] ? do_page_fault+0x30a/0x345 [192173.364448] [] ? mmap_region+0x353/0x44a [192173.364460] [] ? vfs_fstatat+0x32/0x60 [192173.364471] [] ? sys_newstat+0x12/0x2b [192173.364483] [] ? page_fault+0x25/0x30 [192173.364495] [] ? system_call_fastpath+0x16/0x1b [192173.364503] XFS (md0): Corruption detected. Unmount and run xfs_repair That last line, by the way, is why I ran umount and xfs_repair. From lrhorer@mygrande.net Tue Sep 9 20:24:08 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D350B7F56 for ; Tue, 9 Sep 2014 20:24:07 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6DCB4AC004 for ; Tue, 9 Sep 2014 18:24:07 -0700 (PDT) X-ASG-Debug-ID: 1410312245-04bdf010a08ecf40001-NocioJ Received: from mail01.lsn.net (mail01.lsn.net [66.90.130.120]) by cuda.sgi.com with ESMTP id LJHsYiVMFOrgW0Xr for ; Tue, 09 Sep 2014 18:24:06 -0700 (PDT) X-Barracuda-Envelope-From: lrhorer@mygrande.net X-Barracuda-Apparent-Source-IP: 66.90.130.120 Received: from [192.168.1.121] (24-155-170-173.dyn.grandenetworks.net [24.155.170.173]) (authenticated bits=0) by mail01.lsn.net (8.14.4/8.13.6) with ESMTP id s8A1NpkQ014855 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Tue, 9 Sep 2014 20:23:52 -0500 X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.98.4 at av01.lsn.net Message-ID: <540FA827.3090308@mygrande.net> Date: Tue, 09 Sep 2014 20:23:51 -0500 From: Leslie Rhorer User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: Roger Willcocks , Sean Caron CC: Eric Sandeen , "xfs@oss.sgi.com" Subject: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> <540F7E37.7020500@sandeen.net> <62B15E94-1944-457F-B298-89EDEE3EC70D@filmlight.ltd.uk> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: <62B15E94-1944-457F-B298-89EDEE3EC70D@filmlight.ltd.uk> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail01.lsn.net[66.90.130.120] X-Barracuda-Start-Time: 1410312245 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_SA210e X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9328 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC5_SA210e Custom Rule SA210e On 9/9/2014 8:00 PM, Roger Willcocks wrote: > I normally watch quietly from the sidelines but I think it's important > to get some balance here That is almost always wise advice. Shooting from the hip often has regrettable consequences, yet being too cautious can have its down side, too. In this case, things are working very well at the moment, and the apparent issues are reasonably small, so there is no need for panic. > our customers between them run many hundreds > of multi-terabyte arrays and when something goes badly awry it generally > falls to me to sort it out. In my experience xfs_repair does exactly > what it says on the tin. I couldn't say. This is only the second time I have ever had an array drop, and the first time it was completely unrecoverable. Less than 5 minutes after I had started a RAID upgrade from RAID5 to RAID6, there was a protracted power outage. I shut down the system cleanly and after the outage restarted the reshape. The recovery had only been running a few minutes when the system suffered a kernel panic - I never did find out why. Every single structure on the array larger than the stripe size (16K, I think) was garbage. > I can recall only a couple of instances where we elected to reformat and > reload from backups and they were both due to human error: somebody > deleted the wrong raid unit when doing routine maintenance, and then > tried to fix it up hemselves. > > In theory of course xfs_repair shouldn't be needed if the write barriers > work properly (it's a journalled filesystem), but low-level corruption > does creep in due to power failures / kernel crashes and it's this which > xfs_repair is intended to address; not massive data corruption due to > failed hardware or careless users. Oh, yeah, like losing 3 out of 8 drives in the array after a drive controller replacement... From scaron@umich.edu Tue Sep 9 20:25:45 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id F2ED57F59 for ; Tue, 9 Sep 2014 20:25:44 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id E147E304053 for ; Tue, 9 Sep 2014 18:25:41 -0700 (PDT) X-ASG-Debug-ID: 1410312338-04cbb05485c18f10001-NocioJ Received: from mail-qc0-f171.google.com (mail-qc0-f171.google.com [209.85.216.171]) by cuda.sgi.com with ESMTP id xH8AIGh47xAFdsGp (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Tue, 09 Sep 2014 18:25:39 -0700 (PDT) X-Barracuda-Envelope-From: scaron@umich.edu X-Barracuda-Apparent-Source-IP: 209.85.216.171 Received: by mail-qc0-f171.google.com with SMTP id x3so18147387qcv.2 for ; Tue, 09 Sep 2014 18:25:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=+4QsMROfKIxAq7byZtgcGatjSdpPMHzcA9ihRgM4xQU=; b=Gp456MqoNNaUKNj550h/L/R7C5DfvntyeQRZ50JPlu85ETPasn1uAu50yKqVdqdt2F WaloYkwZ44CAeSmbe57WXpCIeXN8W8NzMQ2UuaLaWmuiR1hSjIgDcqlZUUP+xzL/9ysS 9Vu8jmUgLP/1cKpdvW+P8hyCYxbl2G0dp8tqAtBIznwMhpwIk7fK0Rt1cv+1WIDUvCAd 1Nf88hL9p/DXYkSDYhpx1n59ejemaiC9hTQEdbYyPUweUNyK4zb10mj0L6XCOWNTHzIW I+XmQBkltdckuhKIk1CsH3xpYkXY2zFHQGfxwUDuZIIiKJrQp8cz57YFM09pAfflBTXH nHUw== X-Gm-Message-State: ALoCoQlZ8Qpv8S/AvAprk8DNr2ztzakbmqAsegTPoc8+OjEGqZpBfrN55Ujlm6nyai+vF0g1QBtM MIME-Version: 1.0 X-Received: by 10.224.13.141 with SMTP id c13mr18967048qaa.85.1410312337157; Tue, 09 Sep 2014 18:25:37 -0700 (PDT) Received: by 10.224.8.132 with HTTP; Tue, 9 Sep 2014 18:25:37 -0700 (PDT) In-Reply-To: <540FA586.9090308@mygrande.net> References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> Date: Tue, 9 Sep 2014 21:25:37 -0400 Message-ID: Subject: Re: Corrupted files From: Sean Caron X-ASG-Orig-Subj: Re: Corrupted files To: Leslie Rhorer , Sean Caron Cc: Dave Chinner , "xfs@oss.sgi.com" Content-Type: multipart/alternative; boundary=047d7bdca458e10c0d0502abed22 X-Barracuda-Connect: mail-qc0-f171.google.com[209.85.216.171] X-Barracuda-Start-Time: 1410312339 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9328 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 0.10 BSF_SC0_SA085 Custom Rule SA085 --047d7bdca458e10c0d0502abed22 Content-Type: text/plain; charset=UTF-8 Hi Leslie, You really don't want to be running "green" anything in an array... that is a ticking time bomb just waiting to go off... let me tell you... At my installation, a predecessor had procured a large number of green drives because they were very inexpensive and regrets were had by all. Lousy performance, lots of spurious ejection/RAID gremlins and the failure rate on the WDC Greens is just appalling... BBWC stands for Battery Backed Write Cache; this is a feature of hardware RAID cards; it is just like it says on the tin; a bit (usually half a gig, or a gig, or two...) of nonvolatile cache that retains writes to the array in case of power failure, etc. If you have BBWC enabled but your battery is dead, bad things can happen. Not applicable for JBOD software RAID. I hold firm to my beliefs on xfs_repair :) As I say, you'll see a variety of opinions here. Best, Sean On Tue, Sep 9, 2014 at 9:12 PM, Leslie Rhorer wrote: > On 9/9/2014 5:06 PM, Dave Chinner wrote: > >> Fristly, more infomration is required, namely versions and actual >> error messages: >> > > Indubitably: > > RAID-Server:/# xfs_repair -V > xfs_repair version 3.1.7 > RAID-Server:/# uname -r > 3.2.0-4-amd64 > > 4.0 GHz FX-8350 eight core processor > > RAID-Server:/# cat /proc/meminfo /proc/mounts /proc/partitions > MemTotal: 8099916 kB > MemFree: 5786420 kB > Buffers: 112684 kB > Cached: 457020 kB > SwapCached: 0 kB > Active: 521800 kB > Inactive: 457268 kB > Active(anon): 276648 kB > Inactive(anon): 140180 kB > Active(file): 245152 kB > Inactive(file): 317088 kB > Unevictable: 0 kB > Mlocked: 0 kB > SwapTotal: 12623740 kB > SwapFree: 12623740 kB > Dirty: 20 kB > Writeback: 0 kB > AnonPages: 409488 kB > Mapped: 47576 kB > Shmem: 7464 kB > Slab: 197100 kB > SReclaimable: 112644 kB > SUnreclaim: 84456 kB > KernelStack: 2560 kB > PageTables: 8468 kB > NFS_Unstable: 0 kB > Bounce: 0 kB > WritebackTmp: 0 kB > CommitLimit: 16673696 kB > Committed_AS: 1010172 kB > VmallocTotal: 34359738367 kB > VmallocUsed: 339140 kB > VmallocChunk: 34359395308 kB > HardwareCorrupted: 0 kB > AnonHugePages: 0 kB > HugePages_Total: 0 > HugePages_Free: 0 > HugePages_Rsvd: 0 > HugePages_Surp: 0 > Hugepagesize: 2048 kB > DirectMap4k: 65532 kB > DirectMap2M: 5120000 kB > DirectMap1G: 3145728 kB > rootfs / rootfs rw 0 0 > sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0 > proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0 > udev /dev devtmpfs rw,relatime,size=10240k,nr_inodes=1002653,mode=755 0 0 > devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 > 0 0 > tmpfs /run tmpfs rw,nosuid,noexec,relatime,size=809992k,mode=755 0 0 > /dev/disk/by-uuid/fa5c404a-bfcb-43de-87ed-e671fda1ba99 / ext4 > rw,relatime,errors=remount-ro,user_xattr,barrier=1,data=ordered 0 0 > tmpfs /run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k 0 0 > tmpfs /run/shm tmpfs rw,nosuid,nodev,noexec,relatime,size=4144720k 0 0 > /dev/md1 /boot ext2 rw,relatime,errors=continue 0 0 > rpc_pipefs /var/lib/nfs/rpc_pipefs rpc_pipefs rw,relatime 0 0 > Backup:/Backup /Backup nfs rw,relatime,vers=3,rsize= > 524288,wsize=524288,namlen=255,hard,proto=tcp,timeo=600, > retrans=2,sec=sys,mountaddr=192.168.1.51,mountvers=3, > mountport=39597,mountproto=tcp,local_lock=none,addr=192.168.1.51 0 0 > Backup:/var/www /var/www/backup nfs rw,relatime,vers=3,rsize= > 524288,wsize=524288,namlen=255,hard,proto=tcp,timeo=600, > retrans=2,sec=sys,mountaddr=192.168.1.51,mountvers=3, > mountport=39597,mountproto=tcp,local_lock=none,addr=192.168.1.51 0 0 > /dev/md0 /RAID xfs rw,relatime,attr2,delaylog,sunit=2048,swidth=12288,noquota > 0 0 > major minor #blocks name > > 8 0 125034840 sda > 8 1 96256 sda1 > 8 2 112305152 sda2 > 8 3 12632064 sda3 > 8 16 125034840 sdb > 8 17 96256 sdb1 > 8 18 112305152 sdb2 > 8 19 12632064 sdb3 > 8 48 3907018584 sdd > 8 32 3907018584 sdc > 8 64 1465138584 sde > 8 80 1465138584 sdf > 8 96 1465138584 sdg > 8 112 3907018584 sdh > 8 128 3907018584 sdi > 8 144 3907018584 sdj > 8 160 3907018584 sdk > 9 1 96192 md1 > 9 2 112239488 md2 > 9 3 12623744 md3 > 9 0 23441319936 md0 > 9 10 4395021312 md10 > > RAID-Server:/# cat /proc/mdstat > Personalities : [raid6] [raid5] [raid4] [raid1] [raid0] > md10 : active raid0 sdf[0] sde[2] sdg[1] > 4395021312 blocks super 1.2 512k chunks > > md0 : active raid6 md10[12] sdc[13] sdk[10] sdj[11] sdi[15] sdh[8] sdd[9] > 23441319936 blocks super 1.2 level 6, 1024k chunk, algorithm 2 [8/7] > [UUU_UUUU] > bitmap: 29/30 pages [116KB], 65536KB chunk > > md3 : active (auto-read-only) raid1 sda3[0] sdb3[1] > 12623744 blocks super 1.2 [3/2] [UU_] > bitmap: 1/1 pages [4KB], 65536KB chunk > > md2 : active raid1 sda2[0] sdb2[1] > 112239488 blocks super 1.2 [3/2] [UU_] > bitmap: 1/1 pages [4KB], 65536KB chunk > > md1 : active raid1 sda1[0] sdb1[1] > 96192 blocks [3/2] [UU_] > bitmap: 1/1 pages [4KB], 65536KB chunk > > unused devices: > > Six of the drives are 4T spindles (a mixture of makes and > models). The three drives comprising MD10 are WD 1.5T green drives. These > are in place to take over the function of one of the kicked 4T drives. > Md1, 2, and 3 are not data drives and are not suffering any issue. > > I'm not sure what is meant by "write cache status" in this > context. The machine has been rebooted more than once during recovery and > the FS has been umounted and xfs_repair run several times. > > I don't know for what the acronym BBWC stands. > > RAID-Server:/# xfs_info /dev/md0 > meta-data=/dev/md0 isize=256 agcount=43, agsize=137356288 > blks > = sectsz=512 attr=2 > data = bsize=4096 blocks=5860329984, imaxpct=5 > = sunit=256 swidth=1536 blks > naming =version 2 bsize=4096 ascii-ci=0 > log =internal bsize=4096 blocks=521728, version=2 > = sectsz=512 sunit=8 blks, lazy-count=1 > realtime =none extsz=4096 blocks=0, rtextents=0 > > The system performs just fine, other than the aforementioned, with > loads in excess of 3Gbps. That is internal only. The LAN link is ony > 1Gbps, so no external request exceeds about 950Mbps. > > http://xfs.org/index.php/XFS_FAQ#Q:_What_information_ >> should_I_include_when_reporting_a_problem.3F >> >> dmesg, in particular, should tell use what the corruption being >> encountered is when stat fails. >> > > RAID-Server:/# ls "/RAID/DVD/Big Sleep, The (1945)/VIDEO_TS/VTS_01_1.VOB" > ls: cannot access /RAID/DVD/Big Sleep, The (1945)/VIDEO_TS/VTS_01_1.VOB: > Structure needs cleaning > RAID-Server:/# dmesg | tail -n 30 > ... > [192173.363981] XFS (md0): corrupt dinode 41006, extent total = 1, nblocks > = 0. > [192173.363988] ffff8802338b8e00: 49 4e 81 b6 02 02 00 00 00 00 03 e8 00 > 00 03 e8 IN.............. > [192173.363996] XFS (md0): Internal error xfs_iformat(1) at line 319 of > file /build/linux-eKuxrT/linux-3.2.60/fs/xfs/xfs_inode.c. Caller > 0xffffffffa0509318 > [192173.363999] > [192173.364062] Pid: 10813, comm: ls Not tainted 3.2.0-4-amd64 #1 Debian > 3.2.60-1+deb7u3 > [192173.364065] Call Trace: > [192173.364097] [] ? xfs_corruption_error+0x54/0x6f > [xfs] > [192173.364134] [] ? xfs_iread+0x9f/0x177 [xfs] > [192173.364170] [] ? xfs_iformat+0xe3/0x462 [xfs] > [192173.364204] [] ? xfs_iread+0x9f/0x177 [xfs] > [192173.364240] [] ? xfs_iread+0x9f/0x177 [xfs] > [192173.364268] [] ? xfs_iget+0x37c/0x56c [xfs] > [192173.364300] [] ? xfs_lookup+0xa4/0xd3 [xfs] > [192173.364328] [] ? xfs_vn_lookup+0x3f/0x7e [xfs] > [192173.364344] [] ? d_alloc_and_lookup+0x3a/0x60 > [192173.364357] [] ? walk_component+0x219/0x406 > [192173.364370] [] ? path_lookupat+0x7c/0x2bd > [192173.364383] [] ? should_resched+0x5/0x23 > [192173.364396] [] ? _cond_resched+0x7/0x1c > [192173.364408] [] ? do_path_lookup+0x1c/0x87 > [192173.364420] [] ? user_path_at_empty+0x47/0x7b > [192173.364434] [] ? do_page_fault+0x30a/0x345 > [192173.364448] [] ? mmap_region+0x353/0x44a > [192173.364460] [] ? vfs_fstatat+0x32/0x60 > [192173.364471] [] ? sys_newstat+0x12/0x2b > [192173.364483] [] ? page_fault+0x25/0x30 > [192173.364495] [] ? system_call_fastpath+0x16/0x1b > [192173.364503] XFS (md0): Corruption detected. Unmount and run xfs_repair > > That last line, by the way, is why I ran umount and xfs_repair. > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs > --047d7bdca458e10c0d0502abed22 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi Leslie,

You really don't want to= be running "green" anything in an array... that is a ticking tim= e bomb just waiting to go off... let me tell you... At my installation, a p= redecessor had procured a large number of green drives because they were ve= ry inexpensive and regrets were had by all. Lousy performance, lots of spur= ious ejection/RAID gremlins and the failure rate on the WDC Greens is just = appalling...

BBWC stands for Battery Backed Write = Cache; this is a feature of hardware RAID cards; it is just like it says on= the tin; a bit (usually half a gig, or a gig, or two...) of nonvolatile ca= che that retains writes to the array in case of power failure, etc. If you = have BBWC enabled but your battery is dead, bad things can happen. Not appl= icable for JBOD software RAID.

I hold firm to my b= eliefs on xfs_repair :) As I say, you'll see a variety of opinions here= .=C2=A0

Best,

Sean
<= div>



On Tue, Sep 9, 2014 at 9:12 PM, Leslie Rho= rer <lrhorer@mygrande.net> wrote:
On 9/9/2014 5:06 PM, Dave Chinner wrote:
Fristly, more infomration is required, namely versions and actual
error messages:

=C2=A0 =C2=A0 =C2=A0 =C2=A0 Indubitably:

RAID-Server:/# xfs_repair -V
xfs_repair version 3.1.7
RAID-Server:/# uname -r
3.2.0-4-amd64

4.0 GHz FX-8350 eight core processor

RAID-Server:/# cat /proc/meminfo /proc/mounts /proc/partitions
MemTotal:=C2=A0 =C2=A0 =C2=A0 =C2=A0 8099916 kB
MemFree:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A05786420 kB
Buffers:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 112684 kB
Cached:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0457020 kB
SwapCached:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0 kB
Active:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0521800 kB
Inactive:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0457268 kB
Active(anon):=C2=A0 =C2=A0 =C2=A0276648 kB
Inactive(anon):=C2=A0 =C2=A0140180 kB
Active(file):=C2=A0 =C2=A0 =C2=A0245152 kB
Inactive(file):=C2=A0 =C2=A0317088 kB
Unevictable:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00 kB
Mlocked:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00 kB
SwapTotal:=C2=A0 =C2=A0 =C2=A0 12623740 kB
SwapFree:=C2=A0 =C2=A0 =C2=A0 =C2=A012623740 kB
Dirty:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 20 kB
Writeback:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00 kB
AnonPages:=C2=A0 =C2=A0 =C2=A0 =C2=A0 409488 kB
Mapped:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 47576 kB
Shmem:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 7464 kB
Slab:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0197100 kB
SReclaimable:=C2=A0 =C2=A0 =C2=A0112644 kB
SUnreclaim:=C2=A0 =C2=A0 =C2=A0 =C2=A0 84456 kB
KernelStack:=C2=A0 =C2=A0 =C2=A0 =C2=A0 2560 kB
PageTables:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A08468 kB
NFS_Unstable:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0 kB
Bounce:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0 kB
WritebackTmp:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 0 kB
CommitLimit:=C2=A0 =C2=A0 16673696 kB
Committed_AS:=C2=A0 =C2=A0 1010172 kB
VmallocTotal:=C2=A0 =C2=A034359738367 kB
VmallocUsed:=C2=A0 =C2=A0 =C2=A0 339140 kB
VmallocChunk:=C2=A0 =C2=A034359395308 kB
HardwareCorrupted:=C2=A0 =C2=A0 =C2=A00 kB
AnonHugePages:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A00 kB
HugePages_Total:=C2=A0 =C2=A0 =C2=A0 =C2=A00
HugePages_Free:=C2=A0 =C2=A0 =C2=A0 =C2=A0 0
HugePages_Rsvd:=C2=A0 =C2=A0 =C2=A0 =C2=A0 0
HugePages_Surp:=C2=A0 =C2=A0 =C2=A0 =C2=A0 0
Hugepagesize:=C2=A0 =C2=A0 =C2=A0 =C2=A02048 kB
DirectMap4k:=C2=A0 =C2=A0 =C2=A0 =C2=A065532 kB
DirectMap2M:=C2=A0 =C2=A0 =C2=A05120000 kB
DirectMap1G:=C2=A0 =C2=A0 =C2=A03145728 kB
rootfs / rootfs rw 0 0
sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
udev /dev devtmpfs rw,relatime,size=3D10240k,nr_inodes=3D1002653,mod= e=3D755 0 0
devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=3D5,mode=3D620,= ptmxmode=3D000 0 0
tmpfs /run tmpfs rw,nosuid,noexec,relatime,size=3D809992k,mode=3D755= 0 0
/dev/disk/by-uuid/fa5c404a-bfcb-43de-87ed-e671fda1ba99 / ext4 rw,rel= atime,errors=3Dremount-ro,user_xattr,barrier=3D1,data=3Dorder= ed 0 0
tmpfs /run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=3D5120k 0= 0
tmpfs /run/shm tmpfs rw,nosuid,nodev,noexec,relatime,size=3D4144720k= 0 0
/dev/md1 /boot ext2 rw,relatime,errors=3Dcontinue 0 0
rpc_pipefs /var/lib/nfs/rpc_pipefs rpc_pipefs rw,relatime 0 0
Backup:/Backup /Backup nfs rw,relatime,vers=3D3,rsize=3D524288,wsize= =3D524288,namlen=3D255,hard,proto=3Dtcp,timeo=3D600,retrans= =3D2,sec=3Dsys,mountaddr=3D192.168.1.51,mountvers=3D3,mountpo= rt=3D39597,mountproto=3Dtcp,local_lock=3Dnone,addr=3D192.168.= 1.51 0 0
Backup:/var/www /var/www/backup nfs rw,relatime,vers=3D3,rsize=3D524= 288,wsize=3D524288,namlen=3D255,hard,proto=3Dtcp,timeo=3D600,= retrans=3D2,sec=3Dsys,mountaddr=3D192.168.1.51,mountvers=3D3,= mountport=3D39597,mountproto=3Dtcp,local_lock=3Dnone,addr=3D192.<= /u>168.1.51 0 0
/dev/md0 /RAID xfs rw,relatime,attr2,delaylog,sunit=3D2048,swidth=3D= 12288,noquota 0 0
major minor=C2=A0 #blocks=C2=A0 name

=C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 =C2=A0 0=C2=A0 125034840 sda
=C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 =C2=A0 1=C2=A0 =C2=A0 =C2=A0 96256 sda1<= br> =C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 =C2=A0 2=C2=A0 112305152 sda2
=C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 =C2=A0 3=C2=A0 =C2=A012632064 sda3
=C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 =C2=A016 125034840 sdb
=C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 =C2=A017=C2=A0 =C2=A0 =C2=A0 96256 sdb1<= br> =C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 =C2=A018=C2=A0 112305152 sdb2
=C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 =C2=A019=C2=A0 =C2=A012632064 sdb3
=C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 =C2=A048 3907018584 sdd
=C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 =C2=A032 3907018584 sdc
=C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 =C2=A064 1465138584 sde
=C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 =C2=A080 1465138584 sdf
=C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 =C2=A096 1465138584 sdg
=C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 112 3907018584 sdh
=C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 128 3907018584 sdi
=C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 144 3907018584 sdj
=C2=A0 =C2=A08=C2=A0 =C2=A0 =C2=A0 160 3907018584 sdk
=C2=A0 =C2=A09=C2=A0 =C2=A0 =C2=A0 =C2=A0 1=C2=A0 =C2=A0 =C2=A0 96192 md1 =C2=A0 =C2=A09=C2=A0 =C2=A0 =C2=A0 =C2=A0 2=C2=A0 112239488 md2
=C2=A0 =C2=A09=C2=A0 =C2=A0 =C2=A0 =C2=A0 3=C2=A0 =C2=A012623744 md3
=C2=A0 =C2=A09=C2=A0 =C2=A0 =C2=A0 =C2=A0 0 23441319936 md0
=C2=A0 =C2=A09=C2=A0 =C2=A0 =C2=A0 =C2=A010 4395021312 md10

RAID-Server:/# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4] [raid1] [raid0]
md10 : active raid0 sdf[0] sde[2] sdg[1]
=C2=A0 =C2=A0 =C2=A0 4395021312 blocks super 1.2 512k chunks

md0 : active raid6 md10[12] sdc[13] sdk[10] sdj[11] sdi[15] sdh[8] sdd[9] =C2=A0 =C2=A0 =C2=A0 23441319936 blocks super 1.2 level 6, 1024k chunk, alg= orithm 2 [8/7] [UUU_UUUU]
=C2=A0 =C2=A0 =C2=A0 bitmap: 29/30 pages [116KB], 65536KB chunk

md3 : active (auto-read-only) raid1 sda3[0] sdb3[1]
=C2=A0 =C2=A0 =C2=A0 12623744 blocks super 1.2 [3/2] [UU_]
=C2=A0 =C2=A0 =C2=A0 bitmap: 1/1 pages [4KB], 65536KB chunk

md2 : active raid1 sda2[0] sdb2[1]
=C2=A0 =C2=A0 =C2=A0 112239488 blocks super 1.2 [3/2] [UU_]
=C2=A0 =C2=A0 =C2=A0 bitmap: 1/1 pages [4KB], 65536KB chunk

md1 : active raid1 sda1[0] sdb1[1]
=C2=A0 =C2=A0 =C2=A0 96192 blocks [3/2] [UU_]
=C2=A0 =C2=A0 =C2=A0 bitmap: 1/1 pages [4KB], 65536KB chunk

unused devices: <none>

=C2=A0 =C2=A0 =C2=A0 =C2=A0 Six of the drives are 4T spindles (a mixture of= makes and models).=C2=A0 The three drives comprising MD10 are WD 1.5T gree= n drives.=C2=A0 These are in place to take over the function of one of the = kicked 4T drives.=C2=A0 Md1, 2, and 3 are not data drives and are not suffe= ring any issue.

=C2=A0 =C2=A0 =C2=A0 =C2=A0 I'm not sure what is meant by "write c= ache status" in this context. The machine has been rebooted more than = once during recovery and the FS has been umounted and xfs_repair run severa= l times.

=C2=A0 =C2=A0 =C2=A0 =C2=A0 I don't know for what the acronym BBWC stan= ds.

RAID-Server:/# xfs_info /dev/md0
meta-data=3D/dev/md0=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= isize=3D256=C2=A0 =C2=A0 agcount=3D43, agsize=3D137356288 blks
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sectsz=3D512=C2=A0 =C2=A0attr= =3D2
data=C2=A0 =C2=A0 =C2=A0=3D=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0bsize=3D4096=C2=A0 =C2=A0blocks=3D586032= 9984, imaxpct=3D5
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sunit=3D256=C2=A0 =C2=A0 swidt= h=3D1536 blks
naming=C2=A0 =C2=A0=3Dversion 2=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 bsize=3D4096=C2=A0 =C2=A0ascii-ci=3D0
log=C2=A0 =C2=A0 =C2=A0 =3Dinternal=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0bsize=3D4096=C2=A0 =C2=A0blocks=3D521728, version=3D2
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=3D=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sectsz=3D512=C2=A0 =C2=A0sunit= =3D8 blks, lazy-count=3D1
realtime =3Dnone=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0extsz=3D4096=C2=A0 =C2=A0blocks=3D0, rtextents=3D0

=C2=A0 =C2=A0 =C2=A0 =C2=A0 The system performs just fine, other than the a= forementioned, with loads in excess of 3Gbps.=C2=A0 That is internal only.= =C2=A0 The LAN link is ony 1Gbps, so no external request exceeds about 950M= bps.

http://xfs.org/index.p= hp/XFS_FAQ#Q:_What_information_should_I_include_when_r= eporting_a_problem.3F

dmesg, in particular, should tell use what the corruption being
encountered is when stat fails.

RAID-Server:/# ls "/RAID/DVD/Big Sleep, The (1945)/VIDEO_TS/VTS_01_1.V= OB"
ls: cannot access /RAID/DVD/Big Sleep, The (1945)/VIDEO_TS/VTS_01_1.VOB: St= ructure needs cleaning
RAID-Server:/# dmesg | tail -n 30
...
[192173.363981] XFS (md0): corrupt dinode 41006, extent total =3D 1, nblock= s =3D 0.
[192173.363988] ffff8802338b8e00: 49 4e 81 b6 02 02 00 00 00 00 03 e8 00 00= 03 e8=C2=A0 IN..............
[192173.363996] XFS (md0): Internal error xfs_iformat(1) at line 319 of fil= e /build/linux-eKuxrT/linux-3.2.60/fs/xfs/xfs_inode.c.=C2=A0 Caller = 0xffffffffa0509318
[192173.363999]
[192173.364062] Pid: 10813, comm: ls Not tainted 3.2.0-4-amd64 #1 Debian 3.= 2.60-1+deb7u3
[192173.364065] Call Trace:
[192173.364097]=C2=A0 [<ffffffffa04d3731>] ? xfs_corruption_error+0x5= 4/0x6f [xfs]
[192173.364134]=C2=A0 [<ffffffffa0509318>] ? xfs_iread+0x9f/0x177 [xf= s]
[192173.364170]=C2=A0 [<ffffffffa0508efa>] ? xfs_iformat+0xe3/0x462 [= xfs]
[192173.364204]=C2=A0 [<ffffffffa0509318>] ? xfs_iread+0x9f/0x177 [xf= s]
[192173.364240]=C2=A0 [<ffffffffa0509318>] ? xfs_iread+0x9f/0x177 [xf= s]
[192173.364268]=C2=A0 [<ffffffffa04d6ebe>] ? xfs_iget+0x37c/0x56c [xf= s]
[192173.364300]=C2=A0 [<ffffffffa04e13b4>] ? xfs_lookup+0xa4/0xd3 [xf= s]
[192173.364328]=C2=A0 [<ffffffffa04d9e5a>] ? xfs_vn_lookup+0x3f/0x7e = [xfs]
[192173.364344]=C2=A0 [<ffffffff81102de9>] ? d_alloc_and_lookup+0x3a/= 0x60
[192173.364357]=C2=A0 [<ffffffff8110388d>] ? walk_component+0x219/0x4= 06
[192173.364370]=C2=A0 [<ffffffff81104721>] ? path_lookupat+0x7c/0x2bd=
[192173.364383]=C2=A0 [<ffffffff81036628>] ? should_resched+0x5/0x23<= br> [192173.364396]=C2=A0 [<ffffffff8134f144>] ? _cond_resched+0x7/0x1c [192173.364408]=C2=A0 [<ffffffff8110497e>] ? do_path_lookup+0x1c/0x87=
[192173.364420]=C2=A0 [<ffffffff81106407>] ? user_path_at_empty+0x47/= 0x7b
[192173.364434]=C2=A0 [<ffffffff813533d8>] ? do_page_fault+0x30a/0x34= 5
[192173.364448]=C2=A0 [<ffffffff810d6a04>] ? mmap_region+0x353/0x44a<= br> [192173.364460]=C2=A0 [<ffffffff810fe45a>] ? vfs_fstatat+0x32/0x60 [192173.364471]=C2=A0 [<ffffffff810fe590>] ? sys_newstat+0x12/0x2b [192173.364483]=C2=A0 [<ffffffff813509f5>] ? page_fault+0x25/0x30
[192173.364495]=C2=A0 [<ffffffff81355452>] ? system_call_fastpath+0x1= 6/0x1b
[192173.364503] XFS (md0): Corruption detected. Unmount and run xfs_repair<= br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 That last line, by the way, is why I ran umount= and xfs_repair.


_______________________________________________
xfs mailing list
xfs@oss.sgi.com http:= //oss.sgi.com/mailman/listinfo/xfs

--047d7bdca458e10c0d0502abed22-- From lrhorer@mygrande.net Tue Sep 9 20:31:18 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id DBD497F5D for ; Tue, 9 Sep 2014 20:31:18 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9919D304048 for ; Tue, 9 Sep 2014 18:31:18 -0700 (PDT) X-ASG-Debug-ID: 1410312676-04cbb05488c19170001-NocioJ Received: from mail01.lsn.net (mail01.lsn.net [66.90.130.120]) by cuda.sgi.com with ESMTP id 15nnJ8nOpEu7klmS for ; Tue, 09 Sep 2014 18:31:16 -0700 (PDT) X-Barracuda-Envelope-From: lrhorer@mygrande.net X-Barracuda-Apparent-Source-IP: 66.90.130.120 Received: from [192.168.1.121] (24-155-170-173.dyn.grandenetworks.net [24.155.170.173]) (authenticated bits=0) by mail01.lsn.net (8.14.4/8.13.6) with ESMTP id s8A1V7Ik019625 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Tue, 9 Sep 2014 20:31:08 -0500 X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.98.4 at av01.lsn.net Message-ID: <540FA9DB.20000@mygrande.net> Date: Tue, 09 Sep 2014 20:31:07 -0500 From: Leslie Rhorer User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: Roger Willcocks CC: Eric Sandeen , Sean Caron , "xfs@oss.sgi.com" Subject: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> <540F7E37.7020500@sandeen.net> <540F9FE9.7070500@mygrande.net> <3E40936B-A1F2-424D-B0B3-54B6C7B50B13@filmlight.ltd.uk> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: <3E40936B-A1F2-424D-B0B3-54B6C7B50B13@filmlight.ltd.uk> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail01.lsn.net[66.90.130.120] X-Barracuda-Start-Time: 1410312676 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9328 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 BSF_SC0_SA085 Custom Rule SA085 On 9/9/2014 8:10 PM, Roger Willcocks wrote: > > On 10 Sep 2014, at 01:48, Leslie Rhorer wrote: > >> The only ones remaining at issue are 3 files which cannot be read, written or deleted. > > The most straightforward fix would be to note down the inode numbers of the three fies and then use xfs_db to clear the inodes; then run xfs_repair again. > > See: > > http://xfs.org/index.php/XFS_FAQ#Q:_How_to_get_around_a_bad_inode_repair_is_unable_to_clean_up That sounds reasonable. If no one has any more sound advice, I think I will try that. > but before that try running the latest (3.2.1 I think) xfs_repair. I am always reticent to run anything outside the distro package. Ive had problems in the past with doing so. 3.1.7 is pretty close, so unless there is a really solid reason to use 3.2.1 vs. 3.1.7, I think I will stick with the distro version and try the above. Can you or anyone else give a reason why 3.2.1 would work when 3.1.7 would not? More importantly, is there some reason 3.1.7 would make things worse while 3.2.1 would not? If not, then I can always try 3.1.7 and then try 3.2.1 if that does not help. From lrhorer@mygrande.net Tue Sep 9 20:43:11 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 5AD647F5F for ; Tue, 9 Sep 2014 20:43:11 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 3CF648F8052 for ; Tue, 9 Sep 2014 18:43:11 -0700 (PDT) X-ASG-Debug-ID: 1410313389-04cbb05487c1ac20001-NocioJ Received: from mail04.lsn.net (mail04.lsn.net [66.90.130.138]) by cuda.sgi.com with ESMTP id 8vstn0KcJ354nJpy for ; Tue, 09 Sep 2014 18:43:10 -0700 (PDT) X-Barracuda-Envelope-From: lrhorer@mygrande.net X-Barracuda-Apparent-Source-IP: 66.90.130.138 Received: from [192.168.1.121] (24-155-170-173.dyn.grandenetworks.net [24.155.170.173]) (authenticated bits=0) by mail04.lsn.net (8.14.4/8.13.6) with ESMTP id s8A1h8Xv017150 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Tue, 9 Sep 2014 20:43:09 -0500 X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.98.4 at av02.lsn.net Message-ID: <540FACAC.3010504@mygrande.net> Date: Tue, 09 Sep 2014 20:43:08 -0500 From: Leslie Rhorer User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: Sean Caron CC: "xfs@oss.sgi.com" Subject: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail04.lsn.net[66.90.130.138] X-Barracuda-Start-Time: 1410313389 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_SA210e X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9328 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC5_SA210e Custom Rule SA210e On 9/9/2014 8:25 PM, Sean Caron wrote: > Hi Leslie, > > You really don't want to be running "green" anything in an array... that > is a ticking time bomb just waiting to go off... let me tell you... At > my installation, a predecessor had procured a large number of green > drives because they were very inexpensive and regrets were had by all. The alternative is nothing at all. I am not a company, just a guy with a couple of arrays at his house. 'Not a rich guy, either. I've had these arrays since 2001 with only one other mass drive failure, and that was not unrecoverable, nor were they "green" drives. (Four Seagate drives all suddenly decided they did not want to be part of the array, so md kicked all four simultaneously. After that, they would not stay up as part of the array long enough to be mounted. I was able to read all four with dd_rescue, and get the array back online without a single lost file. Note also these arrays are not usually under any sort of massive load. The bulk of the data is video files which are written once at about 80MBps and then read one-by-one at about 4MBps. > Lousy performance, lots of spurious ejection/RAID gremlins and the > failure rate on the WDC Greens is just appalling... None of the failed drives were WD green. All three and the previous four were Seagate. I realize that is not a large statistical sample. > BBWC stands for Battery Backed Write Cache; this is a feature of > hardware RAID cards Ah, yes. This array does not have a BBWC controller. The backup array does, actually, but the battery backup is disabled. > it is just like it says on the tin; a bit (usually > half a gig, or a gig, or two...) of nonvolatile cache that retains > writes to the array in case of power failure, etc. If you have BBWC > enabled but your battery is dead, bad things can happen. Not applicable > for JBOD software RAID. Exactly. All the arrays are JBOD / mdadm. From david@fromorbit.com Tue Sep 9 20:53:38 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 47B8B7F61 for ; Tue, 9 Sep 2014 20:53:38 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id B20BEAC004 for ; Tue, 9 Sep 2014 18:53:37 -0700 (PDT) X-ASG-Debug-ID: 1410314013-04cb6c54fd9487a0001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id kbSHjkiadBrRTO2f for ; Tue, 09 Sep 2014 18:53:34 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ApxPAI6uD1R5LKYhPGdsb2JhbAA/GoMNU1eCLIsto1cGmRaBWYVpAgIBAQGBBxcFAQEBATg3hAMBAQQBHhwcIwULCAMOCgklDwUlAwcaE4g6Bw42vFMBFxiFZIhpGgxCB4RMBZUWW4cBmSIrLwGBB4FHAQEB Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail05.adl6.internode.on.net with ESMTP; 10 Sep 2014 11:23:32 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XRX6B-00071U-Ic; Wed, 10 Sep 2014 11:53:31 +1000 Date: Wed, 10 Sep 2014 11:53:31 +1000 From: Dave Chinner To: Leslie Rhorer Cc: xfs@oss.sgi.com Subject: Re: Corrupted files Message-ID: <20140910015331.GJ20518@dastard> X-ASG-Orig-Subj: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540FA586.9090308@mygrande.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1410314013 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9328 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 BSF_SC0_SA085 Custom Rule SA085 On Tue, Sep 09, 2014 at 08:12:38PM -0500, Leslie Rhorer wrote: > On 9/9/2014 5:06 PM, Dave Chinner wrote: > >Fristly, more infomration is required, namely versions and actual > >error messages: > > Indubitably: > > RAID-Server:/# xfs_repair -V > xfs_repair version 3.1.7 > RAID-Server:/# uname -r > 3.2.0-4-amd64 Ok, so a relatively old xfs_repair. That's important - read on.... > 4.0 GHz FX-8350 eight core processor > > RAID-Server:/# cat /proc/meminfo /proc/mounts /proc/partitions > MemTotal: 8099916 kB .... > /dev/md0 /RAID xfs > rw,relatime,attr2,delaylog,sunit=2048,swidth=12288,noquota 0 0 FWIW, you don't need sunit=2048,swidth=12288 in the mount options - they are stored on disk and the mount options are only necessray to change the on-disk values. > Personalities : [raid6] [raid5] [raid4] [raid1] [raid0] > md10 : active raid0 sdf[0] sde[2] sdg[1] > 4395021312 blocks super 1.2 512k chunks > > md0 : active raid6 md10[12] sdc[13] sdk[10] sdj[11] sdi[15] sdh[8] sdd[9] > 23441319936 blocks super 1.2 level 6, 1024k chunk, algorithm 2 > [8/7] [UUU_UUUU] > bitmap: 29/30 pages [116KB], 65536KB chunk > > md3 : active (auto-read-only) raid1 sda3[0] sdb3[1] > 12623744 blocks super 1.2 [3/2] [UU_] > bitmap: 1/1 pages [4KB], 65536KB chunk > > md2 : active raid1 sda2[0] sdb2[1] > 112239488 blocks super 1.2 [3/2] [UU_] > bitmap: 1/1 pages [4KB], 65536KB chunk > > md1 : active raid1 sda1[0] sdb1[1] > 96192 blocks [3/2] [UU_] > bitmap: 1/1 pages [4KB], 65536KB chunk > > unused devices: > > Six of the drives are 4T spindles (a mixture of makes and models). > The three drives comprising MD10 are WD 1.5T green drives. These > are in place to take over the function of one of the kicked 4T > drives. Md1, 2, and 3 are not data drives and are not suffering any > issue. Ok, that's creative. But when you need another drive in the array and you don't have the right spares.... ;) > I'm not sure what is meant by "write cache status" in this context. > The machine has been rebooted more than once during recovery and the > FS has been umounted and xfs_repair run several times. Start here and read the next few entries: http://xfs.org/index.php/XFS_FAQ#Q:_What_is_the_problem_with_the_write_cache_on_journaled_filesystems.3F > I don't know for what the acronym BBWC stands. "battery backed write cache". If you're not using a hardware RAID controller, it's unlikely you have one. The difference between a drive write cache and a BBWC is that the BBWC is non-volatile - it does not get lost when power drops. > RAID-Server:/# xfs_info /dev/md0 > meta-data=/dev/md0 isize=256 agcount=43, > agsize=137356288 blks > = sectsz=512 attr=2 > data = bsize=4096 blocks=5860329984, imaxpct=5 > = sunit=256 swidth=1536 blks > naming =version 2 bsize=4096 ascii-ci=0 > log =internal bsize=4096 blocks=521728, version=2 > = sectsz=512 sunit=8 blks, lazy-count=1 > realtime =none extsz=4096 blocks=0, rtextents=0 Ok, that all looks pretty good, and the sunit/swidth match the mount options you set so you definitely don't need the mount options... > The system performs just fine, other than the aforementioned, with > loads in excess of 3Gbps. That is internal only. The LAN link is > ony 1Gbps, so no external request exceeds about 950Mbps. > > >http://xfs.org/index.php/XFS_FAQ#Q:_What_information_should_I_include_when_reporting_a_problem.3F > > > >dmesg, in particular, should tell use what the corruption being > >encountered is when stat fails. > > RAID-Server:/# ls "/RAID/DVD/Big Sleep, The (1945)/VIDEO_TS/VTS_01_1.VOB" > ls: cannot access /RAID/DVD/Big Sleep, The > (1945)/VIDEO_TS/VTS_01_1.VOB: Structure needs cleaning > RAID-Server:/# dmesg | tail -n 30 > ... > [192173.363981] XFS (md0): corrupt dinode 41006, extent total = 1, > nblocks = 0. > [192173.363988] ffff8802338b8e00: 49 4e 81 b6 02 02 00 00 00 00 03 > e8 00 00 03 e8 IN.............. > [192173.363996] XFS (md0): Internal error xfs_iformat(1) at line 319 > of file /build/linux-eKuxrT/linux-3.2.60/fs/xfs/xfs_inode.c. Caller > 0xffffffffa0509318 > [192173.363999] > [192173.364062] Pid: 10813, comm: ls Not tainted 3.2.0-4-amd64 #1 > Debian 3.2.60-1+deb7u3 > [192173.364065] Call Trace: > [192173.364097] [] ? xfs_corruption_error+0x54/0x6f [xfs] > [192173.364134] [] ? xfs_iread+0x9f/0x177 [xfs] > [192173.364170] [] ? xfs_iformat+0xe3/0x462 [xfs] > [192173.364204] [] ? xfs_iread+0x9f/0x177 [xfs] > [192173.364240] [] ? xfs_iread+0x9f/0x177 [xfs] > [192173.364268] [] ? xfs_iget+0x37c/0x56c [xfs] > [192173.364300] [] ? xfs_lookup+0xa4/0xd3 [xfs] > [192173.364328] [] ? xfs_vn_lookup+0x3f/0x7e [xfs] > [192173.364344] [] ? d_alloc_and_lookup+0x3a/0x60 > [192173.364357] [] ? walk_component+0x219/0x406 > [192173.364370] [] ? path_lookupat+0x7c/0x2bd > [192173.364383] [] ? should_resched+0x5/0x23 > [192173.364396] [] ? _cond_resched+0x7/0x1c > [192173.364408] [] ? do_path_lookup+0x1c/0x87 > [192173.364420] [] ? user_path_at_empty+0x47/0x7b > [192173.364434] [] ? do_page_fault+0x30a/0x345 > [192173.364448] [] ? mmap_region+0x353/0x44a > [192173.364460] [] ? vfs_fstatat+0x32/0x60 > [192173.364471] [] ? sys_newstat+0x12/0x2b > [192173.364483] [] ? page_fault+0x25/0x30 > [192173.364495] [] ? system_call_fastpath+0x16/0x1b > [192173.364503] XFS (md0): Corruption detected. Unmount and run xfs_repair > > That last line, by the way, is why I ran umount and xfs_repair. Right, that's the correct thing to do, but sometimes there are issues that repair doesn't handle properly. This *was* one of them, and it was fixed by commit e1f43b4 ("repair: update extent count after zapping duplicate blocks") which was added to xfs_repair v3.1.8. IOWs, upgrading xfsprogs to the latest release and re-running xfs_repair should fix this error. Cheers, Dave. -- Dave Chinner david@fromorbit.com From lrhorer@mygrande.net Tue Sep 9 22:11:52 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 24E2E7F66 for ; Tue, 9 Sep 2014 22:11:52 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1348D304048 for ; Tue, 9 Sep 2014 20:11:49 -0700 (PDT) X-ASG-Debug-ID: 1410318707-04cbb05485c3e270001-NocioJ Received: from mail02.lsn.net (mail02.lsn.net [66.90.130.128]) by cuda.sgi.com with ESMTP id bigOQlrixdHdiAjr for ; Tue, 09 Sep 2014 20:11:47 -0700 (PDT) X-Barracuda-Envelope-From: lrhorer@mygrande.net X-Barracuda-Apparent-Source-IP: 66.90.130.128 Received: from [192.168.1.121] (24-155-170-173.dyn.grandenetworks.net [24.155.170.173]) (authenticated bits=0) by mail02.lsn.net (8.14.4/8.13.6) with ESMTP id s8A3AjIT017931 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Tue, 9 Sep 2014 22:10:46 -0500 X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.98.4 at av02.lsn.net Message-ID: <540FC135.8010601@mygrande.net> Date: Tue, 09 Sep 2014 22:10:45 -0500 From: Leslie Rhorer User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: Dave Chinner CC: xfs@oss.sgi.com Subject: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> <20140910015331.GJ20518@dastard> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: <20140910015331.GJ20518@dastard> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail02.lsn.net[66.90.130.128] X-Barracuda-Start-Time: 1410318707 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9329 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 BSF_SC0_SA085 Custom Rule SA085 On 9/9/2014 8:53 PM, Dave Chinner wrote: > On Tue, Sep 09, 2014 at 08:12:38PM -0500, Leslie Rhorer wrote: >> On 9/9/2014 5:06 PM, Dave Chinner wrote: >>> Fristly, more infomration is required, namely versions and actual >>> error messages: >> >> Indubitably: >> >> RAID-Server:/# xfs_repair -V >> xfs_repair version 3.1.7 >> RAID-Server:/# uname -r >> 3.2.0-4-amd64 > > Ok, so a relatively old xfs_repair. That's important - read on.... OK, a good reason is a good reason. >> 4.0 GHz FX-8350 eight core processor >> >> RAID-Server:/# cat /proc/meminfo /proc/mounts /proc/partitions >> MemTotal: 8099916 kB > .... >> /dev/md0 /RAID xfs >> rw,relatime,attr2,delaylog,sunit=2048,swidth=12288,noquota 0 0 > > FWIW, you don't need sunit=2048,swidth=12288 in the mount options - > they are stored on disk and the mount options are only necessray to > change the on-disk values. They aren't. Those were created automatically, weather at creation time or at mount time, I don't know, but the filesystem was created with mkfs.xfs /dev/md0 and fstab contains: /dev/md0 /RAID xfs rw 1 2 >> Six of the drives are 4T spindles (a mixture of makes and models). >> The three drives comprising MD10 are WD 1.5T green drives. These >> are in place to take over the function of one of the kicked 4T >> drives. Md1, 2, and 3 are not data drives and are not suffering any >> issue. > > Ok, that's creative. But when you need another drive in the array > and you don't have the right spares.... ;) Yes, but I wasn't really expecting to need 3 spares this soon or suddenly. These are fairly new drives, and with 33% of the array being parity, the sudden need for 3 extra drives just is not too likely. That, plus I have quite a few 1.5 and 1.0T drives lying around in case of sudden emergency. This isn't the first time I've replaced a single drive temporarily with a RAID0. The performance is actually better, of course, and for the 3 or 4 days it takes to get a new drive, it's really not an issue. Since I have a full online backup system plus a regularly updated off-site backup, the risk is quite minimal. This is an exercise in mild inconvenience, not an emergency failure. If this were a commercial system, it would be another matter, but I know for a fact there are a very large number of home NAS solutions in place that are less robust than this one. I personally know quite a few people who never do backups, at all. >> I'm not sure what is meant by "write cache status" in this context. >> The machine has been rebooted more than once during recovery and the >> FS has been umounted and xfs_repair run several times. > > Start here and read the next few entries: > > http://xfs.org/index.php/XFS_FAQ#Q:_What_is_the_problem_with_the_write_cache_on_journaled_filesystems.3F I knew that, but I still don't see the relevance in this context. There is no battery backup on the drive controller or the drives, and the drives have all been powered down and back up several times. Anything in any cache right now would be from some operation in the last few minutes, not four days ago. >> I don't know for what the acronym BBWC stands. > > "battery backed write cache". If you're not using a hardware RAID > controller, it's unlikely you have one. See my previous. I do have one (a 3Ware 9650E, given to me by a friend when his company switched to zfs for their server). It's not on this system. This array is on a HighPoint RocketRAID 2722. > The difference between a > drive write cache and a BBWC is that the BBWC is non-volatile - it > does not get lost when power drops. Yeah, I'm aware, thanks. I just didn't cotton to the acronym. >> RAID-Server:/# xfs_info /dev/md0 >> meta-data=/dev/md0 isize=256 agcount=43, >> agsize=137356288 blks >> = sectsz=512 attr=2 >> data = bsize=4096 blocks=5860329984, imaxpct=5 >> = sunit=256 swidth=1536 blks >> naming =version 2 bsize=4096 ascii-ci=0 >> log =internal bsize=4096 blocks=521728, version=2 >> = sectsz=512 sunit=8 blks, lazy-count=1 >> realtime =none extsz=4096 blocks=0, rtextents=0 > > Ok, that all looks pretty good, and the sunit/swidth match the mount > options you set so you definitely don't need the mount options... Yeah, I didn't set them. What did, I don't really know for certain. See above. >> [192173.364460] [] ? vfs_fstatat+0x32/0x60 >> [192173.364471] [] ? sys_newstat+0x12/0x2b >> [192173.364483] [] ? page_fault+0x25/0x30 >> [192173.364495] [] ? system_call_fastpath+0x16/0x1b >> [192173.364503] XFS (md0): Corruption detected. Unmount and run xfs_repair >> >> That last line, by the way, is why I ran umount and xfs_repair. > > Right, that's the correct thing to do, but sometimes there are > issues that repair doesn't handle properly. This *was* one of them, > and it was fixed by commit e1f43b4 ("repair: update extent count > after zapping duplicate blocks") which was added to xfs_repair > v3.1.8. > > IOWs, upgrading xfsprogs to the latest release and re-running > xfs_repair should fix this error. OK. I'll scarf the source and compile. All I need is to git clone git://oss.sgi.com/xfs/xfs and git://oss.sgi.com/xfs/cmds/xfsprogs, right? I've never used git on a package maintained in my distro. Will I have issues when I upgrade to Debian Jessie in a few months, since this is not being managed by apt / dpkg? It looks like Jessie has 3.2.1 of xfs-progs. From david@fromorbit.com Tue Sep 9 22:33:38 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 0E08A7F58 for ; Tue, 9 Sep 2014 22:33:38 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id EE7388F8054 for ; Tue, 9 Sep 2014 20:33:37 -0700 (PDT) X-ASG-Debug-ID: 1410320015-04cbb05487c45210001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id e2tt3AUnHdBBitGS for ; Tue, 09 Sep 2014 20:33:35 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AnQ/AP7FD1R5LKYhPGdsb2JhbAA/GoMNU1eCLK5fBpkWgVmFaQICAQEBgQgXBQEBAQE4N4QDAQEEATocIwULCAMOCgklDwUlAwcaE4g6Bw42vFEBFxiFZIhmAyZCB4MvgR0FlXGHAZkiKy8BgQeBRwEBAQ Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail05.adl6.internode.on.net with ESMTP; 10 Sep 2014 13:03:34 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XRYex-0007Fa-Nj; Wed, 10 Sep 2014 13:33:31 +1000 Date: Wed, 10 Sep 2014 13:33:31 +1000 From: Dave Chinner To: Leslie Rhorer Cc: xfs@oss.sgi.com Subject: Re: Corrupted files Message-ID: <20140910033331.GA27048@dastard> X-ASG-Orig-Subj: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> <20140910015331.GJ20518@dastard> <540FC135.8010601@mygrande.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540FC135.8010601@mygrande.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1410320015 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9330 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 BSF_SC0_SA085 Custom Rule SA085 On Tue, Sep 09, 2014 at 10:10:45PM -0500, Leslie Rhorer wrote: > On 9/9/2014 8:53 PM, Dave Chinner wrote: > >On Tue, Sep 09, 2014 at 08:12:38PM -0500, Leslie Rhorer wrote: > >>On 9/9/2014 5:06 PM, Dave Chinner wrote: > >>>Fristly, more infomration is required, namely versions and actual > >>>error messages: > >> > >> Indubitably: > >> > >>RAID-Server:/# xfs_repair -V > >>xfs_repair version 3.1.7 > >>RAID-Server:/# uname -r > >>3.2.0-4-amd64 > > > >Ok, so a relatively old xfs_repair. That's important - read on.... > > OK, a good reason is a good reason. > > >>4.0 GHz FX-8350 eight core processor > >> > >>RAID-Server:/# cat /proc/meminfo /proc/mounts /proc/partitions > >>MemTotal: 8099916 kB > >.... > >>/dev/md0 /RAID xfs > >>rw,relatime,attr2,delaylog,sunit=2048,swidth=12288,noquota 0 0 > > > >FWIW, you don't need sunit=2048,swidth=12288 in the mount options - > >they are stored on disk and the mount options are only necessray to > >change the on-disk values. > > They aren't. Those were created automatically, weather at creation > time or at mount time, I don't know, but the filesystem was created > with Ah, my mistake. Normally it's only mount options in that code - I forgot that we report sunit/swidth unconditionally if it is set in the superblock. > >> I'm not sure what is meant by "write cache status" in this context. > >>The machine has been rebooted more than once during recovery and the > >>FS has been umounted and xfs_repair run several times. > > > >Start here and read the next few entries: > > > >http://xfs.org/index.php/XFS_FAQ#Q:_What_is_the_problem_with_the_write_cache_on_journaled_filesystems.3F > > I knew that, but I still don't see the relevance in this context. > There is no battery backup on the drive controller or the drives, > and the drives have all been powered down and back up several times. > Anything in any cache right now would be from some operation in the > last few minutes, not four days ago. There is no direct relevance to your situation, but for a lot of other common problems it definitely is. That's why we ask people to report it with all the other information about their system > >> I don't know for what the acronym BBWC stands. > > > >"battery backed write cache". If you're not using a hardware RAID > >controller, it's unlikely you have one. > > See my previous. I do have one (a 3Ware 9650E, given to me by a > friend when his company switched to zfs for their server). It's not > on this system. This array is on a HighPoint RocketRAID 2722. Ok. We have seen over time that those 3ware controllers can do strange things in error conditions - we've had reports of entire hardware luns dying and being completely unrecoverable after a disk was kicked out due to an error. I can't comment on the highpoint controller - either not many people use them or they just don't report problems if there do. Either way, I'd suggest that if you aren't running the latest firmware it would be to update them as these problems were typically fixed by newer firmware releases. > >>[192173.364460] [] ? vfs_fstatat+0x32/0x60 > >>[192173.364471] [] ? sys_newstat+0x12/0x2b > >>[192173.364483] [] ? page_fault+0x25/0x30 > >>[192173.364495] [] ? system_call_fastpath+0x16/0x1b > >>[192173.364503] XFS (md0): Corruption detected. Unmount and run xfs_repair > >> > >> That last line, by the way, is why I ran umount and xfs_repair. > > > >Right, that's the correct thing to do, but sometimes there are > >issues that repair doesn't handle properly. This *was* one of them, > >and it was fixed by commit e1f43b4 ("repair: update extent count > >after zapping duplicate blocks") which was added to xfs_repair > >v3.1.8. > > > >IOWs, upgrading xfsprogs to the latest release and re-running > >xfs_repair should fix this error. > > OK. I'll scarf the source and compile. All I need is to git clone > git://oss.sgi.com/xfs/xfs and git://oss.sgi.com/xfs/cmds/xfsprogs, > right? Just clone git://oss.sgi.com/xfs/cmds/xfsprogs and check out the v3.2.1 tag and build that.. > I've never used git on a package maintained in my distro. Will I > have issues when I upgrade to Debian Jessie in a few months, since > this is not being managed by apt / dpkg? It looks like Jessie has > 3.2.1 of xfs-progs. If you're using debian you can build debian packages directly from the git tree via "make deb" (I use it all the time for pushing new builds to my test machines) and so when you upgrade to Jessie it should just replace your custom built package correctly... Cheers, Dave. -- Dave Chinner david@fromorbit.com From lrhorer@mygrande.net Tue Sep 9 23:16:01 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 4A2D97F6C for ; Tue, 9 Sep 2014 23:16:01 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id BE36FAC003 for ; Tue, 9 Sep 2014 21:15:57 -0700 (PDT) X-ASG-Debug-ID: 1410322555-04cb6c54ff9639d0001-NocioJ Received: from mail04.lsn.net (mail04.lsn.net [66.90.130.138]) by cuda.sgi.com with ESMTP id nA0NYnjeNNmOgxFD for ; Tue, 09 Sep 2014 21:15:55 -0700 (PDT) X-Barracuda-Envelope-From: lrhorer@mygrande.net X-Barracuda-Apparent-Source-IP: 66.90.130.138 Received: from [192.168.1.121] (24-155-170-173.dyn.grandenetworks.net [24.155.170.173]) (authenticated bits=0) by mail04.lsn.net (8.14.4/8.13.6) with ESMTP id s8A4EnYG000932 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Tue, 9 Sep 2014 23:14:49 -0500 X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.98.4 at av01.lsn.net Message-ID: <540FD038.5010202@mygrande.net> Date: Tue, 09 Sep 2014 23:14:48 -0500 From: Leslie Rhorer User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: Dave Chinner CC: xfs@oss.sgi.com Subject: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> <20140910015331.GJ20518@dastard> <540FC135.8010601@mygrande.net> <20140910033331.GA27048@dastard> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: <20140910033331.GA27048@dastard> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail04.lsn.net[66.90.130.138] X-Barracuda-Start-Time: 1410322555 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9330 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/9/2014 10:33 PM, Dave Chinner wrote: > There is no direct relevance to your situation, but for a lot of > other common problems it definitely is. That's why we ask people to > report it with all the other information about their system Yeah, understood. > Ok. We have seen over time that those 3ware controllers can do > strange things in error conditions - we've had reports of entire > hardware luns dying and being completely unrecoverable after a > disk was kicked out due to an error. Oof. That's not good. It's stable right now. I'm considering a different controller at some point. I may accelerate that process. > I can't comment on the > highpoint controller - either not many people use them or they just > don't report problems if there do. Either way, I'd suggest that if > you aren't running the latest firmware it would be to update them > as these problems were typically fixed by newer firmware releases. As a matter of fact, I was going to do just that. I have to reboot the system in DOS (of all things), since they don't have a linux loader. I've got to arrange a convenient time. >> OK. I'll scarf the source and compile. All I need is to git clone >> git://oss.sgi.com/xfs/xfs and git://oss.sgi.com/xfs/cmds/xfsprogs, >> right? > > Just clone git://oss.sgi.com/xfs/cmds/xfsprogs and check out the > v3.2.1 tag and build that.. OK, I'm doing something wrong, I think. It's been over a decade since I compiled a kernel. It makes me a little nervous. > >> I've never used git on a package maintained in my distro. Will I >> have issues when I upgrade to Debian Jessie in a few months, since >> this is not being managed by apt / dpkg? It looks like Jessie has >> 3.2.1 of xfs-progs. > > If you're using debian you can build debian packages directly from > the git tree via "make deb" (I use it all the time for pushing Um, is that make deb-pkg, perhaps? I'm not seeing a "deb" in the package targets. > new builds to my test machines) and so when you upgrade to Jessie it > should just replace your custom built package correctly... `make deb` finds no install target. If I run `make menuconfig` it complains about there being no ncurses. Libncurses5 is installed, and I don't know what else I should get. `make oldconfig` seems to work. Am I headed the right direction? There are quite a few configuration targets, and I am not sure which one to choose. There are also a number of questions asked by the oldconfig target (and presumably the same for other config targets), and I'm unsure how to answer. I definitely don't want to make an error and potentially wind up with an unbootable system. From lrhorer@mygrande.net Tue Sep 9 23:23:10 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 000F17F72 for ; Tue, 9 Sep 2014 23:23:09 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id E27D0304059 for ; Tue, 9 Sep 2014 21:23:06 -0700 (PDT) X-ASG-Debug-ID: 1410322985-04cbb05488c51cd0001-NocioJ Received: from mail02.lsn.net (mail02.lsn.net [66.90.130.128]) by cuda.sgi.com with ESMTP id gwWfYmm5MJQHB7Qy for ; Tue, 09 Sep 2014 21:23:05 -0700 (PDT) X-Barracuda-Envelope-From: lrhorer@mygrande.net X-Barracuda-Apparent-Source-IP: 66.90.130.128 Received: from [192.168.1.121] (24-155-170-173.dyn.grandenetworks.net [24.155.170.173]) (authenticated bits=0) by mail02.lsn.net (8.14.4/8.13.6) with ESMTP id s8A4M3G4029409 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Tue, 9 Sep 2014 23:22:04 -0500 X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.98.4 at av01.lsn.net Message-ID: <540FD1EB.8070007@mygrande.net> Date: Tue, 09 Sep 2014 23:22:03 -0500 From: Leslie Rhorer User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: Dave Chinner CC: xfs@oss.sgi.com Subject: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> <20140910015331.GJ20518@dastard> <540FC135.8010601@mygrande.net> <20140910033331.GA27048@dastard> <540FD038.5010202@mygrande.net> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: <540FD038.5010202@mygrande.net> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail02.lsn.net[66.90.130.128] X-Barracuda-Start-Time: 1410322985 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9331 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- >>> OK. I'll scarf the source and compile. All I need is to git clone >>> git://oss.sgi.com/xfs/xfs and git://oss.sgi.com/xfs/cmds/xfsprogs, >>> right? >> >> Just clone git://oss.sgi.com/xfs/cmds/xfsprogs and check out the >> v3.2.1 tag and build that.. Oops! Hold on. I didn't read that closely enough. You were saying I only need to compile xfs-progs. That's working. From lrhorer@mygrande.net Tue Sep 9 23:52:45 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id BC69C7F74 for ; Tue, 9 Sep 2014 23:52:45 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id A1812304048 for ; Tue, 9 Sep 2014 21:52:45 -0700 (PDT) X-ASG-Debug-ID: 1410324764-04cb6c54fe96a410001-NocioJ Received: from mail04.lsn.net (mail04.lsn.net [66.90.130.138]) by cuda.sgi.com with ESMTP id 6mhRhkldaBDl6Suh for ; Tue, 09 Sep 2014 21:52:44 -0700 (PDT) X-Barracuda-Envelope-From: lrhorer@mygrande.net X-Barracuda-Apparent-Source-IP: 66.90.130.138 Received: from [192.168.1.121] (24-155-170-173.dyn.grandenetworks.net [24.155.170.173]) (authenticated bits=0) by mail04.lsn.net (8.14.4/8.13.6) with ESMTP id s8A4pgUs017045 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Tue, 9 Sep 2014 23:51:43 -0500 X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.98.4 at av02.lsn.net Message-ID: <540FD8DE.7090306@mygrande.net> Date: Tue, 09 Sep 2014 23:51:42 -0500 From: Leslie Rhorer User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: Dave Chinner CC: xfs@oss.sgi.com Subject: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> <20140910015331.GJ20518@dastard> <540FC135.8010601@mygrande.net> <20140910033331.GA27048@dastard> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: <20140910033331.GA27048@dastard> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail04.lsn.net[66.90.130.138] X-Barracuda-Start-Time: 1410324764 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9331 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 BSF_SC0_SA085 Custom Rule SA085 On 9/9/2014 10:33 PM, Dave Chinner wrote: > On Tue, Sep 09, 2014 at 10:10:45PM -0500, Leslie Rhorer wrote: >> On 9/9/2014 8:53 PM, Dave Chinner wrote: >>> On Tue, Sep 09, 2014 at 08:12:38PM -0500, Leslie Rhorer wrote: >>>> On 9/9/2014 5:06 PM, Dave Chinner wrote: >>>>> Fristly, more infomration is required, namely versions and actual >>>>> error messages: >>>> >>>> Indubitably: >>>> >>>> RAID-Server:/# xfs_repair -V >>>> xfs_repair version 3.1.7 >>>> RAID-Server:/# uname -r >>>> 3.2.0-4-amd64 >>> >>> Ok, so a relatively old xfs_repair. That's important - read on.... >> >> OK, a good reason is a good reason. >> >>>> 4.0 GHz FX-8350 eight core processor >>>> >>>> RAID-Server:/# cat /proc/meminfo /proc/mounts /proc/partitions >>>> MemTotal: 8099916 kB >>> .... >>>> /dev/md0 /RAID xfs >>>> rw,relatime,attr2,delaylog,sunit=2048,swidth=12288,noquota 0 0 >>> >>> FWIW, you don't need sunit=2048,swidth=12288 in the mount options - >>> they are stored on disk and the mount options are only necessray to >>> change the on-disk values. >> >> They aren't. Those were created automatically, weather at creation >> time or at mount time, I don't know, but the filesystem was created >> with > > Ah, my mistake. Normally it's only mount options in that code - I > forgot that we report sunit/swidth unconditionally if it is set in > the superblock. > >>>> I'm not sure what is meant by "write cache status" in this context. >>>> The machine has been rebooted more than once during recovery and the >>>> FS has been umounted and xfs_repair run several times. >>> >>> Start here and read the next few entries: >>> >>> http://xfs.org/index.php/XFS_FAQ#Q:_What_is_the_problem_with_the_write_cache_on_journaled_filesystems.3F >> >> I knew that, but I still don't see the relevance in this context. >> There is no battery backup on the drive controller or the drives, >> and the drives have all been powered down and back up several times. >> Anything in any cache right now would be from some operation in the >> last few minutes, not four days ago. > > There is no direct relevance to your situation, but for a lot of > other common problems it definitely is. That's why we ask people to > report it with all the other information about their system > >>>> I don't know for what the acronym BBWC stands. >>> >>> "battery backed write cache". If you're not using a hardware RAID >>> controller, it's unlikely you have one. >> >> See my previous. I do have one (a 3Ware 9650E, given to me by a >> friend when his company switched to zfs for their server). It's not >> on this system. This array is on a HighPoint RocketRAID 2722. > > Ok. We have seen over time that those 3ware controllers can do > strange things in error conditions - we've had reports of entire > hardware luns dying and being completely unrecoverable after a > disk was kicked out due to an error. I can't comment on the > highpoint controller - either not many people use them or they just > don't report problems if there do. Either way, I'd suggest that if > you aren't running the latest firmware it would be to update them > as these problems were typically fixed by newer firmware releases. > >>>> [192173.364460] [] ? vfs_fstatat+0x32/0x60 >>>> [192173.364471] [] ? sys_newstat+0x12/0x2b >>>> [192173.364483] [] ? page_fault+0x25/0x30 >>>> [192173.364495] [] ? system_call_fastpath+0x16/0x1b >>>> [192173.364503] XFS (md0): Corruption detected. Unmount and run xfs_repair >>>> >>>> That last line, by the way, is why I ran umount and xfs_repair. >>> >>> Right, that's the correct thing to do, but sometimes there are >>> issues that repair doesn't handle properly. This *was* one of them, >>> and it was fixed by commit e1f43b4 ("repair: update extent count >>> after zapping duplicate blocks") which was added to xfs_repair >>> v3.1.8. >>> >>> IOWs, upgrading xfsprogs to the latest release and re-running >>> xfs_repair should fix this error. >> >> OK. I'll scarf the source and compile. All I need is to git clone >> git://oss.sgi.com/xfs/xfs and git://oss.sgi.com/xfs/cmds/xfsprogs, >> right? > > Just clone git://oss.sgi.com/xfs/cmds/xfsprogs and check out the > v3.2.1 tag and build that.. > >> I've never used git on a package maintained in my distro. Will I >> have issues when I upgrade to Debian Jessie in a few months, since >> this is not being managed by apt / dpkg? It looks like Jessie has >> 3.2.1 of xfs-progs. > > If you're using debian you can build debian packages directly from > the git tree via "make deb" (I use it all the time for pushing > new builds to my test machines) and so when you upgrade to Jessie it > should just replace your custom built package correctly... > > Cheers, > > Dave. Thanks a ton, Dave (and everyone else who helped). That seems to have worked just fine. The three grunged entries are gone and the system is happily copying over the backups. Now I'll run another rsync with checksum to make sure everything is good before putting the backup into production. I'm also going to upgrade the controller BIOS just in case. From sandeen@sandeen.net Wed Sep 10 00:09:09 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 0DBE37F76 for ; Wed, 10 Sep 2014 00:09:09 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id EEF168F8050 for ; Tue, 9 Sep 2014 22:09:05 -0700 (PDT) X-ASG-Debug-ID: 1410325744-04cb6c550096ab30001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id mKRpVCd9jK4dYaqu for ; Tue, 09 Sep 2014 22:09:04 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 3C96765A2CE6; Wed, 10 Sep 2014 00:09:04 -0500 (CDT) Message-ID: <540FDCF4.3020202@sandeen.net> Date: Wed, 10 Sep 2014 00:09:08 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Sean Caron CC: Leslie Rhorer , "xfs@oss.sgi.com" Subject: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> <540F7E37.7020500@sandeen.net> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410325744 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9331 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/9/14 5:57 PM, Sean Caron wrote: > Hey, just sharing some hard-won (believe me) professional experience. > I have seen xfs_repair take a bad situation and make it worse many > times. I don't know that a filesystem fuzzer or any other simulation > can ever provide true simulation of users absolutely pounding the tar > out of a system. There seems to be a real disconnect between what > developers are able to test and observe directly, and what happens in > the production environment in a very high-throughput environment. > > Best, > > Sean Fair enough, but I don't want to let stand an assertion that you should avoid xfs_repair at all (most) costs. It, like almost any software, has some bugs, but they don't get fixed if they don't get well reported. We do our best to improve it when we get useful reports from users - usually including a metadata dump - and we beat on it as best we can in the lab. "pounding the tar out of a filesystem" should not, in general, require an xfs_repair run. ;) Yes, it's always good advice to do a dry run before committing to a repair, in case something goes off the rails. But most times I've seen things go very very badly was when the storage device under the filesystem was no longer consistent, and the filesystem really had no pieces to pick up. -Eric From david@fromorbit.com Wed Sep 10 00:23:31 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 527467F78 for ; Wed, 10 Sep 2014 00:23:31 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id D4C52AC006 for ; Tue, 9 Sep 2014 22:23:30 -0700 (PDT) X-ASG-Debug-ID: 1410326604-04cbb05487c5ba10001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id FXizr3gR03iks0cK for ; Tue, 09 Sep 2014 22:23:25 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtYlAMffD1R5LKYhPGdsb2JhbABZgw2BKoIsrn8Gmm+FaQQCAYEJFwUBAQEBODeEBAEFOhwjEAgDDgoJJQ8FJQMHGhOIQb0yARcYhWSIZmsHgy+BHQWccpkiKy+CTwEBAQ Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail05.adl6.internode.on.net with ESMTP; 10 Sep 2014 14:53:05 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XRaMx-0007Xa-Bz; Wed, 10 Sep 2014 15:23:03 +1000 Date: Wed, 10 Sep 2014 15:23:03 +1000 From: Dave Chinner To: Leslie Rhorer Cc: xfs@oss.sgi.com Subject: Re: Corrupted files Message-ID: <20140910052303.GB27048@dastard> X-ASG-Orig-Subj: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> <20140910015331.GJ20518@dastard> <540FC135.8010601@mygrande.net> <20140910033331.GA27048@dastard> <540FD8DE.7090306@mygrande.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <540FD8DE.7090306@mygrande.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1410326604 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9332 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 09, 2014 at 11:51:42PM -0500, Leslie Rhorer wrote: > On 9/9/2014 10:33 PM, Dave Chinner wrote: > >On Tue, Sep 09, 2014 at 10:10:45PM -0500, Leslie Rhorer wrote: > >>On 9/9/2014 8:53 PM, Dave Chinner wrote: > >>>On Tue, Sep 09, 2014 at 08:12:38PM -0500, Leslie Rhorer wrote: > >>>>On 9/9/2014 5:06 PM, Dave Chinner wrote: > >> I've never used git on a package maintained in my distro. Will I > >>have issues when I upgrade to Debian Jessie in a few months, since > >>this is not being managed by apt / dpkg? It looks like Jessie has > >>3.2.1 of xfs-progs. > > > >If you're using debian you can build debian packages directly from > >the git tree via "make deb" (I use it all the time for pushing > >new builds to my test machines) and so when you upgrade to Jessie it > >should just replace your custom built package correctly... > > Thanks a ton, Dave (and everyone else who helped). That seems to > have worked just fine. The three grunged entries are gone and the > system is happily copying over the backups. Now I'll run another > rsync with checksum to make sure everything is good before putting > the backup into production. I'm also going to upgrade the > controller BIOS just in case. Good to hear. Hopefully everything will check out. Just yell if you need more help. ;) Cheers, Dave. -- Dave Chinner david@fromorbit.com From denoy.steve32@gmail.com Wed Sep 10 03:04:43 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.3 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id A4D807F3F for ; Wed, 10 Sep 2014 03:04:43 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 92A9C8F8059 for ; Wed, 10 Sep 2014 01:04:40 -0700 (PDT) X-ASG-Debug-ID: 1410336277-04cb6c54fd9788b0001-NocioJ Received: from mwork.nabble.com (static.162.253.133.43.macminivault.com [162.253.133.43]) by cuda.sgi.com with ESMTP id N0jyuMJkYBgNxNro for ; Wed, 10 Sep 2014 01:04:38 -0700 (PDT) X-Barracuda-Envelope-From: denoy.steve32@gmail.com X-Barracuda-Apparent-Source-IP: 162.253.133.43 Received: from mtom.nabble.com (unknown [162.253.133.81]) by mwork.nabble.com (Postfix) with ESMTP id 3E5A7550B66 for ; Wed, 10 Sep 2014 01:04:36 -0700 (PDT) Date: Wed, 10 Sep 2014 01:03:54 -0700 (MST) From: jame87 To: xfs@oss.sgi.com Message-ID: <1410336234315-35025.post@n7.nabble.com> In-Reply-To: References: Subject: =?UTF-8?Q?Re:_VIETNAM_Acquiring_Business?= =?UTF-8?Q?_=E2=80=93_Legal_and_Tax_Considerations?= MIME-Version: 1.0 X-ASG-Orig-Subj: =?UTF-8?Q?Re:_VIETNAM_Acquiring_Business?= =?UTF-8?Q?_=E2=80=93_Legal_and_Tax_Considerations?= Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: static.162.253.133.43.macminivault.com[162.253.133.43] X-Barracuda-Start-Time: 1410336277 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-BRTS-Evidence: lawbrokers.com.au X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9334 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- I would be interested in acquiring law firms for sale in Vietnam but the idea of the complicated regulatory framework for acquisitions is holding me back. The government should make the process easier. -- View this message in context: http://xfs.9218.n7.nabble.com/VIETNAM-Acquiring-Business-Legal-and-Tax-Considerations-tp18168p35025.html Sent from the Xfs - General mailing list archive at Nabble.com. From bfoster@redhat.com Wed Sep 10 08:20:37 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 3B8F57F3F for ; Wed, 10 Sep 2014 08:20:37 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 2A7178F8049 for ; Wed, 10 Sep 2014 06:20:34 -0700 (PDT) X-ASG-Debug-ID: 1410355232-04cb6c54fe990130001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id dlzHwzyg3drpMDqF (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 10 Sep 2014 06:20:33 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8ADKWDw030987 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Wed, 10 Sep 2014 09:20:32 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8ADKWga009670 for ; Wed, 10 Sep 2014 09:20:32 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 5159E1256F8; Wed, 10 Sep 2014 09:20:31 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc Date: Wed, 10 Sep 2014 09:20:26 -0400 X-ASG-Orig-Subj: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc Message-Id: <1410355231-50495-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410355233 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hi all, Here's v2 of the collapse clean up. We refactor a bit more via the insertion of patch 3, otherwise it's similar to v1. This will see some continued testing, but it survived ~500m fsx operations overnight. Brian v2: - Rename helpers to xfs_bmse_*() scheme. - Rearrange logic and minor cleanups to xfs_bmse[_can]_merge(). - Inserted patch 3 to further refactor xfs_bmap_shift_extents() into xfs_bmse_shift_one(). - Return corruption error rather than BUG_ON() in patch 4 and detect error in new helper. v1: http://oss.sgi.com/archives/xfs/2014-09/msg00061.html - Retain the eofblocks trim and writeback/inval. the range of shifted data only. - Added the xfs_free_file_space() patch to no longer writeback the entire file. rfc: http://oss.sgi.com/archives/xfs/2014-08/msg00462.html Brian Foster (5): xfs: track collapse via file offset rather than extent index xfs: refactor shift-by-merge into xfs_bmse_merge() helper xfs: refactor single extent shift into xfs_bmse_shift_one() helper xfs: writeback and inval. file range to be shifted by collapse xfs: only writeback and truncate pages for the freed range fs/xfs/libxfs/xfs_bmap.c | 365 +++++++++++++++++++++++++++++++---------------- fs/xfs/libxfs/xfs_bmap.h | 7 +- fs/xfs/xfs_bmap_util.c | 54 ++++--- 3 files changed, 275 insertions(+), 151 deletions(-) -- 1.8.3.1 From bfoster@redhat.com Wed Sep 10 08:20:37 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 810347F47 for ; Wed, 10 Sep 2014 08:20:37 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 615BC304051 for ; Wed, 10 Sep 2014 06:20:34 -0700 (PDT) X-ASG-Debug-ID: 1410355233-04cb6c54fd990130001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id MLTUfng196Ptn2Es (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 10 Sep 2014 06:20:33 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8ADKW1n030574 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Wed, 10 Sep 2014 09:20:32 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8ADKWPr014730 for ; Wed, 10 Sep 2014 09:20:32 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 799191256FA; Wed, 10 Sep 2014 09:20:31 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 4/5] xfs: writeback and inval. file range to be shifted by collapse Date: Wed, 10 Sep 2014 09:20:30 -0400 X-ASG-Orig-Subj: [PATCH v2 4/5] xfs: writeback and inval. file range to be shifted by collapse Message-Id: <1410355231-50495-5-git-send-email-bfoster@redhat.com> In-Reply-To: <1410355231-50495-1-git-send-email-bfoster@redhat.com> References: <1410355231-50495-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410355233 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The collapse range operation currently writes the entire file before starting the collapse to avoid changes in the in-core extent list due to writeback causing the extent count to change. Now that collapse range is fsb based rather than extent index based it can sustain changes in the extent list during the shift sequence without disruption. Modify xfs_collapse_file_space() to writeback and invalidate pages associated with the range of the file to be shifted. xfs_free_file_space() currently has similar behavior, but the space free need only affect the region of the file that is freed and this could change in the future. Also update the comments to reflect the current implementation. We retain the eofblocks trim permanently as a best option for dealing with delalloc extents. We don't shift delalloc extents because this scenario only occurs with post-eof preallocation (since data must be flushed such that the cache can be invalidated and data can be shifted). That means said space must also be initialized before being shifted into the accessible region of the file only to be immediately truncated off as the last part of the collapse. In other words, the eofblocks trim will happen anyways, we just run it first to ensure the file remains in a consistent state throughout the collapse. Finally, detect and fail explicitly in the event of a delalloc extent during the extent shift. The implementation does not support delalloc extents and the caller is expected to prevent this scenario in advance as is done by collapse. Signed-off-by: Brian Foster --- fs/xfs/libxfs/xfs_bmap.c | 4 ++++ fs/xfs/xfs_bmap_util.c | 32 +++++++++++++++++++------------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 69bf8d8..79c9819 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5543,6 +5543,10 @@ xfs_bmse_shift_one( xfs_bmbt_get_all(gotp, &got); startoff = got.br_startoff - offset_shift_fsb; + /* delalloc extents should be prevented by caller */ + XFS_WANT_CORRUPTED_GOTO(!isnullstartblock(got.br_startblock), + out_error); + /* * If this is the first extent in the file, make sure there's enough * room at the start of the file and jump right to the shift as there's diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 1e96d77..eae763f 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1470,27 +1470,33 @@ xfs_collapse_file_space( next_fsb = XFS_B_TO_FSB(mp, offset + len); shift_fsb = XFS_B_TO_FSB(mp, len); - /* - * Writeback the entire file and force remove any post-eof blocks. The - * writeback prevents changes to the extent list via concurrent - * writeback and the eofblocks trim prevents the extent shift algorithm - * from running into a post-eof delalloc extent. - * - * XXX: This is a temporary fix until the extent shift loop below is - * converted to use offsets and lookups within the ILOCK rather than - * carrying around the index into the extent list for the next - * iteration. - */ - error = filemap_write_and_wait(VFS_I(ip)->i_mapping); + error = xfs_free_file_space(ip, offset, len); if (error) return error; + + /* + * Trim eofblocks to avoid shifting uninitialized post-eof preallocation + * into the accessible region of the file. + */ if (xfs_can_free_eofblocks(ip, true)) { error = xfs_free_eofblocks(mp, ip, false); if (error) return error; } - error = xfs_free_file_space(ip, offset, len); + /* + * Writeback and invalidate cache for the remainder of the file as we're + * about to shift down every extent from the collapse range to EOF. The + * free of the collapse range above might have already done some of + * this, but we shouldn't rely on it to do anything outside of the range + * that was freed. + */ + error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, + offset + len, -1); + if (error) + return error; + error = invalidate_inode_pages2_range(VFS_I(ip)->i_mapping, + (offset + len) >> PAGE_CACHE_SHIFT, -1); if (error) return error; -- 1.8.3.1 From bfoster@redhat.com Wed Sep 10 08:20:38 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A1BDB7F50 for ; Wed, 10 Sep 2014 08:20:37 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 736EF304053 for ; Wed, 10 Sep 2014 06:20:34 -0700 (PDT) X-ASG-Debug-ID: 1410355232-04bdf0109a934640001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id N9uQdvPMyHNeDF5Z (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 10 Sep 2014 06:20:33 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8ADKWxQ030991 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Wed, 10 Sep 2014 09:20:32 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8ADKW38015979 for ; Wed, 10 Sep 2014 09:20:32 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 6D0721256FB; Wed, 10 Sep 2014 09:20:31 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 1/5] xfs: track collapse via file offset rather than extent index Date: Wed, 10 Sep 2014 09:20:27 -0400 X-ASG-Orig-Subj: [PATCH v2 1/5] xfs: track collapse via file offset rather than extent index Message-Id: <1410355231-50495-2-git-send-email-bfoster@redhat.com> In-Reply-To: <1410355231-50495-1-git-send-email-bfoster@redhat.com> References: <1410355231-50495-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410355233 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The collapse range implementation uses a transaction per extent shift. The progress of the overall operation is tracked via the current extent index of the in-core extent list. This is racy because the ilock must be dropped and reacquired for each transaction according to locking and log reservation rules. Therefore, writeback to prior regions of the file is possible and can change the extent count. This changes the extent to which the current index refers and causes the collapse to fail mid operation. To avoid this problem, the entire file is currently written back before the collapse operation starts. To eliminate the need to flush the entire file, use the file offset (fsb) to track the progress of the overall extent shift operation rather than the extent index. Modify xfs_bmap_shift_extents() to unconditionally convert the start_fsb parameter to an extent index and return the file offset of the extent where the shift left off, if further extents exist. The bulk of ths function can remain based on extent index as ilock is held by the caller. xfs_collapse_file_space() now uses the fsb output as the starting point for the subsequent shift. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner --- fs/xfs/libxfs/xfs_bmap.c | 85 +++++++++++++++++++++++++----------------------- fs/xfs/libxfs/xfs_bmap.h | 7 ++-- fs/xfs/xfs_bmap_util.c | 12 +++---- 3 files changed, 53 insertions(+), 51 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 86df952..4b3f1b9 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5406,20 +5406,21 @@ error0: /* * Shift extent records to the left to cover a hole. * - * The maximum number of extents to be shifted in a single operation - * is @num_exts, and @current_ext keeps track of the current extent - * index we have shifted. @offset_shift_fsb is the length by which each - * extent is shifted. If there is no hole to shift the extents - * into, this will be considered invalid operation and we abort immediately. + * The maximum number of extents to be shifted in a single operation is + * @num_exts. @start_fsb specifies the file offset to start the shift and the + * file offset where we've left off is returned in @next_fsb. @offset_shift_fsb + * is the length by which each extent is shifted. If there is no hole to shift + * the extents into, this will be considered invalid operation and we abort + * immediately. */ int xfs_bmap_shift_extents( struct xfs_trans *tp, struct xfs_inode *ip, - int *done, xfs_fileoff_t start_fsb, xfs_fileoff_t offset_shift_fsb, - xfs_extnum_t *current_ext, + int *done, + xfs_fileoff_t *next_fsb, xfs_fsblock_t *firstblock, struct xfs_bmap_free *flist, int num_exts) @@ -5431,6 +5432,7 @@ xfs_bmap_shift_extents( struct xfs_mount *mp = ip->i_mount; struct xfs_ifork *ifp; xfs_extnum_t nexts = 0; + xfs_extnum_t current_ext; xfs_fileoff_t startoff; int error = 0; int i; @@ -5451,7 +5453,8 @@ xfs_bmap_shift_extents( if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; - ASSERT(current_ext != NULL); + ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ifp = XFS_IFORK_PTR(ip, whichfork); if (!(ifp->if_flags & XFS_IFEXTENTS)) { @@ -5462,20 +5465,18 @@ xfs_bmap_shift_extents( } /* - * If *current_ext is 0, we would need to lookup the extent - * from where we would start shifting and store it in gotp. + * Look up the extent index for the fsb where we start shifting. We can + * henceforth iterate with current_ext as extent list changes are locked + * out via ilock. + * + * gotp can be null in 2 cases: 1) if there are no extents or 2) + * start_fsb lies in a hole beyond which there are no extents. Either + * way, we are done. */ - if (!*current_ext) { - gotp = xfs_iext_bno_to_ext(ifp, start_fsb, current_ext); - /* - * gotp can be null in 2 cases: 1) if there are no extents - * or 2) start_fsb lies in a hole beyond which there are - * no extents. Either way, we are done. - */ - if (!gotp) { - *done = 1; - return 0; - } + gotp = xfs_iext_bno_to_ext(ifp, start_fsb, ¤t_ext); + if (!gotp) { + *done = 1; + return 0; } if (ifp->if_flags & XFS_IFBROOT) { @@ -5487,36 +5488,32 @@ xfs_bmap_shift_extents( /* * There may be delalloc extents in the data fork before the range we - * are collapsing out, so we cannot - * use the count of real extents here. Instead we have to calculate it - * from the incore fork. + * are collapsing out, so we cannot use the count of real extents here. + * Instead we have to calculate it from the incore fork. */ total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); - while (nexts++ < num_exts && *current_ext < total_extents) { + while (nexts++ < num_exts && current_ext < total_extents) { - gotp = xfs_iext_get_ext(ifp, *current_ext); + gotp = xfs_iext_get_ext(ifp, current_ext); xfs_bmbt_get_all(gotp, &got); startoff = got.br_startoff - offset_shift_fsb; /* - * Before shifting extent into hole, make sure that the hole - * is large enough to accomodate the shift. + * Before shifting extent into hole, make sure that the hole is + * large enough to accommodate the shift. */ - if (*current_ext) { - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, - *current_ext - 1), &left); - + if (current_ext > 0) { + xfs_bmbt_get_all(xfs_iext_get_ext(ifp, current_ext - 1), + &left); if (startoff < left.br_startoff + left.br_blockcount) error = -EINVAL; } else if (offset_shift_fsb > got.br_startoff) { /* - * When first extent is shifted, offset_shift_fsb - * should be less than the stating offset of - * the first extent. + * When first extent is shifted, offset_shift_fsb should + * be less than the stating offset of the first extent. */ error = -EINVAL; } - if (error) goto del_cursor; @@ -5531,7 +5528,7 @@ xfs_bmap_shift_extents( } /* Check if we can merge 2 adjacent extents */ - if (*current_ext && + if (current_ext && left.br_startoff + left.br_blockcount == startoff && left.br_startblock + left.br_blockcount == got.br_startblock && @@ -5539,7 +5536,7 @@ xfs_bmap_shift_extents( left.br_blockcount + got.br_blockcount <= MAXEXTLEN) { blockcount = left.br_blockcount + got.br_blockcount; - xfs_iext_remove(ip, *current_ext, 1, 0); + xfs_iext_remove(ip, current_ext, 1, 0); logflags |= XFS_ILOG_CORE; if (cur) { error = xfs_btree_delete(cur, &i); @@ -5551,7 +5548,7 @@ xfs_bmap_shift_extents( } XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) - 1); - gotp = xfs_iext_get_ext(ifp, --*current_ext); + gotp = xfs_iext_get_ext(ifp, --current_ext); xfs_bmbt_get_all(gotp, &got); /* Make cursor point to the extent we will update */ @@ -5585,13 +5582,18 @@ xfs_bmap_shift_extents( logflags |= XFS_ILOG_DEXT; } - (*current_ext)++; + current_ext++; total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); } /* Check if we are done */ - if (*current_ext == total_extents) + if (current_ext == total_extents) *done = 1; + else if (next_fsb) { + gotp = xfs_iext_get_ext(ifp, current_ext); + xfs_bmbt_get_all(gotp, &got); + *next_fsb = got.br_startoff; + } del_cursor: if (cur) @@ -5600,5 +5602,6 @@ del_cursor: if (logflags) xfs_trans_log_inode(tp, ip, logflags); + return error; } diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index b879ca5..44db6db 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -178,9 +178,8 @@ int xfs_check_nostate_extents(struct xfs_ifork *ifp, xfs_extnum_t idx, xfs_extnum_t num); uint xfs_default_attroffset(struct xfs_inode *ip); int xfs_bmap_shift_extents(struct xfs_trans *tp, struct xfs_inode *ip, - int *done, xfs_fileoff_t start_fsb, - xfs_fileoff_t offset_shift_fsb, xfs_extnum_t *current_ext, - xfs_fsblock_t *firstblock, struct xfs_bmap_free *flist, - int num_exts); + xfs_fileoff_t start_fsb, xfs_fileoff_t offset_shift_fsb, + int *done, xfs_fileoff_t *next_fsb, xfs_fsblock_t *firstblock, + struct xfs_bmap_free *flist, int num_exts); #endif /* __XFS_BMAP_H__ */ diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 1707980..1e96d77 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1456,18 +1456,18 @@ xfs_collapse_file_space( struct xfs_mount *mp = ip->i_mount; struct xfs_trans *tp; int error; - xfs_extnum_t current_ext = 0; struct xfs_bmap_free free_list; xfs_fsblock_t first_block; int committed; xfs_fileoff_t start_fsb; + xfs_fileoff_t next_fsb; xfs_fileoff_t shift_fsb; ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); trace_xfs_collapse_file_space(ip); - start_fsb = XFS_B_TO_FSB(mp, offset + len); + next_fsb = XFS_B_TO_FSB(mp, offset + len); shift_fsb = XFS_B_TO_FSB(mp, len); /* @@ -1525,10 +1525,10 @@ xfs_collapse_file_space( * We are using the write transaction in which max 2 bmbt * updates are allowed */ - error = xfs_bmap_shift_extents(tp, ip, &done, start_fsb, - shift_fsb, ¤t_ext, - &first_block, &free_list, - XFS_BMAP_MAX_SHIFT_EXTENTS); + start_fsb = next_fsb; + error = xfs_bmap_shift_extents(tp, ip, start_fsb, shift_fsb, + &done, &next_fsb, &first_block, &free_list, + XFS_BMAP_MAX_SHIFT_EXTENTS); if (error) goto out; -- 1.8.3.1 From bfoster@redhat.com Wed Sep 10 08:20:37 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 8F1DC7F4E for ; Wed, 10 Sep 2014 08:20:37 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 60E15304032 for ; Wed, 10 Sep 2014 06:20:34 -0700 (PDT) X-ASG-Debug-ID: 1410355233-04bdf010a1934650001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id jJAg7RLnwAh4Lcrf (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 10 Sep 2014 06:20:33 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8ADKX0X030578 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Wed, 10 Sep 2014 09:20:33 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8ADKWYY014743 for ; Wed, 10 Sep 2014 09:20:32 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 927D0125701; Wed, 10 Sep 2014 09:20:31 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 5/5] xfs: only writeback and truncate pages for the freed range Date: Wed, 10 Sep 2014 09:20:31 -0400 X-ASG-Orig-Subj: [PATCH v2 5/5] xfs: only writeback and truncate pages for the freed range Message-Id: <1410355231-50495-6-git-send-email-bfoster@redhat.com> In-Reply-To: <1410355231-50495-1-git-send-email-bfoster@redhat.com> References: <1410355231-50495-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410355233 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xfs_free_file_space() only affects the range of the file for which space is being freed. It currently writes and truncates the page cache from the start offset of the free to EOF. Modify xfs_free_file_space() to write back and truncate page cache of just the range being freed. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner --- fs/xfs/xfs_bmap_util.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index eae763f..809ae7d 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1205,6 +1205,7 @@ xfs_free_file_space( xfs_bmap_free_t free_list; xfs_bmbt_irec_t imap; xfs_off_t ioffset; + xfs_off_t iendoffset; xfs_extlen_t mod=0; xfs_mount_t *mp; int nimap; @@ -1233,12 +1234,13 @@ xfs_free_file_space( inode_dio_wait(VFS_I(ip)); rounding = max_t(xfs_off_t, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); - ioffset = offset & ~(rounding - 1); - error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, - ioffset, -1); + ioffset = round_down(offset, rounding); + iendoffset = round_up(offset + len, rounding) - 1; + error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, ioffset, + iendoffset); if (error) goto out; - truncate_pagecache_range(VFS_I(ip), ioffset, -1); + truncate_pagecache_range(VFS_I(ip), ioffset, iendoffset); /* * Need to zero the stuff we're not freeing, on disk. -- 1.8.3.1 From bfoster@redhat.com Wed Sep 10 08:20:38 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D83E57F3F for ; Wed, 10 Sep 2014 08:20:37 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 76ED6AC007 for ; Wed, 10 Sep 2014 06:20:34 -0700 (PDT) X-ASG-Debug-ID: 1410355233-04bdf01097934640001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id qfkpCcnauXCupPYl (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 10 Sep 2014 06:20:33 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8ADKWoY007715 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Wed, 10 Sep 2014 09:20:33 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8ADKWmm015976 for ; Wed, 10 Sep 2014 09:20:32 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 5E8E3123B5C; Wed, 10 Sep 2014 09:20:31 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 2/5] xfs: refactor shift-by-merge into xfs_bmse_merge() helper Date: Wed, 10 Sep 2014 09:20:28 -0400 X-ASG-Orig-Subj: [PATCH v2 2/5] xfs: refactor shift-by-merge into xfs_bmse_merge() helper Message-Id: <1410355231-50495-3-git-send-email-bfoster@redhat.com> In-Reply-To: <1410355231-50495-1-git-send-email-bfoster@redhat.com> References: <1410355231-50495-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410355233 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The extent shift mechanism in xfs_bmap_shift_extents() is complicated and handles several different, non-deterministic scenarios. These include extent shifts, extent merges and potential btree updates in either of the former scenarios. Refactor the code to be more linear and readable. The loop logic in xfs_bmap_shift_extents() and some initial error checking is adjusted slightly. The associated btree lookup and update/delete operations are condensed into single blocks of code. This reduces the number of btree-specific blocks and facilitates the separation of the merge operation into a new xfs_bmse_merge() and xfs_bmse_can_merge() helpers. This is a code refactor only. The behavior of extent shift and collapse range is not modified. Signed-off-by: Brian Foster --- fs/xfs/libxfs/xfs_bmap.c | 242 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 167 insertions(+), 75 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 4b3f1b9..532c4aa 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5404,6 +5404,120 @@ error0: } /* + * Determine whether an extent shift can be accomplished by a merge with the + * extent that precedes the target hole of the shift. + */ +STATIC bool +xfs_bmse_can_merge( + struct xfs_bmbt_irec *left, /* preceding extent */ + struct xfs_bmbt_irec *got, /* current extent to shift */ + xfs_fileoff_t shift) /* shift fsb */ +{ + xfs_fileoff_t startoff; + + startoff = got->br_startoff - shift; + + /* + * The extent, once shifted, must be adjacent in-file and on-disk with + * the preceding extent. + */ + if ((left->br_startoff + left->br_blockcount != startoff) || + (left->br_startblock + left->br_blockcount != got->br_startblock) || + (left->br_state != got->br_state) || + (left->br_blockcount + got->br_blockcount > MAXEXTLEN)) + return false; + + return true; +} + +/* + * A bmap extent shift adjusts the file offset of an extent to fill a preceding + * hole in the file. If an extent shift would result in the extent being fully + * adjacent to the extent that currently precedes the hole, we can merge with + * the preceding extent rather than do the shift. + * + * This function assumes the caller has verified a shift-by-merge is possible + * with the provided extents via xfs_bmse_can_merge(). + */ +STATIC int +xfs_bmse_merge( + struct xfs_inode *ip, + int whichfork, + xfs_fileoff_t shift, /* shift fsb */ + int current_ext, /* idx of gotp */ + struct xfs_bmbt_rec_host *gotp, /* extent to shift */ + struct xfs_bmbt_rec_host *leftp, /* preceding extent */ + struct xfs_btree_cur *cur, + int *logflags) /* output */ +{ + struct xfs_ifork *ifp; + struct xfs_bmbt_irec got; + struct xfs_bmbt_irec left; + xfs_filblks_t blockcount; + int error, i; + + ifp = XFS_IFORK_PTR(ip, whichfork); + xfs_bmbt_get_all(gotp, &got); + xfs_bmbt_get_all(leftp, &left); + blockcount = left.br_blockcount + got.br_blockcount; + + ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); + ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); + ASSERT(xfs_bmse_can_merge(&left, &got, shift)); + + /* + * Merge the in-core extents. Note that the host record pointers and + * current_ext index are invalid once the extent has been removed via + * xfs_iext_remove(). + */ + xfs_bmbt_set_blockcount(leftp, blockcount); + xfs_iext_remove(ip, current_ext, 1, 0); + + /* + * Update the on-disk extent count, the btree if necessary and log the + * inode. + */ + XFS_IFORK_NEXT_SET(ip, whichfork, + XFS_IFORK_NEXTENTS(ip, whichfork) - 1); + *logflags |= XFS_ILOG_CORE; + if (!cur) { + *logflags |= XFS_ILOG_DEXT; + return 0; + } + + /* lookup and remove the extent to merge */ + error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock, + got.br_blockcount, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(i == 1, out_error); + + error = xfs_btree_delete(cur, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(i == 1, out_error); + + /* lookup and update size of the previous extent */ + error = xfs_bmbt_lookup_eq(cur, left.br_startoff, left.br_startblock, + left.br_blockcount, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(i == 1, out_error); + + left.br_blockcount = blockcount; + + error = xfs_bmbt_update(cur, left.br_startoff, left.br_startblock, + left.br_blockcount, left.br_state); + if (error) + goto out_error; + + return 0; + +out_error: + return error; +} + +/* * Shift extent records to the left to cover a hole. * * The maximum number of extents to be shifted in a single operation is @@ -5427,6 +5541,7 @@ xfs_bmap_shift_extents( { struct xfs_btree_cur *cur = NULL; struct xfs_bmbt_rec_host *gotp; + struct xfs_bmbt_rec_host *leftp; struct xfs_bmbt_irec got; struct xfs_bmbt_irec left; struct xfs_mount *mp = ip->i_mount; @@ -5438,7 +5553,6 @@ xfs_bmap_shift_extents( int i; int whichfork = XFS_DATA_FORK; int logflags = 0; - xfs_filblks_t blockcount = 0; int total_extents; if (unlikely(XFS_TEST_ERROR( @@ -5464,6 +5578,13 @@ xfs_bmap_shift_extents( return error; } + if (ifp->if_flags & XFS_IFBROOT) { + cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); + cur->bc_private.b.firstblock = *firstblock; + cur->bc_private.b.flist = flist; + cur->bc_private.b.flags = 0; + } + /* * Look up the extent index for the fsb where we start shifting. We can * henceforth iterate with current_ext as extent list changes are locked @@ -5476,14 +5597,17 @@ xfs_bmap_shift_extents( gotp = xfs_iext_bno_to_ext(ifp, start_fsb, ¤t_ext); if (!gotp) { *done = 1; - return 0; + goto del_cursor; } + xfs_bmbt_get_all(gotp, &got); - if (ifp->if_flags & XFS_IFBROOT) { - cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); - cur->bc_private.b.firstblock = *firstblock; - cur->bc_private.b.flist = flist; - cur->bc_private.b.flags = 0; + /* + * If the first extent is shifted, offset_shift_fsb cannot be larger + * than the starting offset of the first extent. + */ + if (current_ext == 0 && got.br_startoff < offset_shift_fsb) { + error = -EINVAL; + goto del_cursor; } /* @@ -5493,30 +5617,41 @@ xfs_bmap_shift_extents( */ total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); while (nexts++ < num_exts && current_ext < total_extents) { - - gotp = xfs_iext_get_ext(ifp, current_ext); - xfs_bmbt_get_all(gotp, &got); startoff = got.br_startoff - offset_shift_fsb; - /* - * Before shifting extent into hole, make sure that the hole is - * large enough to accommodate the shift. - */ + /* grab the left extent and check for a potential merge */ if (current_ext > 0) { - xfs_bmbt_get_all(xfs_iext_get_ext(ifp, current_ext - 1), - &left); - if (startoff < left.br_startoff + left.br_blockcount) + leftp = xfs_iext_get_ext(ifp, current_ext - 1); + xfs_bmbt_get_all(leftp, &left); + + /* make sure hole is large enough for shift */ + if (startoff < left.br_startoff + left.br_blockcount) { error = -EINVAL; - } else if (offset_shift_fsb > got.br_startoff) { - /* - * When first extent is shifted, offset_shift_fsb should - * be less than the stating offset of the first extent. - */ - error = -EINVAL; + goto del_cursor; + } + + if (xfs_bmse_can_merge(&left, &got, offset_shift_fsb)) { + error = xfs_bmse_merge(ip, whichfork, + offset_shift_fsb, current_ext, gotp, + leftp, cur, &logflags); + if (error) + goto del_cursor; + + /* + * The extent was merged so adjust the extent + * index and move onto the next. + */ + current_ext--; + goto next; + } } - if (error) - goto del_cursor; + /* + * We didn't merge the extent so do the shift. Update the start + * offset in the in-core extent and btree, if necessary. + */ + xfs_bmbt_set_startoff(gotp, startoff); + logflags |= XFS_ILOG_CORE; if (cur) { error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock, @@ -5525,53 +5660,8 @@ xfs_bmap_shift_extents( if (error) goto del_cursor; XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor); - } - - /* Check if we can merge 2 adjacent extents */ - if (current_ext && - left.br_startoff + left.br_blockcount == startoff && - left.br_startblock + left.br_blockcount == - got.br_startblock && - left.br_state == got.br_state && - left.br_blockcount + got.br_blockcount <= MAXEXTLEN) { - blockcount = left.br_blockcount + - got.br_blockcount; - xfs_iext_remove(ip, current_ext, 1, 0); - logflags |= XFS_ILOG_CORE; - if (cur) { - error = xfs_btree_delete(cur, &i); - if (error) - goto del_cursor; - XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor); - } else { - logflags |= XFS_ILOG_DEXT; - } - XFS_IFORK_NEXT_SET(ip, whichfork, - XFS_IFORK_NEXTENTS(ip, whichfork) - 1); - gotp = xfs_iext_get_ext(ifp, --current_ext); - xfs_bmbt_get_all(gotp, &got); - - /* Make cursor point to the extent we will update */ - if (cur) { - error = xfs_bmbt_lookup_eq(cur, got.br_startoff, - got.br_startblock, - got.br_blockcount, - &i); - if (error) - goto del_cursor; - XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor); - } - xfs_bmbt_set_blockcount(gotp, blockcount); - got.br_blockcount = blockcount; - } else { - /* We have to update the startoff */ - xfs_bmbt_set_startoff(gotp, startoff); got.br_startoff = startoff; - } - - logflags |= XFS_ILOG_CORE; - if (cur) { error = xfs_bmbt_update(cur, got.br_startoff, got.br_startblock, got.br_blockcount, @@ -5582,18 +5672,20 @@ xfs_bmap_shift_extents( logflags |= XFS_ILOG_DEXT; } - current_ext++; +next: + /* update total extent count and grab the next record */ total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); + if (++current_ext >= total_extents) + break; + gotp = xfs_iext_get_ext(ifp, current_ext); + xfs_bmbt_get_all(gotp, &got); } /* Check if we are done */ if (current_ext == total_extents) *done = 1; - else if (next_fsb) { - gotp = xfs_iext_get_ext(ifp, current_ext); - xfs_bmbt_get_all(gotp, &got); + else if (next_fsb) *next_fsb = got.br_startoff; - } del_cursor: if (cur) -- 1.8.3.1 From bfoster@redhat.com Wed Sep 10 08:20:39 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6BE4E7F58 for ; Wed, 10 Sep 2014 08:20:38 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id CF63AAC00A for ; Wed, 10 Sep 2014 06:20:34 -0700 (PDT) X-ASG-Debug-ID: 1410355233-04cb6c5500990140001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 46w0l9aFg2sVLoeI (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 10 Sep 2014 06:20:33 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8ADKWBe001676 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Wed, 10 Sep 2014 09:20:32 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8ADKW3Z015982 for ; Wed, 10 Sep 2014 09:20:32 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 860BF12570E; Wed, 10 Sep 2014 09:20:31 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 3/5] xfs: refactor single extent shift into xfs_bmse_shift_one() helper Date: Wed, 10 Sep 2014 09:20:29 -0400 X-ASG-Orig-Subj: [PATCH v2 3/5] xfs: refactor single extent shift into xfs_bmse_shift_one() helper Message-Id: <1410355231-50495-4-git-send-email-bfoster@redhat.com> In-Reply-To: <1410355231-50495-1-git-send-email-bfoster@redhat.com> References: <1410355231-50495-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410355233 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xfs_bmap_shift_extents() has a variety of conditions and error checks that make the logic difficult to follow and indent heavy. Refactor the loop body of this function into a new xfs_bmse_shift_one() helper. This simplifies the error checks, eliminates index decrement on merge hack by pushing the index increment down into the helper, and makes the code more readable by reducing multiple levels of indentation. This is a code refactor only. The behavior of extent shift and collapse range is not modified. Signed-off-by: Brian Foster --- fs/xfs/libxfs/xfs_bmap.c | 164 ++++++++++++++++++++++++++--------------------- 1 file changed, 91 insertions(+), 73 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 532c4aa..69bf8d8 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5518,6 +5518,88 @@ out_error: } /* + * Shift a single extent. + */ +STATIC int +xfs_bmse_shift_one( + struct xfs_inode *ip, + int whichfork, + xfs_fileoff_t offset_shift_fsb, + int *current_ext, + struct xfs_bmbt_rec_host *gotp, + struct xfs_btree_cur *cur, + int *logflags) +{ + struct xfs_ifork *ifp; + xfs_fileoff_t startoff; + struct xfs_bmbt_rec_host *leftp; + struct xfs_bmbt_irec got; + struct xfs_bmbt_irec left; + int error; + int i; + + ifp = XFS_IFORK_PTR(ip, whichfork); + + xfs_bmbt_get_all(gotp, &got); + startoff = got.br_startoff - offset_shift_fsb; + + /* + * If this is the first extent in the file, make sure there's enough + * room at the start of the file and jump right to the shift as there's + * no left extent to merge. + */ + if (*current_ext == 0) { + if (got.br_startoff < offset_shift_fsb) + return -EINVAL; + goto shift_extent; + } + + /* grab the left extent and check for a large enough hole */ + leftp = xfs_iext_get_ext(ifp, *current_ext - 1); + xfs_bmbt_get_all(leftp, &left); + + if (startoff < left.br_startoff + left.br_blockcount) + return -EINVAL; + + /* check whether to merge the extent or shift it down */ + if (!xfs_bmse_can_merge(&left, &got, offset_shift_fsb)) + goto shift_extent; + + return xfs_bmse_merge(ip, whichfork, offset_shift_fsb, *current_ext, + gotp, leftp, cur, logflags); + +shift_extent: + /* + * Increment the extent index for the next iteration, update the start + * offset of the in-core extent and update the btree if applicable. + */ + (*current_ext)++; + xfs_bmbt_set_startoff(gotp, startoff); + *logflags |= XFS_ILOG_CORE; + if (!cur) { + *logflags |= XFS_ILOG_DEXT; + return 0; + } + + error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock, + got.br_blockcount, &i); + if (error) + return error; + XFS_WANT_CORRUPTED_GOTO(i == 1, out_error); + + got.br_startoff = startoff; + error = xfs_bmbt_update(cur, got.br_startoff, got.br_startblock, + got.br_blockcount, got.br_state); + if (error) + return error; + + return 0; + +out_error: + return error; +} + +/* * Shift extent records to the left to cover a hole. * * The maximum number of extents to be shifted in a single operation is @@ -5541,16 +5623,12 @@ xfs_bmap_shift_extents( { struct xfs_btree_cur *cur = NULL; struct xfs_bmbt_rec_host *gotp; - struct xfs_bmbt_rec_host *leftp; struct xfs_bmbt_irec got; - struct xfs_bmbt_irec left; struct xfs_mount *mp = ip->i_mount; struct xfs_ifork *ifp; xfs_extnum_t nexts = 0; xfs_extnum_t current_ext; - xfs_fileoff_t startoff; int error = 0; - int i; int whichfork = XFS_DATA_FORK; int logflags = 0; int total_extents; @@ -5599,16 +5677,6 @@ xfs_bmap_shift_extents( *done = 1; goto del_cursor; } - xfs_bmbt_get_all(gotp, &got); - - /* - * If the first extent is shifted, offset_shift_fsb cannot be larger - * than the starting offset of the first extent. - */ - if (current_ext == 0 && got.br_startoff < offset_shift_fsb) { - error = -EINVAL; - goto del_cursor; - } /* * There may be delalloc extents in the data fork before the range we @@ -5617,75 +5685,25 @@ xfs_bmap_shift_extents( */ total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); while (nexts++ < num_exts && current_ext < total_extents) { - startoff = got.br_startoff - offset_shift_fsb; - - /* grab the left extent and check for a potential merge */ - if (current_ext > 0) { - leftp = xfs_iext_get_ext(ifp, current_ext - 1); - xfs_bmbt_get_all(leftp, &left); - - /* make sure hole is large enough for shift */ - if (startoff < left.br_startoff + left.br_blockcount) { - error = -EINVAL; - goto del_cursor; - } - - if (xfs_bmse_can_merge(&left, &got, offset_shift_fsb)) { - error = xfs_bmse_merge(ip, whichfork, - offset_shift_fsb, current_ext, gotp, - leftp, cur, &logflags); - if (error) - goto del_cursor; - - /* - * The extent was merged so adjust the extent - * index and move onto the next. - */ - current_ext--; - goto next; - } - } - - /* - * We didn't merge the extent so do the shift. Update the start - * offset in the in-core extent and btree, if necessary. - */ - xfs_bmbt_set_startoff(gotp, startoff); - logflags |= XFS_ILOG_CORE; - if (cur) { - error = xfs_bmbt_lookup_eq(cur, got.br_startoff, - got.br_startblock, - got.br_blockcount, - &i); - if (error) - goto del_cursor; - XFS_WANT_CORRUPTED_GOTO(i == 1, del_cursor); - - got.br_startoff = startoff; - error = xfs_bmbt_update(cur, got.br_startoff, - got.br_startblock, - got.br_blockcount, - got.br_state); - if (error) - goto del_cursor; - } else { - logflags |= XFS_ILOG_DEXT; - } + error = xfs_bmse_shift_one(ip, whichfork, offset_shift_fsb, + ¤t_ext, gotp, cur, &logflags); + if (error) + goto del_cursor; -next: /* update total extent count and grab the next record */ total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); - if (++current_ext >= total_extents) + if (current_ext >= total_extents) break; gotp = xfs_iext_get_ext(ifp, current_ext); - xfs_bmbt_get_all(gotp, &got); } /* Check if we are done */ - if (current_ext == total_extents) + if (current_ext == total_extents) { *done = 1; - else if (next_fsb) + } else if (next_fsb) { + xfs_bmbt_get_all(gotp, &got); *next_fsb = got.br_startoff; + } del_cursor: if (cur) -- 1.8.3.1 From eflorac@intellique.com Wed Sep 10 09:24:12 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 58F117F3F for ; Wed, 10 Sep 2014 09:24:12 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4746A304059 for ; Wed, 10 Sep 2014 07:24:12 -0700 (PDT) X-ASG-Debug-ID: 1410359050-04cbb05485c987a0001-NocioJ Received: from mail1.g1.pair.com (mail1.g1.pair.com [66.39.3.162]) by cuda.sgi.com with ESMTP id B4d30FUkwa6W9Kzl (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 10 Sep 2014 07:24:10 -0700 (PDT) X-Barracuda-Envelope-From: eflorac@intellique.com X-Barracuda-Apparent-Source-IP: 66.39.3.162 Received: from localhost (localhost [127.0.0.1]) by mail1.g1.pair.com (Postfix) with SMTP id 6960D2C6B2; Wed, 10 Sep 2014 10:24:10 -0400 (EDT) Received: from harpe.intellique.com (labo.djinux.com [82.225.196.72]) by mail1.g1.pair.com (Postfix) with ESMTPSA id F0CB72C32A; Wed, 10 Sep 2014 10:24:07 -0400 (EDT) Date: Wed, 10 Sep 2014 16:24:11 +0200 From: Emmanuel Florac To: Leslie Rhorer Cc: Roger Willcocks , Sean Caron , Eric Sandeen , "xfs@oss.sgi.com" Subject: Re: Corrupted files Message-ID: <20140910162411.07ef02a5@harpe.intellique.com> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: <540FA9DB.20000@mygrande.net> References: <540F1B01.3020700@mygrande.net> <540F7E37.7020500@sandeen.net> <540F9FE9.7070500@mygrande.net> <3E40936B-A1F2-424D-B0B3-54B6C7B50B13@filmlight.ltd.uk> <540FA9DB.20000@mygrande.net> Organization: Intellique X-Mailer: Claws Mail 3.10.0 (GTK+ 2.24.20; i486-slackware-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail1.g1.pair.com[66.39.3.162] X-Barracuda-Start-Time: 1410359050 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9341 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Le Tue, 09 Sep 2014 20:31:07 -0500 Leslie Rhorer =C3=A9crivait: > More=20 > importantly, is there some reason 3.1.7 would make things worse while=20 > 3.2.1 would not? If not, then I can always try 3.1.7 and then try > 3.2.1 if that does not help. I don't know for these particular versions, however in the past I've confirmed that a later version of xfs_repair performed way better (salvaged more files from lost+found, in particular). At some point in the distant past, some versions of xfs_repair were buggy and would happily throw away TB of perfectly sane data... Ih ad this very problem once on Christmas eve in 2005 IIRC :/ --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From debbugs@buxtehude.debian.org Wed Sep 10 09:24:13 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=3.0 required=5.0 tests=TVD_SUBJ_NUM_OBFU_MINFP autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 3D2757F3F for ; Wed, 10 Sep 2014 09:24:13 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2B24C304059 for ; Wed, 10 Sep 2014 07:24:13 -0700 (PDT) X-ASG-Debug-ID: 1410359048-04cbb05486c987a0001-NocioJ Received: from buxtehude.debian.org (buxtehude.debian.org [140.211.166.26]) by cuda.sgi.com with ESMTP id lI26uLfCSW10cjcD (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO) for ; Wed, 10 Sep 2014 07:24:08 -0700 (PDT) X-Barracuda-Envelope-From: debbugs@buxtehude.debian.org X-Barracuda-Apparent-Source-IP: 140.211.166.26 Received: from debbugs by buxtehude.debian.org with local (Exim 4.80) (envelope-from ) id 1XRioX-00084C-Jx; Wed, 10 Sep 2014 14:24:05 +0000 X-Loop: owner@bugs.debian.org Subject: Bug#757455: please run dh_autoreconf or manually update m4/libtool.m4 for ppc64el Reply-To: Andreas Barth , 757455@bugs.debian.org X-ASG-Orig-Subj: Bug#757455: please run dh_autoreconf or manually update m4/libtool.m4 for ppc64el Resent-From: Andreas Barth Resent-To: debian-bugs-dist@lists.debian.org Resent-Cc: XFS Development Team X-Loop: owner@bugs.debian.org Resent-Date: Wed, 10 Sep 2014 14:24:02 +0000 Resent-Message-ID: X-Debian-PR-Message: followup 757455 X-Debian-PR-Package: src:xfsprogs X-Debian-PR-Keywords: X-Debian-PR-Source: xfsprogs Received: via spool by 757455-submit@bugs.debian.org id=B757455.141035895430667 (code B ref 757455); Wed, 10 Sep 2014 14:24:02 +0000 Received: (at 757455) by bugs.debian.org; 10 Sep 2014 14:22:34 +0000 Received: from alius.ayous.org ([89.238.89.44]) by buxtehude.debian.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.80) (envelope-from ) id 1XRin3-0007yN-VO for 757455@bugs.debian.org; Wed, 10 Sep 2014 14:22:34 +0000 Received: from eos.turmzimmer.net ([2001:a60:f006:aba::1]) by alius.turmzimmer.net with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.72) (envelope-from ) id 1XRin1-00085Z-OI; Wed, 10 Sep 2014 14:22:31 +0000 Received: from aba by eos.turmzimmer.net with local (Exim 4.69) (envelope-from ) id 1XRimw-0008LL-ET; Wed, 10 Sep 2014 16:22:26 +0200 Date: Wed, 10 Sep 2014 16:22:26 +0200 From: Andreas Barth To: Matthias Klose , 757455@bugs.debian.org Message-ID: <20140910142226.GA32059@mails.so.argh.org> References: <53E4C0A5.8060704@debian.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <53E4C0A5.8060704@debian.org> X-Editor: Vim http://www.vim.org/ User-Agent: Mutt/1.5.18 (2008-05-17) X-Barracuda-Connect: buxtehude.debian.org[140.211.166.26] X-Barracuda-Start-Time: 1410359048 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9341 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- * Matthias Klose (doko@debian.org) [140910 14:19]: > trying to use dh_autoreconf: It works with the following patch: diff -ur xfsprogs-3.2.1~/debian/control xfsprogs-3.2.1/debian/control --- xfsprogs-3.2.1~/debian/control 2014-05-02 00:09:15.000000000 +0000 +++ xfsprogs-3.2.1/debian/control 2014-09-10 14:14:34.026319172 +0000 @@ -3,7 +3,7 @@ Priority: optional Maintainer: XFS Development Team Uploaders: Nathan Scott , Anibal Monsalve Salazar -Build-Depends: uuid-dev, autoconf, debhelper (>= 5), gettext, libtool, libreadline-gplv2-dev | libreadline5-dev, libblkid-dev (>= 2.17), linux-libc-dev, autotools-dev +Build-Depends: uuid-dev, dh-autoreconf, debhelper (>= 5), gettext, libtool, libreadline-gplv2-dev | libreadline5-dev, libblkid-dev (>= 2.17), linux-libc-dev Standards-Version: 3.9.1 Homepage: http://oss.sgi.com/projects/xfs/ diff -ur xfsprogs-3.2.1~/debian/rules xfsprogs-3.2.1/debian/rules --- xfsprogs-3.2.1~/debian/rules 2014-05-02 00:09:15.000000000 +0000 +++ xfsprogs-3.2.1/debian/rules 2014-09-10 14:13:18.182294515 +0000 @@ -35,7 +35,7 @@ .census: @echo "== dpkg-buildpackage: configure" 1>&2 $(checkdir) - dh_autotools-dev_updateconfig + AUTOHEADER=/bin/true dh_autoreconf $(options) $(MAKE) include/platform_defs.h touch .census @@ -58,7 +58,7 @@ $(MAKE) distclean -rm -rf $(dirme) $(dirdev) $(dirdi) -rm -f debian/*substvars debian/files* debian/*.debhelper - dh_autotools-dev_restoreconfig + dh_autoreconf_clean dh_clean binary-indep: As this package is required to build ceph, libvirt and redhat-cluster I'd be willing to help fixing it, if required also by an NMU. Unless there is a reason why not, I intend to upload the fix within the next days. Andi From eflorac@intellique.com Wed Sep 10 09:31:27 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 333327F3F for ; Wed, 10 Sep 2014 09:31:27 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id C4CB5AC005 for ; Wed, 10 Sep 2014 07:31:23 -0700 (PDT) X-ASG-Debug-ID: 1410359481-04bdf010a09373f0001-NocioJ Received: from mail1.g1.pair.com (mail1.g1.pair.com [66.39.3.162]) by cuda.sgi.com with ESMTP id pwXfqXRKhWCPVaEi (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 10 Sep 2014 07:31:22 -0700 (PDT) X-Barracuda-Envelope-From: eflorac@intellique.com X-Barracuda-Apparent-Source-IP: 66.39.3.162 Received: from localhost (localhost [127.0.0.1]) by mail1.g1.pair.com (Postfix) with SMTP id AD8FD2C95D; Wed, 10 Sep 2014 10:31:21 -0400 (EDT) Received: from harpe.intellique.com (labo.djinux.com [82.225.196.72]) by mail1.g1.pair.com (Postfix) with ESMTPSA id 3DE922CE0E; Wed, 10 Sep 2014 10:31:20 -0400 (EDT) Date: Wed, 10 Sep 2014 16:31:24 +0200 From: Emmanuel Florac To: Leslie Rhorer Cc: Sean Caron , "xfs@oss.sgi.com" Subject: Re: Corrupted files Message-ID: <20140910163124.3d879432@harpe.intellique.com> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: <540FACAC.3010504@mygrande.net> References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> <540FACAC.3010504@mygrande.net> Organization: Intellique X-Mailer: Claws Mail 3.10.0 (GTK+ 2.24.20; i486-slackware-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail1.g1.pair.com[66.39.3.162] X-Barracuda-Start-Time: 1410359482 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9341 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Le Tue, 09 Sep 2014 20:43:08 -0500 Leslie Rhorer =C3=A9crivait: > None of the failed drives were WD green. All three and the > previous four were Seagate. I realize that is not a large > statistical sample. >=20 If you're interested in large statistical samples, on a grand total of 4000 1 TB Seagate Barracuda ES2, I had to replace 2100 of them over the course of 3 years. I still have a couple of hundred of these unfortunate pieces of crap in service, and they still represent the vast majority of unexpected RAID malfunctions, urgent replacements, late night calls and other "interesting side activities". I wouldn't buy anything labeled Seagate nowadays. Their drives have been the baddest train wreck since the dreaded 9 GB Micropolis back in 1994 (or was it 1995?). --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From eflorac@intellique.com Wed Sep 10 09:34:40 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 54B6D7F4E for ; Wed, 10 Sep 2014 09:34:40 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 34CCC8F8052 for ; Wed, 10 Sep 2014 07:34:37 -0700 (PDT) X-ASG-Debug-ID: 1410359676-04cb6c5500992d30001-NocioJ Received: from mail1.g1.pair.com (mail1.g1.pair.com [66.39.3.162]) by cuda.sgi.com with ESMTP id nzTq4JYhmuEOcySv (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 10 Sep 2014 07:34:36 -0700 (PDT) X-Barracuda-Envelope-From: eflorac@intellique.com X-Barracuda-Apparent-Source-IP: 66.39.3.162 Received: from localhost (localhost [127.0.0.1]) by mail1.g1.pair.com (Postfix) with SMTP id E62EE2C958; Wed, 10 Sep 2014 10:34:35 -0400 (EDT) Received: from harpe.intellique.com (labo.djinux.com [82.225.196.72]) by mail1.g1.pair.com (Postfix) with ESMTPSA id B123A2CF69; Wed, 10 Sep 2014 10:34:33 -0400 (EDT) Date: Wed, 10 Sep 2014 16:34:38 +0200 From: Emmanuel Florac To: Leslie Rhorer Cc: Dave Chinner , xfs@oss.sgi.com Subject: Re: Corrupted files Message-ID: <20140910163438.473511ce@harpe.intellique.com> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: <540FD1EB.8070007@mygrande.net> References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> <20140910015331.GJ20518@dastard> <540FC135.8010601@mygrande.net> <20140910033331.GA27048@dastard> <540FD038.5010202@mygrande.net> <540FD1EB.8070007@mygrande.net> Organization: Intellique X-Mailer: Claws Mail 3.10.0 (GTK+ 2.24.20; i486-slackware-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail1.g1.pair.com[66.39.3.162] X-Barracuda-Start-Time: 1410359676 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9341 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Le Tue, 09 Sep 2014 23:22:03 -0500 Leslie Rhorer =C3=A9crivait: > Oops! Hold on. I didn't read that closely enough. You were > saying I only need to compile xfs-progs. That's working. >=20 You don't need to install the resulting binaries either. xfs_repair will happily run from the source directory, ./xfs_repair /dev/blah ... --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From scaron@umich.edu Wed Sep 10 09:49:34 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D79067F50 for ; Wed, 10 Sep 2014 09:49:34 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id B5A148F8049 for ; Wed, 10 Sep 2014 07:49:34 -0700 (PDT) X-ASG-Debug-ID: 1410360572-04cbb05488c998e0001-NocioJ Received: from mail-qg0-f47.google.com (mail-qg0-f47.google.com [209.85.192.47]) by cuda.sgi.com with ESMTP id f65i81D7aJFsUkwn (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Wed, 10 Sep 2014 07:49:32 -0700 (PDT) X-Barracuda-Envelope-From: scaron@umich.edu X-Barracuda-Apparent-Source-IP: 209.85.192.47 Received: by mail-qg0-f47.google.com with SMTP id i50so4734392qgf.20 for ; Wed, 10 Sep 2014 07:49:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=vi3qCc/JlqhSZeLKuxrZYVzixSvIQ6md0uBVV/Bg+RM=; b=GSPNJ95NEVvpGkix0p5Ff3X8WJOT8LmTfbwfjtHsVNHiF6yXKqSi+PowsH48xPFXli pitRnKFrLauwWH+iNbBhX0JTDinFBlcfZ8z0btrnlC6B4lfXDjCrUnEB+UJJmqT1zAXH uuWak6q3VvjwvUROWIPeh2hZARcy9cF4yBDKVO3vC8Rzg8wADA3TsxuIPfwWodxtMIHV PVxWOpQLUny3lBjNS9lRSofsCI88h+IfEOWu+t8wyMigQPiPE6z/6ymIGP8UqPscgneA YWah+PpXz/0KxNx23BHtN7obmMg2IXRU5kbzzIeO4Xk1aFlrY7QTajtq/pb2eic4hlAC sMhQ== X-Gm-Message-State: ALoCoQltgQrI8DZyDMoJONZECP4zRtK7pz779s6Twld/mi0TDB5+IzydLlxtyo+TEZUnUbj0fuLO MIME-Version: 1.0 X-Received: by 10.224.24.68 with SMTP id u4mr13597295qab.71.1410360572281; Wed, 10 Sep 2014 07:49:32 -0700 (PDT) Received: by 10.224.8.132 with HTTP; Wed, 10 Sep 2014 07:49:32 -0700 (PDT) In-Reply-To: <20140910162411.07ef02a5@harpe.intellique.com> References: <540F1B01.3020700@mygrande.net> <540F7E37.7020500@sandeen.net> <540F9FE9.7070500@mygrande.net> <3E40936B-A1F2-424D-B0B3-54B6C7B50B13@filmlight.ltd.uk> <540FA9DB.20000@mygrande.net> <20140910162411.07ef02a5@harpe.intellique.com> Date: Wed, 10 Sep 2014 10:49:32 -0400 Message-ID: Subject: Re: Corrupted files From: Sean Caron X-ASG-Orig-Subj: Re: Corrupted files To: Emmanuel Florac , Sean Caron Cc: Leslie Rhorer , Roger Willcocks , Eric Sandeen , "xfs@oss.sgi.com" Content-Type: multipart/alternative; boundary=001a11c2a30eea9ed20502b728d1 X-Barracuda-Connect: mail-qg0-f47.google.com[209.85.192.47] X-Barracuda-Start-Time: 1410360572 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9341 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message --001a11c2a30eea9ed20502b728d1 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable I don't want to bloviate too much and drag this completely off topic esp. since the OPs query is resolved but please allow me just one anecdote :) Earlier this year, I had one of our project file servers (450 TB) go down. It didn't go down because the array spuriously just lost a bunch of disks; it was simply your usual sort of Linux kernel panic... you go to the console and it's just black screen and unresponsive, or maybe you can see the tail end of a backtrace and it's unresponsive. So, OK, issue a quick remote IPMI reboot of the machine, it comes up... I'm in single user mode, bringing up each sub-RAID6 in our RAID60 by hand, no problem. Bring up the top level RAID0. OK. Then I go to mount the XFS... no go. Apparently the log somehow got corrupted in the crash? So I try to mount ro, no dice, but I _can_ mount ro,noreplaylog and I see good files here! Thank goodness. I start scavenging to a spare host... A few weeks later, after the scavenge is done, I did a few xfs_repair runs just for the sake of experimentation. Using both in dry run mode, I tried the version that shipped with Ubuntu 12.04, as well as the latest xfs_repair I could pull from the source tree. I redirected the output of both runs to file and watched them with 'tail -f'. Diffing the output when they were done, it didn't look like they were behaving much differently. Both files had thousands or tens of thousands of lines worth of output in them, bad this, bad that... (I always run in verbose mode) Since the filesystem was hosed anyway and I was going to rebuild it, I decided to let the new xfs_repair run "for real" just to see what would happen, for kicks. And who knows? Maybe I could recover even more than I already had ...? (I wasn't just totally wasting time) I think it took maybe a week for it to run on a 450 TB volume? At least a week. Maybe I was being a teensy bit hyperbolic in my previous descriptions of runtime, LOL. After it was done? ... almost everything was obliterated. I had tens of millions of zero-length files, and tens of millions of bits of anonymous scrambled junk in lost+found. So, I chuckled a bit (thankful for my hard-won previous experience) before reformatting the array and then copied back the results of my scavenging. Just by ro-mounting and copying what I could, I was able to save around 90% of the data by volume on the array (it was a little more than half full when it failed... ~290 TB? There was only ~30 TB that I couldn't salvage); good clean files that passed validation from their respective users. I think 80-90% recovery rates are very commonly achievable just mounting ro,noreplaylog and getting what you can with cp -R or rsync, given that there wasn't grievous failure of the underlying storage system. If I had depended on xfs_repair, or blithely run it as a first line of response as the documentation might intimate (hey, it's called xfs_repair, right?) like you would casually think to do; run it like people run fsck or CHKDSK... I would have been hosed, big time. Best, Sean On Wed, Sep 10, 2014 at 10:24 AM, Emmanuel Florac wrote: > Le Tue, 09 Sep 2014 20:31:07 -0500 > Leslie Rhorer =C3=A9crivait: > > > More > > importantly, is there some reason 3.1.7 would make things worse while > > 3.2.1 would not? If not, then I can always try 3.1.7 and then try > > 3.2.1 if that does not help. > > I don't know for these particular versions, however in the past > I've confirmed that a later version of xfs_repair performed way better > (salvaged more files from lost+found, in particular). > > At some point in the distant past, some versions of xfs_repair were > buggy and would happily throw away TB of perfectly sane data... Ih ad > this very problem once on Christmas eve in 2005 IIRC :/ > > -- > ------------------------------------------------------------------------ > Emmanuel Florac | Direction technique > | Intellique > | > | +33 1 78 94 84 02 > ------------------------------------------------------------------------ > --001a11c2a30eea9ed20502b728d1 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
I don't want to bloviate too much and drag this c= ompletely off topic esp. since the OPs query is resolved but please allow m= e just one anecdote :)

Earlier this year, I had one of = our project file servers (450 TB) go down. It didn't go down because th= e array spuriously just lost a bunch of disks; it was simply your usual sor= t of Linux kernel panic... you go to the console and it's just black sc= reen and unresponsive, or maybe you can see the tail end of a backtrace and= it's unresponsive. So, OK, issue a quick remote IPMI reboot of the mac= hine, it comes up...

I'm in single user mode, bringi= ng up each sub-RAID6 in our RAID60 by hand, no problem. Bring up the top le= vel RAID0. OK. Then I go to mount the XFS... no go. Apparently the log some= how got corrupted in the crash?

So I try to mount = ro, no dice, but I _can_ mount ro,noreplaylog and I see good files here! Th= ank goodness. I start scavenging to a spare host...

A few weeks later, after the scavenge is done, I did a few xfs_repair run= s just for the sake of experimentation. Using both in dry run mode, I tried= the version that shipped with Ubuntu 12.04, as well as the latest xfs_repa= ir I could pull from the source tree. I redirected the output of both runs = to file and watched them with 'tail -f'.

D= iffing the output when they were done, it didn't look like they were be= having much differently. Both files had thousands or tens of thousands of l= ines worth of output in them, bad this, bad that... (I always run in verbos= e mode) Since the filesystem was hosed anyway and I was going to rebuild it= , I decided to let the new xfs_repair run "for real" just to see = what would happen, for kicks. And who knows? Maybe I could recover even mor= e than I already had ...? (I wasn't just totally wasting time)

I think it took maybe a week for it to run on a 450 TB vol= ume? At least a week. Maybe I was being a teensy bit hyperbolic in my previ= ous descriptions of runtime, LOL. After it was done?

... almost everything was obliterated. I had tens of millions of zero-le= ngth files, and tens of millions of bits of anonymous scrambled junk in los= t+found.

So, I chuckled a bit (thankful for my har= d-won previous experience) before reformatting the array and then copied ba= ck the results of my scavenging. Just by ro-mounting and copying what I cou= ld, I was able to save around 90% of the data by volume on the array (it wa= s a little more than half full when it failed... ~290 TB? There was only ~3= 0 TB that I couldn't salvage); good clean files that passed validation = from their respective users. I think 80-90% recovery rates are very commonl= y achievable just mounting ro,noreplaylog and getting what you can with cp = -R or rsync, given that there wasn't grievous failure of the underlying= storage system.

If I had depended on xfs_repair, = or blithely run it as a first line of response as the documentation might i= ntimate (hey, it's called xfs_repair, right?) like you would casually t= hink to do; run it like people run fsck or CHKDSK... I would have been hose= d, big time.=C2=A0

Best,

= Sean




=


On Wed, Sep 10, 2014 at 10:24 AM, Emmanuel Florac <ef= lorac@intellique.com> wrote:
lrhorer@mygrande.= net> =C3=A9crivait:

> More
> importantly, is there some reason 3.1.7 would make things worse while<= br> > 3.2.1 would not?=C2=A0 If not, then I can always try 3.1.7 and then tr= y
> 3.2.1 if that does not help.

I don't know for these particular versions, however in the past<= br> I've confirmed that a later version of xfs_repair performed way better<= br> (salvaged more files from lost+found, in particular).

At some point in the distant past, some versions of xfs_repair were
buggy and would happily throw away TB of perfectly sane data... Ih ad
this very problem once on Christmas eve in 2005 IIRC :/

--
------------------------------------------------------------------------ Emmanuel Florac=C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A0Direction technique
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2= =A0 =C2=A0Intellique
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2= =A0 =C2=A0<eflorac@intellique.= com>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2= =A0 =C2=A0+33 1 78 94 84 02
------------------------------------------------------------------------

--001a11c2a30eea9ed20502b728d1-- From neutrino8@gmail.com Wed Sep 10 09:52:30 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.3 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 3CB4A7F50 for ; Wed, 10 Sep 2014 09:52:30 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 29B60304048 for ; Wed, 10 Sep 2014 07:52:30 -0700 (PDT) X-ASG-Debug-ID: 1410360747-04cb6c54fd993ac0001-NocioJ Received: from mail-ig0-f177.google.com (mail-ig0-f177.google.com [209.85.213.177]) by cuda.sgi.com with ESMTP id 7oG2SzH1MkGnj8iq (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Wed, 10 Sep 2014 07:52:27 -0700 (PDT) X-Barracuda-Envelope-From: neutrino8@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.213.177 X-Barracuda-IPDD: Level1 [gmail.com/209.85.213.177] Received: by mail-ig0-f177.google.com with SMTP id uq10so3121986igb.4 for ; Wed, 10 Sep 2014 07:52:27 -0700 (PDT) X-Barracuda-IPDD: Level1 [gmail.com/209.85.213.177] X-Barracuda-IPDD: Level1 [gmail.com/209.85.213.177] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; bh=vk2dPPv1zSmJhk70ijVhJSqlIjSlZig2YklQB0UrYic=; b=VrU23j6ipqvcZqdTt4GWSEYOVkHDfc+X1acm2P7+p1krj5Jcitc9QQY9fCJa8vZc+3 QQ1puuGcSiMxnywxp+edwzwnMPK+7mhz3LdEaXNjxu6Zfazg+CFiW0B71WEXIo/evbqP Gc5tISlJsmb9TnqXVXmuwZtQdL7FeJZVzhb19AG4SANlq2xbdSdEJ7UG0pajZ+FdIdRt GMLNCy7mEOvMWPE1yiTbMGbXWj3iQQCE04NVDIkjNBwenDKd2t3wcWj9XgJWueR9onQf 2GhAto/HcOseSFtPdjaunzycD2A0q17PPFnC93YuHO26CQyPgQpDO1vWTuFaGLTnHsdH +yuw== MIME-Version: 1.0 X-Received: by 10.43.158.195 with SMTP id lv3mr46728564icc.30.1410360747133; Wed, 10 Sep 2014 07:52:27 -0700 (PDT) Received: by 10.50.215.163 with HTTP; Wed, 10 Sep 2014 07:52:27 -0700 (PDT) In-Reply-To: <20140910163124.3d879432@harpe.intellique.com> References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> <540FACAC.3010504@mygrande.net> <20140910163124.3d879432@harpe.intellique.com> Date: Wed, 10 Sep 2014 16:52:27 +0200 Message-ID: Subject: Re: Corrupted files From: Grozdan X-ASG-Orig-Subj: Re: Corrupted files To: Emmanuel Florac Cc: Leslie Rhorer , Sean Caron , "xfs@oss.sgi.com" Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail-ig0-f177.google.com[209.85.213.177] X-Barracuda-Start-Time: 1410360747 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9341 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Wed, Sep 10, 2014 at 4:31 PM, Emmanuel Florac w= rote: > Le Tue, 09 Sep 2014 20:43:08 -0500 > Leslie Rhorer =C3=A9crivait: > >> None of the failed drives were WD green. All three and the >> previous four were Seagate. I realize that is not a large >> statistical sample. >> > > If you're interested in large statistical samples, on a grand total of > 4000 1 TB Seagate Barracuda ES2, I had to replace 2100 of them over the > course of 3 years. I still have a couple of hundred of these > unfortunate pieces of crap in service, and they still represent the > vast majority of unexpected RAID malfunctions, urgent replacements, > late night calls and other "interesting side activities". > > I wouldn't buy anything labeled Seagate nowadays. Their drives have > been the baddest train wreck since the dreaded 9 GB Micropolis back in > 1994 (or was it 1995?). Funny, because our server (105 of them) all run on Seagate drives a few years now and I have yet to see one fail or cause other problems. But then again, we use Constellation disks, not Barracuda's. At home I also use both Barracuda's and Constellation ones and also have yet to see a problem with them. > > -- > ------------------------------------------------------------------------ > Emmanuel Florac | Direction technique > | Intellique > | > | +33 1 78 94 84 02 > ------------------------------------------------------------------------ > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs --=20 Yours truly From scaron@umich.edu Wed Sep 10 09:54:37 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2021B7F54 for ; Wed, 10 Sep 2014 09:54:37 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0B4D98F8054 for ; Wed, 10 Sep 2014 07:54:37 -0700 (PDT) X-ASG-Debug-ID: 1410360874-04cbb05486c99d50001-NocioJ Received: from mail-qa0-f54.google.com (mail-qa0-f54.google.com [209.85.216.54]) by cuda.sgi.com with ESMTP id MraEkymU1xd91lE0 (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Wed, 10 Sep 2014 07:54:34 -0700 (PDT) X-Barracuda-Envelope-From: scaron@umich.edu X-Barracuda-Apparent-Source-IP: 209.85.216.54 Received: by mail-qa0-f54.google.com with SMTP id x12so17694239qac.27 for ; Wed, 10 Sep 2014 07:54:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=Dj2DfYtvFUOLJg636U6zS598Newt5ubAxfp8DMzvg4Q=; b=ZR/uVUCk8UCbCEGvPaS8vkF3idVglSwm4LWvQFV9oxxGC5HwYKGdFY8KR55FyOMaMX FeFBkgSWnycodM4pGnUNEHc3ZvkAbwJ6iHM5JblBKOrbbFLPuZ/S7k0FE73GoBKxaiOT LOYKJn0ubHF/QMpEss1ytnhskqQQzzbhWf2c7+0b1UqvLGmleX/utp/om6t3Jt9nmQ/0 ljWvQ/uPN3ktWK3hWwQxsWTU63TDPFx2yv45viX/sZerMEYHWzIG0EThLkkX6rx9pkQy TEGTYKhNdb8jyMLYwUIIqCvFoewRhn8E+gqcxA21+AxHhr0U3NDyPBY29au1Z+91s32V E4UQ== X-Gm-Message-State: ALoCoQkT/MDBD6YWrkGeWN8twLqit07aLmWu5rOKi5siUMbe7ljxNMA3Z+H/kaJ01zJcAQQEDlRW MIME-Version: 1.0 X-Received: by 10.224.167.72 with SMTP id p8mr62056885qay.62.1410360873831; Wed, 10 Sep 2014 07:54:33 -0700 (PDT) Received: by 10.224.8.132 with HTTP; Wed, 10 Sep 2014 07:54:33 -0700 (PDT) In-Reply-To: <20140910163124.3d879432@harpe.intellique.com> References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> <540FACAC.3010504@mygrande.net> <20140910163124.3d879432@harpe.intellique.com> Date: Wed, 10 Sep 2014 10:54:33 -0400 Message-ID: Subject: Re: Corrupted files From: Sean Caron X-ASG-Orig-Subj: Re: Corrupted files To: Emmanuel Florac , Sean Caron Cc: Leslie Rhorer , "xfs@oss.sgi.com" Content-Type: multipart/alternative; boundary=089e0149c46ee3e15b0502b73a95 X-Barracuda-Connect: mail-qa0-f54.google.com[209.85.216.54] X-Barracuda-Start-Time: 1410360874 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9341 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message --089e0149c46ee3e15b0502b73a95 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable I am probably overseeing a similar number (3-4000) of Hitachi A7K3000s, A7K2000s and WDC RE4s and I probably see a few failures a month. When we are building a new machine and we get a fresh shipment in, maybe 10% failure rate right out of the box. Those that survive the burn-in usually do pretty good. Man, you have my sympathy with that failure rate in excess of 50%... even the WDC Greens weren't THAT bad (although it probably got close, as we neared closer and closer to EOLing them... and they had been moved to third-tier "backup storage" status by that point). Thankfully they are gone now, LOL. You're right, esp. in large installations, it's critical to do your homework on drives, pick a good candidate, validate it and then run with them. Even with the good ones, you've gotta keep a watchful eye... "when you buy them in bulk, they fail in bulk". Best, Sean On Wed, Sep 10, 2014 at 10:31 AM, Emmanuel Florac wrote: > Le Tue, 09 Sep 2014 20:43:08 -0500 > Leslie Rhorer =C3=A9crivait: > > > None of the failed drives were WD green. All three and the > > previous four were Seagate. I realize that is not a large > > statistical sample. > > > > If you're interested in large statistical samples, on a grand total of > 4000 1 TB Seagate Barracuda ES2, I had to replace 2100 of them over the > course of 3 years. I still have a couple of hundred of these > unfortunate pieces of crap in service, and they still represent the > vast majority of unexpected RAID malfunctions, urgent replacements, > late night calls and other "interesting side activities". > > I wouldn't buy anything labeled Seagate nowadays. Their drives have > been the baddest train wreck since the dreaded 9 GB Micropolis back in > 1994 (or was it 1995?). > > -- > ------------------------------------------------------------------------ > Emmanuel Florac | Direction technique > | Intellique > | > | +33 1 78 94 84 02 > ------------------------------------------------------------------------ > --089e0149c46ee3e15b0502b73a95 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
I am probably overseeing a similar number (3-4000) of Hita= chi A7K3000s, A7K2000s and WDC RE4s and I probably see a few failures a mon= th. When we are building a new machine and we get a fresh shipment in, mayb= e 10% failure rate right out of the box. Those that survive the burn-in usu= ally do pretty good. Man, you have my sympathy with that failure rate in ex= cess of 50%... even the WDC Greens weren't THAT bad (although it probab= ly got close, as we neared closer and closer to EOLing them... and they had= been moved to third-tier "backup storage" status by that point).= Thankfully they are gone now, LOL.

You're right, es= p. in large installations, it's critical to do your homework on drives,= pick a good candidate, validate it and then run with them. Even with the g= ood ones, you've gotta keep a watchful eye... "when you buy them i= n bulk, they fail in bulk".

Best,
<= br>Sean



On Wed, Sep 10, 2014 at 10:31 AM, Emmanuel = Florac <eflorac@intellique.com> wrote:
Le Tue, 09 Sep 2014 20:43:08 -0500
Leslie Rhorer <lrhorer@mygrande.= net> =C3=A9crivait:

>=C2=A0 =C2=A0 =C2=A0 =C2=A0None of the failed drives were WD green.=C2= =A0 All three and the
> previous four were Seagate.=C2=A0 I realize that is not a large
> statistical sample.
>

If you're interested in large statistical samples, on a grand to= tal of
4000 1 TB Seagate Barracuda ES2, I had to replace 2100 of them over the
course of 3 years. I still have a couple of hundred of these
unfortunate pieces of crap in service, and they still represent the
vast majority of unexpected RAID malfunctions, urgent replacements,
late night calls and other "interesting side activities".

I wouldn't buy anything labeled Seagate nowadays. Their drives have
been the baddest train wreck since the dreaded 9 GB Micropolis back in
1994 (or was it 1995?).

--
------------------------------------------------------------------------ Emmanuel Florac=C2=A0 =C2=A0 =C2=A0|=C2=A0 =C2=A0Direction technique
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2= =A0 =C2=A0Intellique
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2= =A0 =C2=A0<eflorac@intellique.= com>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2= =A0 =C2=A0+33 1 78 94 84 02
------------------------------------------------------------------------

--089e0149c46ee3e15b0502b73a95-- From eflorac@intellique.com Wed Sep 10 10:12:10 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 530777F3F for ; Wed, 10 Sep 2014 10:12:10 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 3258930405F for ; Wed, 10 Sep 2014 08:12:07 -0700 (PDT) X-ASG-Debug-ID: 1410361926-04cbb05486c9a860001-NocioJ Received: from mail1.g1.pair.com (mail1.g1.pair.com [66.39.3.162]) by cuda.sgi.com with ESMTP id U1VGkBss3EpsvxT2 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 10 Sep 2014 08:12:06 -0700 (PDT) X-Barracuda-Envelope-From: eflorac@intellique.com X-Barracuda-Apparent-Source-IP: 66.39.3.162 Received: from localhost (localhost [127.0.0.1]) by mail1.g1.pair.com (Postfix) with SMTP id E118428B74; Wed, 10 Sep 2014 11:12:05 -0400 (EDT) Received: from harpe.intellique.com (labo.djinux.com [82.225.196.72]) by mail1.g1.pair.com (Postfix) with ESMTPSA id 159582CA0A; Wed, 10 Sep 2014 11:12:03 -0400 (EDT) Date: Wed, 10 Sep 2014 17:12:08 +0200 From: Emmanuel Florac To: Grozdan Cc: Leslie Rhorer , Sean Caron , "xfs@oss.sgi.com" Subject: Re: Corrupted files Message-ID: <20140910171208.4b38807c@harpe.intellique.com> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> <540FACAC.3010504@mygrande.net> <20140910163124.3d879432@harpe.intellique.com> Organization: Intellique X-Mailer: Claws Mail 3.10.0 (GTK+ 2.24.20; i486-slackware-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail1.g1.pair.com[66.39.3.162] X-Barracuda-Start-Time: 1410361926 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9341 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Le Wed, 10 Sep 2014 16:52:27 +0200 Grozdan =C3=A9crivait: > Funny, because our server (105 of them) all run on Seagate drives a > few years now and I have yet to see one fail or cause other problems. > But then again, we use Constellation disks, not Barracuda's. At home I > also use both Barracuda's and Constellation ones and also have yet to > see a problem with them. >=20 Yes, we replaced most failed Barracudas with Constellations at a later stage (because the "certified repaired" Barracudas aren't any better... ) and these work fine so far. However, why would I give Seagate my hard-earned money after they cost me so dearly for years? :) --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From neutrino8@gmail.com Wed Sep 10 10:32:19 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.3 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id C8AD17F57 for ; Wed, 10 Sep 2014 10:32:19 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 81421304051 for ; Wed, 10 Sep 2014 08:32:19 -0700 (PDT) X-ASG-Debug-ID: 1410363138-04bdf01097939e70001-NocioJ Received: from mail-ie0-f175.google.com (mail-ie0-f175.google.com [209.85.223.175]) by cuda.sgi.com with ESMTP id 475PQg80C0g52eTU (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Wed, 10 Sep 2014 08:32:18 -0700 (PDT) X-Barracuda-Envelope-From: neutrino8@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.223.175 X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.175] Received: by mail-ie0-f175.google.com with SMTP id at20so2360544iec.20 for ; Wed, 10 Sep 2014 08:32:17 -0700 (PDT) X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.175] X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.175] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; bh=vvqOU3frlDZPTKqok4mpZtdZRi1SNw29lK7R2V1Bp28=; b=w7PSYkdFH96qQ90IFHaqhsUcJiSnwHPGLzbFPiRDGEnS8KK5xoxzHBIEV6/RJN28oG IJTpl8KlJeJ+9yof1zEUvRczgb/DUFZqmuydlnzNmQxP94vJ6hM/m/RnNk1FEkv5NeCP 0rHkp/oDB5xlnm45jrFd+keCZLLej8uBaUohxEvuBBIXnf2CjBedJoIJRMjnW15wDHe4 Ba6GkEcdVNaVKngKQD3YwAOnU7SbjOueuWtdEsRD0JoS9RyKieNDSwJcNPoCZUw3r3XT fyzaG8v+EIra1C7l+e46+xEovSleXJBJ8invGgCyUkz4o6SUslBcUq2M5tY44YgCRfoh bbhw== MIME-Version: 1.0 X-Received: by 10.50.33.16 with SMTP id n16mr755451igi.15.1410363137890; Wed, 10 Sep 2014 08:32:17 -0700 (PDT) Received: by 10.50.215.163 with HTTP; Wed, 10 Sep 2014 08:32:17 -0700 (PDT) In-Reply-To: <20140910171208.4b38807c@harpe.intellique.com> References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> <540FACAC.3010504@mygrande.net> <20140910163124.3d879432@harpe.intellique.com> <20140910171208.4b38807c@harpe.intellique.com> Date: Wed, 10 Sep 2014 17:32:17 +0200 Message-ID: Subject: Re: Corrupted files From: Grozdan X-ASG-Orig-Subj: Re: Corrupted files To: Emmanuel Florac Cc: Leslie Rhorer , Sean Caron , "xfs@oss.sgi.com" Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail-ie0-f175.google.com[209.85.223.175] X-Barracuda-Start-Time: 1410363138 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9342 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Wed, Sep 10, 2014 at 5:12 PM, Emmanuel Florac w= rote: > Le Wed, 10 Sep 2014 16:52:27 +0200 > Grozdan =C3=A9crivait: > >> Funny, because our server (105 of them) all run on Seagate drives a >> few years now and I have yet to see one fail or cause other problems. >> But then again, we use Constellation disks, not Barracuda's. At home I >> also use both Barracuda's and Constellation ones and also have yet to >> see a problem with them. >> > > Yes, we replaced most failed Barracudas with Constellations at a > later stage (because the "certified repaired" Barracudas aren't any > better... ) and these work fine so far. However, why would I give > Seagate my hard-earned money after they cost me so dearly for years? :) Oh, you are correct about the money. If it happened to us I'll also think twice about that too. The biggest problems thus far we had were with Samsung disks. I haven't seen such a high fail rate in all my life. About 70% of the 100 disks we got failed within a year. Too bad Seagate took them over. I can only hope that Seagate's manufacturing an QA doesn't suffer because of that. > > -- > ------------------------------------------------------------------------ > Emmanuel Florac | Direction technique > | Intellique > | > | +33 1 78 94 84 02 > ------------------------------------------------------------------------ --=20 Yours truly From prarit@redhat.com Wed Sep 10 13:59:35 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 7DDE27F5D for ; Wed, 10 Sep 2014 13:59:35 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4065C304048 for ; Wed, 10 Sep 2014 11:59:35 -0700 (PDT) X-ASG-Debug-ID: 1410375573-04cbb05487cae5e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id UknskbPSjpiMDuop (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 10 Sep 2014 11:59:34 -0700 (PDT) X-Barracuda-Envelope-From: prarit@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8AIxWpm023264 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Wed, 10 Sep 2014 14:59:32 -0400 Received: from [10.16.186.145] (prarit-guest.khw.lab.eng.bos.redhat.com [10.16.186.145]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8AIxVda019918; Wed, 10 Sep 2014 14:59:31 -0400 Message-ID: <54109F93.9020206@redhat.com> Date: Wed, 10 Sep 2014 14:59:31 -0400 From: Prarit Bhargava User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20131028 Thunderbird/17.0.10 MIME-Version: 1.0 To: xfs@oss.sgi.com, Eric Sandeen Subject: lockdep warning when logging in with ssh Content-Type: text/plain; charset=ISO-8859-1 X-ASG-Orig-Subj: lockdep warning when logging in with ssh Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410375573 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 I see this when I attempt to login via ssh. I do not see it if I login on the serial console. I recall seeing it earlier when chasing another patch but cannot recall the kernel version. [ 201.054547] ====================================================== [ 201.082819] [ INFO: possible circular locking dependency detected ] [ 201.112071] 3.17.0-rc4+ #1 Not tainted [ 201.129705] ------------------------------------------------------- [ 201.158238] sshd/8554 is trying to acquire lock: [ 201.179054] (&isec->lock){+.+.+.}, at: [] inode_doinit_with_dentry+0xc5/0x670 [ 201.219847] [ 201.219847] but task is already holding lock: [ 201.247255] (&mm->mmap_sem){++++++}, at: [] vm_mmap_pgoff+0x8f/0xf0 [ 201.283640] [ 201.283640] which lock already depends on the new lock. [ 201.283640] [ 201.321218] [ 201.321218] the existing dependency chain (in reverse order) is: [ 201.356331] -> #2 (&mm->mmap_sem){++++++}: [ 201.377731] [] __lock_acquire+0x380/0xb50 [ 201.406027] [] lock_acquire+0x99/0x1d0 [ 201.432867] [] might_fault+0x8c/0xb0 [ 201.458823] [] filldir+0x91/0x120 [ 201.483514] [] xfs_dir2_block_getdents.isra.12+0x1be/0x220 [xfs] [ 201.521199] [] xfs_readdir+0x1a4/0x2a0 [xfs] [ 201.550249] [] xfs_file_readdir+0x2b/0x30 [xfs] [ 201.581293] [] iterate_dir+0xae/0x140 [ 201.607964] [] SyS_getdents+0x9d/0x130 [ 201.635824] [] system_call_fastpath+0x16/0x1b [ 201.665367] -> #1 (&xfs_dir_ilock_class){++++.+}: [ 201.687368] [] __lock_acquire+0x380/0xb50 [ 201.716063] [] lock_acquire+0x99/0x1d0 [ 201.743603] [] down_read_nested+0x57/0xa0 [ 201.771960] [] xfs_ilock+0x122/0x250 [xfs] [ 201.800555] [] xfs_ilock_attr_map_shared+0x34/0x40 [xfs] [ 201.834681] [] xfs_attr_get+0xc0/0x1b0 [xfs] [ 201.864877] [] xfs_xattr_get+0x3d/0x80 [xfs] [ 201.895005] [] generic_getxattr+0x4f/0x70 [ 201.923173] [] inode_doinit_with_dentry+0x172/0x670 [ 201.955329] [] sb_finish_set_opts+0xd8/0x270 [ 201.984446] [] selinux_set_mnt_opts+0x2cd/0x630 [ 202.015726] [] superblock_doinit+0x77/0xf0 [ 202.044073] [] delayed_superblock_init+0x10/0x20 [ 202.074967] [] iterate_supers+0xb2/0x110 [ 202.103173] [] selinux_complete_init+0x33/0x40 [ 202.133771] [] security_load_policy+0x103/0x620 [ 202.164131] [] sel_write_load+0xbb/0x780 [ 202.191891] [] vfs_write+0xba/0x1f0 [ 202.217918] [] SyS_write+0x58/0xd0 [ 202.243473] [] system_call_fastpath+0x16/0x1b [ 202.273205] -> #0 (&isec->lock){+.+.+.}: [ 202.292818] [] validate_chain.isra.43+0x10d9/0x1170 [ 202.324616] [] __lock_acquire+0x380/0xb50 [ 202.352176] [] lock_acquire+0x99/0x1d0 [ 202.379637] [] mutex_lock_nested+0x88/0x520 [ 202.408647] [] inode_doinit_with_dentry+0xc5/0x670 [ 202.440389] [] selinux_d_instantiate+0x1c/0x20 [ 202.470704] [] security_d_instantiate+0x1b/0x30 [ 202.501868] [] d_instantiate+0x50/0x70 [ 202.528664] [] __shmem_file_setup+0xef/0x1f0 [ 202.557658] [] shmem_zero_setup+0x28/0x70 [ 202.585826] [] mmap_region+0x522/0x610 [ 202.613190] [] do_mmap_pgoff+0x301/0x3d0 [ 202.641687] [] vm_mmap_pgoff+0xb0/0xf0 [ 202.668753] [] SyS_mmap_pgoff+0x116/0x290 [ 202.697026] [] SyS_mmap+0x22/0x30 [ 202.722424] [] system_call_fastpath+0x16/0x1b [ 202.751931] [ 202.751931] other info that might help us debug this: [ 202.751931] [ 202.788578] Chain exists of: &isec->lock --> &xfs_dir_ilock_class --> &mm->mmap_sem [ 202.824995] Possible unsafe locking scenario: [ 202.824995] [ 202.851334] CPU0 CPU1 [ 202.872186] ---- ---- [ 202.892929] lock(&mm->mmap_sem); [ 202.908542] lock(&xfs_dir_ilock_class); [ 202.938063] lock(&mm->mmap_sem); [ 202.964735] lock(&isec->lock); [ 202.979226] [ 202.979226] *** DEADLOCK *** [ 202.979226] [ 203.006150] 1 lock held by sshd/8554: [ 203.023836] #0: (&mm->mmap_sem){++++++}, at: [] vm_mmap_pgoff+0x8f/0xf0 [ 203.062439] [ 203.062439] stack backtrace: [ 203.082082] CPU: 1 PID: 8554 Comm: sshd Not tainted 3.17.0-rc4+ #1 [ 203.110336] Hardware name: HP ProLiant MicroServer Gen8, BIOS J06 08/24/2013 [ 203.143994] 0000000000000 00000000d8562903 ffff88006c333a58 ffffffff8171b358 [ 203.671383] ffffffff82accf70 ffff88006c333a98 ffffffff8171444a ffff88006c333ad0 [ 203.705097] ffff88003507b718 ffff88003507b718 0000000000000000 ffff88003507aa10 [ 203.738777] Call Trace: [ 203.749696] [] dump_stack+0x4d/0x66 [ 203.774113] [] print_circular_bug+0x1f9/0x207 [ 203.801532] [] validate_chain.isra.43+0x10d9/0x1170 [ 203.831325] [] __lock_acquire+0x380/0xb50 [ 203.857340] [] lock_acquire+0x99/0x1d0 [ 203.882653] [] ? inode_doinit_with_dentry+0xc5/0x670 [ 203.913148] [] mutex_lock_nested+0x88/0x520 [ 203.939761] [] ? inode_doinit_with_dentry+0xc5/0x670 [ 203.969908] [] ? inode_doinit_with_dentry+0xc5/0x670 [ 203.999854] [] ? native_sched_clock+0x35/0xa0 [ 204.029374] [] ? sched_clock+0x9/0x10 [ 204.053170] [] inode_doinit_with_dentry+0xc5/0x670 [ 204.181571] [] ? lock_release_holdtime.part.28+0xf/0x190 [ 204.213464] [] selinux_d_instantiate+0x1c/0x20 [ 204.241190] [] security_d_instantiate+0x1b/0x30 [ 204.269524] [] d_instantiate+0x50/0x70 [ 204.293826] [] __shmem_file_setup+0xef/0x1f0 [ 204.320845] [] shmem_zero_setup+0x28/0x70 [ 204.346843] [] mmap_region+0x522/0x610 [ 204.371943] [] do_mmap_pgoff+0x301/0x3d0 [ 204.398095] [] vm_mmap_pgoff+0xb0/0xf0 [ 204.422903] [] SyS_mmap_pgoff+0x116/0x290 [ 204.448487] [] ? trace_hardirqs_on+0xd/0x10 [ 204.475204] [] SyS_mmap+0x22/0x30 [ 204.498005] [] system_call_fastpath+0x16/0x1b [ 204.526495] [sched_delayed] sched: RT throttling activated From david@fromorbit.com Wed Sep 10 15:23:56 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 91D5C7F5F for ; Wed, 10 Sep 2014 15:23:56 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7275B8F804C for ; Wed, 10 Sep 2014 13:23:53 -0700 (PDT) X-ASG-Debug-ID: 1410380630-04cb6c54fe9ac930001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id qP7qB2DX4S8RPAe7 for ; Wed, 10 Sep 2014 13:23:51 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Am4jAJmyEFR5LKYhPGdsb2JhbABfgw2DVoUHqXIBAQEBAQEGmnCFagQCAYERFwUBAQEBODeEBAEFOhwjEAgDGAkNARcPBSUDBxoTiEG/LQEXGIVkiVEHEgGDHIEdBZoiglmZLSsvgQgHF4EpAQEB Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail05.adl6.internode.on.net with ESMTP; 11 Sep 2014 05:53:49 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XRoQe-0001T8-2x; Thu, 11 Sep 2014 06:23:48 +1000 Date: Thu, 11 Sep 2014 06:23:48 +1000 From: Dave Chinner To: Prarit Bhargava Cc: xfs@oss.sgi.com, Eric Sandeen Subject: Re: lockdep warning when logging in with ssh Message-ID: <20140910202348.GC27048@dastard> X-ASG-Orig-Subj: Re: lockdep warning when logging in with ssh References: <54109F93.9020206@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <54109F93.9020206@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1410380630 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9351 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Sep 10, 2014 at 02:59:31PM -0400, Prarit Bhargava wrote: > I see this when I attempt to login via ssh. I do not see it if I login on > the serial console. I recall seeing it earlier when chasing another patch but > cannot recall the kernel version. It's the shmem code that is broken - instantiating an inode while holding the mmap_sem inverts lock orders all over the place, especially in the security subsystem.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From prarit@redhat.com Wed Sep 10 17:40:32 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id BF2D87F61 for ; Wed, 10 Sep 2014 17:40:32 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id ADFDA8F8049 for ; Wed, 10 Sep 2014 15:40:29 -0700 (PDT) X-ASG-Debug-ID: 1410388825-04cb6c55009b2420001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id QYRgJzIJjwzVJVRD (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 10 Sep 2014 15:40:25 -0700 (PDT) X-Barracuda-Envelope-From: prarit@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8AMeGJF020806 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 10 Sep 2014 18:40:17 -0400 Received: from [10.16.186.145] (prarit-guest.khw.lab.eng.bos.redhat.com [10.16.186.145]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8AMeGXf006440; Wed, 10 Sep 2014 18:40:16 -0400 Message-ID: <5410D34F.1030404@redhat.com> Date: Wed, 10 Sep 2014 18:40:15 -0400 From: Prarit Bhargava User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20131028 Thunderbird/17.0.10 MIME-Version: 1.0 To: Dave Chinner CC: xfs@oss.sgi.com, Eric Sandeen Subject: Re: lockdep warning when logging in with ssh References: <54109F93.9020206@redhat.com> <20140910202348.GC27048@dastard> X-ASG-Orig-Subj: Re: lockdep warning when logging in with ssh In-Reply-To: <20140910202348.GC27048@dastard> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410388825 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On 09/10/2014 04:23 PM, Dave Chinner wrote: > On Wed, Sep 10, 2014 at 02:59:31PM -0400, Prarit Bhargava wrote: >> I see this when I attempt to login via ssh. I do not see it if I login on >> the serial console. I recall seeing it earlier when chasing another patch but >> cannot recall the kernel version. > > It's the shmem code that is broken - instantiating an inode while > holding the mmap_sem inverts lock orders all over the place, > especially in the security subsystem.... > I'll send this off to Hugh Dickens then. P. > Cheers, > > Dave. > From lrhorer@mygrande.net Wed Sep 10 18:18:48 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id F332C7F63 for ; Wed, 10 Sep 2014 18:18:47 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 81D3CAC00A for ; Wed, 10 Sep 2014 16:18:44 -0700 (PDT) X-ASG-Debug-ID: 1410391122-04cb6c54fd9b3920001-NocioJ Received: from mail03.lsn.net (mail03.lsn.net [66.90.130.130]) by cuda.sgi.com with ESMTP id 83jgvj693yEk3yQt for ; Wed, 10 Sep 2014 16:18:42 -0700 (PDT) X-Barracuda-Envelope-From: lrhorer@mygrande.net X-Barracuda-Apparent-Source-IP: 66.90.130.130 Received: from [192.168.1.121] (24-155-170-173.dyn.grandenetworks.net [24.155.170.173]) (authenticated bits=0) by mail03.lsn.net (8.14.4/8.13.6) with ESMTP id s8ANIcNX009581 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Wed, 10 Sep 2014 18:18:39 -0500 X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.98.4 at av01.lsn.net Message-ID: <5410DC4E.90908@mygrande.net> Date: Wed, 10 Sep 2014 18:18:38 -0500 From: Leslie Rhorer User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: Emmanuel Florac CC: Sean Caron , "xfs@oss.sgi.com" Subject: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> <540FACAC.3010504@mygrande.net> <20140910163124.3d879432@harpe.intellique.com> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: <20140910163124.3d879432@harpe.intellique.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Barracuda-Connect: mail03.lsn.net[66.90.130.130] X-Barracuda-Start-Time: 1410391122 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9355 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/10/2014 9:31 AM, Emmanuel Florac wrote: > Le Tue, 09 Sep 2014 20:43:08 -0500 > Leslie Rhorer écrivait: > >> None of the failed drives were WD green. All three and the >> previous four were Seagate. I realize that is not a large >> statistical sample. >> > > If you're interested in large statistical samples, on a grand total of > 4000 1 TB Seagate Barracuda ES2, I had to replace 2100 of them over the > course of 3 years. That's a good sized statistical sample. Oddly enough, perhaps, the ones that failed on me were also 1T Barracuda drives, and my failure rate was 40%. From sandeen@redhat.com Wed Sep 10 22:25:04 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 0472D7F67 for ; Wed, 10 Sep 2014 22:25:04 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id C9796304043 for ; Wed, 10 Sep 2014 20:25:00 -0700 (PDT) X-ASG-Debug-ID: 1410405899-04bdf01097969030001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id oBQWN1TT1mUVIiI1 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 10 Sep 2014 20:24:59 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8B3OxHf020735 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Wed, 10 Sep 2014 23:24:59 -0400 Received: from liberator.sandeen.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8B3OvQE008598 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Wed, 10 Sep 2014 23:24:58 -0400 Message-ID: <54111610.4080604@redhat.com> Date: Wed, 10 Sep 2014 22:25:04 -0500 From: Eric Sandeen MIME-Version: 1.0 To: xfs-oss Subject: [PATCH] xfs_io: add mremap command Content-Type: text/plain; charset=utf-8; format=flowed X-ASG-Orig-Subj: [PATCH] xfs_io: add mremap command Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410405899 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 This adds a simple mremap command to xfs_io. It does not take a start address; it uses the existing start address, so the sized passed will be the new total size of the mapping. Signed-off-by: Eric Sandeen --- diff --git a/io/mmap.c b/io/mmap.c index ea7498f..565a541 100644 --- a/io/mmap.c +++ b/io/mmap.c @@ -29,6 +29,7 @@ static cmdinfo_t mread_cmd; static cmdinfo_t msync_cmd; static cmdinfo_t munmap_cmd; static cmdinfo_t mwrite_cmd; +static cmdinfo_t mremap_cmd; mmap_region_t *maptable; int mapcount; @@ -574,6 +575,66 @@ mwrite_f( return 0; } +static void +mremap_help(void) +{ + printf(_( +"\n" +" resizes the current memory mapping\n" +"\n" +" Examples:\n" +" 'mremap 8192' - resizes the current mapping to 8192 bytes.\n" +"\n" +" Resizes the mappping, growing or shrinking from the current size.\n" +" The default stored value is 'X', repeated to fill the range specified.\n" +" -f -- use the MREMAP_FIXED flag\n" +" -m -- use the MREMAP_MAYMOVE flag\n" +"\n")); +} + +int +mremap_f( + int argc, + char **argv) +{ + ssize_t new_length; + void *new_addr; + int flags = 0; + int c; + size_t blocksize, sectsize; + + while ((c = getopt(argc, argv, "fm")) != EOF) { + switch (c) { + case 'f': + flags = MREMAP_FIXED|MREMAP_MAYMOVE; + break; + case 'm': + flags = MREMAP_MAYMOVE; + break; + default: + return command_usage(&mremap_cmd); + } + } + + init_cvtnum(&blocksize, §size); + new_length = cvtnum(blocksize, sectsize, argv[optind]); + if (new_length < 0) { + printf(_("non-numeric offset argument -- %s\n"), + argv[optind]); + return 0; + } + + new_addr = mremap(mapping->addr, mapping->length, new_length, flags); + if (new_addr == MAP_FAILED) + perror("mremap"); + else { + mapping->addr = new_addr; + mapping->length = new_length; + } + + return 0; +} + void mmap_init(void) { @@ -628,9 +689,21 @@ mmap_init(void) _("writes data into a region in the current memory mapping"); mwrite_cmd.help = mwrite_help; + mremap_cmd.name = "mremap"; + mremap_cmd.altname = "mrm"; + mremap_cmd.cfunc = mremap_f; + mremap_cmd.argmin = 1; + mremap_cmd.argmax = 2; + mremap_cmd.flags = CMD_NOFILE_OK | CMD_FOREIGN_OK; + mremap_cmd.args = _("[-f|-m] newsize"); + mremap_cmd.oneline = + _("alters the size of the current memory mapping"); + mremap_cmd.help = mremap_help; + add_command(&mmap_cmd); add_command(&mread_cmd); add_command(&msync_cmd); add_command(&munmap_cmd); add_command(&mwrite_cmd); + add_command(&mremap_cmd); } diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index e1a3e1a..e40fbf9 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -501,6 +501,20 @@ See the .B mmap command. .TP +.BI "mremap [ \-f ] [ \-m ] " new_length +Changes the current mapping size to +.IR new_length . +Whether the mapping may be moved is controlled by the flags passed; +MREMAP_FIXED +.RB ( \-f ), +or MREMAP_MAYMOVE +.RB ( \-m ). +.TP +.B mrm +See the +.B mremap +command. +.TP .B munmap Unmaps the current memory mapping. .TP From sandeen@sandeen.net Wed Sep 10 22:29:39 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 146BC7F6F for ; Wed, 10 Sep 2014 22:29:39 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 974B9AC005 for ; Wed, 10 Sep 2014 20:29:35 -0700 (PDT) X-ASG-Debug-ID: 1410406170-04cbb05486cc3fd0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id xAuXNzCVqMYN2ZgF for ; Wed, 10 Sep 2014 20:29:30 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 19DC861F892F; Wed, 10 Sep 2014 22:29:30 -0500 (CDT) Message-ID: <5411171F.6010704@sandeen.net> Date: Wed, 10 Sep 2014 22:29:35 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Eric Sandeen , xfs-oss Subject: [PATCH V2] xfs_io: add mremap command References: <54111610.4080604@redhat.com> X-ASG-Orig-Subj: [PATCH V2] xfs_io: add mremap command In-Reply-To: <54111610.4080604@redhat.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410406170 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9360 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This adds a simple mremap command to xfs_io. It does not take a start address; it uses the existing start address, so the sized passed will be the new total size of the mapping. Signed-off-by: Eric Sandeen --- V2: fix stray line in help. Why was it only visible after I sent V1... :/ diff --git a/io/mmap.c b/io/mmap.c index ea7498f..f1809e0 100644 --- a/io/mmap.c +++ b/io/mmap.c @@ -29,6 +29,7 @@ static cmdinfo_t mread_cmd; static cmdinfo_t msync_cmd; static cmdinfo_t munmap_cmd; static cmdinfo_t mwrite_cmd; +static cmdinfo_t mremap_cmd; mmap_region_t *maptable; int mapcount; @@ -574,6 +575,65 @@ mwrite_f( return 0; } +static void +mremap_help(void) +{ + printf(_( +"\n" +" resizes the current memory mapping\n" +"\n" +" Examples:\n" +" 'mremap 8192' - resizes the current mapping to 8192 bytes.\n" +"\n" +" Resizes the mappping, growing or shrinking from the current size.\n" +" -f -- use the MREMAP_FIXED flag\n" +" -m -- use the MREMAP_MAYMOVE flag\n" +"\n")); +} + +int +mremap_f( + int argc, + char **argv) +{ + ssize_t new_length; + void *new_addr; + int flags = 0; + int c; + size_t blocksize, sectsize; + + while ((c = getopt(argc, argv, "fm")) != EOF) { + switch (c) { + case 'f': + flags = MREMAP_FIXED|MREMAP_MAYMOVE; + break; + case 'm': + flags = MREMAP_MAYMOVE; + break; + default: + return command_usage(&mremap_cmd); + } + } + + init_cvtnum(&blocksize, §size); + new_length = cvtnum(blocksize, sectsize, argv[optind]); + if (new_length < 0) { + printf(_("non-numeric offset argument -- %s\n"), + argv[optind]); + return 0; + } + + new_addr = mremap(mapping->addr, mapping->length, new_length, flags); + if (new_addr == MAP_FAILED) + perror("mremap"); + else { + mapping->addr = new_addr; + mapping->length = new_length; + } + + return 0; +} + void mmap_init(void) { @@ -628,9 +688,21 @@ mmap_init(void) _("writes data into a region in the current memory mapping"); mwrite_cmd.help = mwrite_help; + mremap_cmd.name = "mremap"; + mremap_cmd.altname = "mrm"; + mremap_cmd.cfunc = mremap_f; + mremap_cmd.argmin = 1; + mremap_cmd.argmax = 2; + mremap_cmd.flags = CMD_NOFILE_OK | CMD_FOREIGN_OK; + mremap_cmd.args = _("[-m|-f] newsize"); + mremap_cmd.oneline = + _("alters the size of the current memory mapping"); + mremap_cmd.help = mremap_help; + add_command(&mmap_cmd); add_command(&mread_cmd); add_command(&msync_cmd); add_command(&munmap_cmd); add_command(&mwrite_cmd); + add_command(&mremap_cmd); } diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index e1a3e1a..e40fbf9 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -501,6 +501,20 @@ See the .B mmap command. .TP +.BI "mremap [ \-f ] [ \-m ] " new_length +Changes the current mapping size to +.IR new_length . +Whether the mapping may be moved is controlled by the flags passed; +MREMAP_FIXED +.RB ( \-f ), +or MREMAP_MAYMOVE +.RB ( \-m ). +.TP +.B mrm +See the +.B mremap +command. +.TP .B munmap Unmaps the current memory mapping. .TP From david@fromorbit.com Wed Sep 10 23:42:47 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id DAC4E7F6B for ; Wed, 10 Sep 2014 23:42:47 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id C6BB7304051 for ; Wed, 10 Sep 2014 21:42:47 -0700 (PDT) X-ASG-Debug-ID: 1410410565-04cbb05485cc5e70001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id ZBgByYRqE1SDDSIn for ; Wed, 10 Sep 2014 21:42:45 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AlsoAG4nEVR5LKYhPGdsb2JhbABggw2BKoczqX8BBQaYd4VqBAIBgQ0XBQEBAQE4N4QEAQEEOhwjEAgDDgoJJQ8FJQMHGhOIQb9FARcYhWSJUQeDL4EdAQSce5ktKy+CTwEBAQ Received: from ppp121-44-166-33.lns20.syd7.internode.on.net (HELO dastard) ([121.44.166.33]) by ipmail04.adl6.internode.on.net with ESMTP; 11 Sep 2014 14:12:44 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XRwDT-0002dP-8S; Thu, 11 Sep 2014 14:42:43 +1000 Date: Thu, 11 Sep 2014 14:42:43 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc Message-ID: <20140911044243.GA10111@dastard> X-ASG-Orig-Subj: Re: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc References: <1410355231-50495-1-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1410355231-50495-1-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410410565 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9361 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Sep 10, 2014 at 09:20:26AM -0400, Brian Foster wrote: > Hi all, > > Here's v2 of the collapse clean up. We refactor a bit more via the > insertion of patch 3, otherwise it's similar to v1. This will see some > continued testing, but it survived ~500m fsx operations overnight. > > Brian I'm not sure about the invalidation patch now. On a 1k block size filesystem, generic/127 fails with: +ltp/fsx -q -l 262144 -o 65536 -S 191110531 -N 100000 -R -W fsx_std_nommap +collapse range: 1000 to 3000 +do_collapse_range: fallocate: Device or resource busy which indicates we had an invalidation failure. This is probably exposing some other bug, but I haven't had time to look into it yet so I don't know. Cheers, Dave. -- Dave Chinner david@fromorbit.com From lrhorer@mygrande.net Thu Sep 11 00:48:45 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 723E37F6D for ; Thu, 11 Sep 2014 00:48:45 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 60042304043 for ; Wed, 10 Sep 2014 22:48:42 -0700 (PDT) X-ASG-Debug-ID: 1410414520-04cbb05487cc78f0001-NocioJ Received: from mail04.lsn.net (mail04.lsn.net [66.90.130.138]) by cuda.sgi.com with ESMTP id y7kOGmzUMoJvtGZu for ; Wed, 10 Sep 2014 22:48:40 -0700 (PDT) X-Barracuda-Envelope-From: lrhorer@mygrande.net X-Barracuda-Apparent-Source-IP: 66.90.130.138 Received: from [192.168.1.121] (24-155-170-173.dyn.grandenetworks.net [24.155.170.173]) (authenticated bits=0) by mail04.lsn.net (8.14.4/8.13.6) with ESMTP id s8B5lVCm031439 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Thu, 11 Sep 2014 00:47:32 -0500 X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.98.4 at av01.lsn.net Message-ID: <54113773.2090103@mygrande.net> Date: Thu, 11 Sep 2014 00:47:31 -0500 From: Leslie Rhorer User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: Dave Chinner CC: xfs@oss.sgi.com Subject: Re: Corrupted files References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> <20140910015331.GJ20518@dastard> <540FC135.8010601@mygrande.net> <20140910033331.GA27048@dastard> <540FD8DE.7090306@mygrande.net> <20140910052303.GB27048@dastard> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: <20140910052303.GB27048@dastard> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail04.lsn.net[66.90.130.138] X-Barracuda-Start-Time: 1410414520 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9363 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/10/2014 12:23 AM, Dave Chinner wrote: > On Tue, Sep 09, 2014 at 11:51:42PM -0500, Leslie Rhorer wrote: >> On 9/9/2014 10:33 PM, Dave Chinner wrote: >>> On Tue, Sep 09, 2014 at 10:10:45PM -0500, Leslie Rhorer wrote: >>>> On 9/9/2014 8:53 PM, Dave Chinner wrote: >>>>> On Tue, Sep 09, 2014 at 08:12:38PM -0500, Leslie Rhorer wrote: >>>>>> On 9/9/2014 5:06 PM, Dave Chinner wrote: >>>> I've never used git on a package maintained in my distro. Will I >>>> have issues when I upgrade to Debian Jessie in a few months, since >>>> this is not being managed by apt / dpkg? It looks like Jessie has >>>> 3.2.1 of xfs-progs. >>> >>> If you're using debian you can build debian packages directly from >>> the git tree via "make deb" (I use it all the time for pushing >>> new builds to my test machines) and so when you upgrade to Jessie it >>> should just replace your custom built package correctly... >> >> Thanks a ton, Dave (and everyone else who helped). That seems to >> have worked just fine. The three grunged entries are gone and the >> system is happily copying over the backups. Now I'll run another >> rsync with checksum to make sure everything is good before putting >> the backup into production. I'm also going to upgrade the >> controller BIOS just in case. > > Good to hear. Hopefully everything will check out. Just yell if you > need more help. ;) Thanks. The rsync compare just finished on the non-volatile areas of the file system without a single mismatch and no missing files. That's good enough for me. From greg.freemyer@gmail.com Thu Sep 11 08:24:50 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D046A7F73 for ; Thu, 11 Sep 2014 08:24:50 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 930058F8049 for ; Thu, 11 Sep 2014 06:24:47 -0700 (PDT) X-ASG-Debug-ID: 1410441884-04bdf010979a13b0001-NocioJ Received: from mail-we0-f180.google.com (mail-we0-f180.google.com [74.125.82.180]) by cuda.sgi.com with ESMTP id S4M6CqTJjUSatvaB (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Thu, 11 Sep 2014 06:24:45 -0700 (PDT) X-Barracuda-Envelope-From: greg.freemyer@gmail.com X-Barracuda-Apparent-Source-IP: 74.125.82.180 Received: by mail-we0-f180.google.com with SMTP id t60so5671828wes.11 for ; Thu, 11 Sep 2014 06:24:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type:content-transfer-encoding; bh=oQFXPUL5DZREmYDysv7l/4YAc9RBwdKaUQauG+KwLfk=; b=e9601iuexuBjoKqc86Ht6MDAxH2vFkd9ue1riw5HibgIq/VZMSHyLIoBYX5gCIhoMn xGMbpbv+O8sXyuG4DcLiuiG8/qtL8dLss3+UJYVBUrl9gHx6rpwhbh/mv92HcZanBNa1 lAPRmIzHS+ljDVRpFOuPAVR1gwJo/4wDaXZT3pTWFVGRnmzDwfmqWfWucgekYtX7cYra hy948bXbbXwKtCdGKp/mBplo3Ki/PDazxOZGgmuCJkoJ4f8MyUkwhnU+Sc04Cyf6ZHGT PQnx1rjdCRqogu9iF/4OuABd1wqSIlfUcdLPNQsGNp+OhlOzrs8OywT/IVZadqcZwpLr LrZQ== X-Received: by 10.194.209.205 with SMTP id mo13mr1419352wjc.122.1410441884645; Thu, 11 Sep 2014 06:24:44 -0700 (PDT) MIME-Version: 1.0 Received: by 10.180.10.102 with HTTP; Thu, 11 Sep 2014 06:24:04 -0700 (PDT) In-Reply-To: <20140910163124.3d879432@harpe.intellique.com> References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> <540FACAC.3010504@mygrande.net> <20140910163124.3d879432@harpe.intellique.com> From: Greg Freemyer Date: Thu, 11 Sep 2014 09:24:04 -0400 Message-ID: Subject: Re: Corrupted files To: Emmanuel Florac X-ASG-Orig-Subj: Re: Corrupted files Cc: Leslie Rhorer , Sean Caron , "xfs@oss.sgi.com" Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail-we0-f180.google.com[74.125.82.180] X-Barracuda-Start-Time: 1410441885 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9370 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Wed, Sep 10, 2014 at 10:31 AM, Emmanuel Florac wrote: > Le Tue, 09 Sep 2014 20:43:08 -0500 > Leslie Rhorer =C3=A9crivait: > >> None of the failed drives were WD green. All three and the >> previous four were Seagate. I realize that is not a large >> statistical sample. >> > > If you're interested in large statistical samples, on a grand total of > 4000 1 TB Seagate Barracuda ES2, I had to replace 2100 of them over the > course of 3 years. I still have a couple of hundred of these > unfortunate pieces of crap in service, and they still represent the > vast majority of unexpected RAID malfunctions, urgent replacements, > late night calls and other "interesting side activities". > > I wouldn't buy anything labeled Seagate nowadays. Their drives have > been the baddest train wreck since the dreaded 9 GB Micropolis back in > 1994 (or was it 1995?). I buy about 100 drives a year, but I don't work them very hard. Just lots of data to store and I need to keep my data sets segregated for legal reasons. I don't use raid, just lots of individual disks and most data maintained redundantly. About 4 years ago (or maybe 5), Seagate had a catastrophic drive situation. I can remember buying a batch of 10 drives and having 8 of them fail in the first 2 months. The bad part was they mostly survived a 10 hour burn-in, so they tended to fail with real data on them. I had one case (at a minimum) that summer where I put the data on 3 different Seagate drives and all 3 failed. Fortunately, I was able to swap the disk controller card from one of the working drives with one of the dead drives and recover the data. Regardless, ignoring the summer of discontent, I find Seagate to be my preferred drives. fyi: In June I bought 30 or so WD elements drives to try them out. These are not the green drives, just bare bones WD drives. None of them were DOA, but 3 failed within 4 weeks, so a 10% failure rate in the first month. Only one of them had unique data on it, so I had to recreate that data. Fortunately the source of the data was still available. All of those drives have been pulled out of routine service. Greg From bfoster@redhat.com Thu Sep 11 10:20:21 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 797CE7F75 for ; Thu, 11 Sep 2014 10:20:21 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4ABE78F8033 for ; Thu, 11 Sep 2014 08:20:18 -0700 (PDT) X-ASG-Debug-ID: 1410448816-04bdf010979af730001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id BNzBbiL5CUDIz561 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 11 Sep 2014 08:20:17 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8BFKEWt032665 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 11 Sep 2014 11:20:14 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8BFKEJl006218; Thu, 11 Sep 2014 11:20:14 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 1BAC01256F8; Thu, 11 Sep 2014 11:20:13 -0400 (EDT) Date: Thu, 11 Sep 2014 11:20:13 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc Message-ID: <20140911152012.GB54638@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc References: <1410355231-50495-1-git-send-email-bfoster@redhat.com> <20140911044243.GA10111@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911044243.GA10111@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410448817 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Sep 11, 2014 at 02:42:43PM +1000, Dave Chinner wrote: > On Wed, Sep 10, 2014 at 09:20:26AM -0400, Brian Foster wrote: > > Hi all, > > > > Here's v2 of the collapse clean up. We refactor a bit more via the > > insertion of patch 3, otherwise it's similar to v1. This will see some > > continued testing, but it survived ~500m fsx operations overnight. > > > > Brian > > I'm not sure about the invalidation patch now. On a 1k block size > filesystem, generic/127 fails with: > > +ltp/fsx -q -l 262144 -o 65536 -S 191110531 -N 100000 -R -W fsx_std_nommap > +collapse range: 1000 to 3000 > +do_collapse_range: fallocate: Device or resource busy > > which indicates we had an invalidation failure. This is probably > exposing some other bug, but I haven't had time to look into it yet > so I don't know. > Yeah, I can reproduce this as well, thanks. I think you're referring to the xfs_free_file_space() patch (5/5)..? FWIW, I don't see the problem without that patch, so it appears that the full pagecache truncate is still covering up a problem somewhere. I'll try to dig into it... Brian > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com From bpm@sgi.com Thu Sep 11 15:37:40 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id F27057F77 for ; Thu, 11 Sep 2014 15:37:39 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id 845D3AC00D; Thu, 11 Sep 2014 13:37:36 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 099264266DC; Thu, 11 Sep 2014 15:37:36 -0500 (CDT) Date: Thu, 11 Sep 2014 15:37:35 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [RFC] Unicode/UTF-8 support for XFS Message-ID: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) Hi, I'm posting this RFC on Olaf's behalf, as he is busy with other projects. First is a series of kernel patches, then a series of patches for xfsprogs, and then a test. Note that I have removed the unicode database files prior to posting due to their large size. There are instructions on how to download them in the relevant commit headers. Thanks, Ben Here are some notes of introduction from Olaf: ----------------------------------------------------------------------------- Unicode/UTF-8 support for XFS So we had a customer request proper unicode support... Design notes. XFS uses byte strings for filenames, so UTF-8 is the expected format for unicode filenames. This does raise the question what criteria a byte string must meet to be UTF-8. We settled on the following: - Valid unicode code points are 0..0x10FFFF, except that - The surrogates 0xD800..0xDFFF are not valid code points, and - Valid UTF-8 must be a shortest encoding of a valid unicode code point. In addition, U+0 (ASCII NUL, '\0') is used to terminate byte strings (and is itself not part of the string). Moreover strings may be length-limited in addition to being NUL-terminated (there is no such thing as an embedded NUL in a length-limited string). Based on feedback on the earlier patches for unicode/UTF-8 support, we decided that a filename that does not match the above criteria should be treated as a binary blob, as opposed to being rejected. To stress: if any part of the string isn't valid UTF-8, then the entire string is treated as a binary blob. This matters once normalization is considered. When comparing unicode strings for equality, normalization comes into play: we must compare the normalized forms of strings, not just the raw sequences of bytes. There are a number of defined normalization forms for unicode. We decided on a variant of NFKD we call NFKDI. NFD was chosed over NFC, because calculating NFC requires calculating NFD first, followed by an additional step. NFKD was chosen over NFD because this makes filenames that ought to be equal compare as equal. My favorite example is the ways "office" can be spelled, when "fi" or "ffi" ligatures are used. NFKDI adds one more step of NFKD, in that it eliminates the code points that have the Default_Ignorable_Code_Point property from the comparison. These code points are as a rule invisible, but might (or might not) be pulled in when you copy/paste a string to be used as a filename. An example of these is U+00AD SOFT HYPHEN, a code point that only shows up if a word is split across lines. If a filename is considered to be binary blob, comparison is based on a simple binary match. Normalization does not apply to any part of a blob. The code uses ("leverages", in corp-speak) the existing infrastructure for case-insensitive filenames. Like the CI code, the name used to create a file is stored on disk, and returned in a lookup. When comparing filenames the normalized forms of the names being compared are generated on the fly from the non-normalized forms stored on disk. If the borgbit (the bit enabling legacy ASCII-based CI) is set in the superblock, then case folding is added into the mix. This normalization form we call NFKDICF. It allows for the creation of case-insensitive filesystems with UTF-8 support. ----------------------------------------------------------------------------- Implementation notes. Strings are normalized using a trie that stores the relevant information. The trie itself is part of the XFS module, and about 250kB in size. The trie is not checked in: instead we add the source files from the Unicode Character Database and a program that creates the header containing the trie. The key for a lookup in the trie is a UTF-8 sequence. Each valid UTF-8 sequence leads to a leaf. No invalid sequence does. This means that trie lookups can be used to validate UTF-8 sequences, which why there is no specialized code for the same purpose. The trie contains information for the version of unicode in which each code point was defined. This matters because non-normalized strings are stored on disk, and newer versions of unicode may introduce new normalized forms. Ideally, the version of unicode used by the filesystem is stored in the filesystem. The trie also accounts for corrections made in the past to normalizations. This has little value today, because any newly created filesystem would be using unicode version 7.0.0. It is included in order to show, not tell, that such corrections can be handled if they are added in future revisions. The algorithm used to calculate the sequences of bytes for the normalized form of a UTF-8 string is tricky. The core is found in utf8byte(), with an explanation in the preceeding comment. The non-XFS-specific supporting code is in separate source files, and be put in some other location in the Linux kernel source tree, if desired. These functions have the prefix 'utf8n' if they handle length-limited strings, and 'utf8' if they handle NUL-terminated strings. ----------------------------------------------------------------------------- From bpm@sgi.com Thu Sep 11 15:40:13 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 8BDE07F7B for ; Thu, 11 Sep 2014 15:40:13 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id 5BFF48F8040; Thu, 11 Sep 2014 13:40:10 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 257D84266DC; Thu, 11 Sep 2014 15:40:10 -0500 (CDT) Date: Thu, 11 Sep 2014 15:40:10 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 1/9] xfs: return the first match during case-insensitive lookup. Message-ID: <20140911204010.GA13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Change the XFS case-insensitive lookup code to return the first match found, even if it is not an exact match. Whether a filesystem uses case-insensitive lookups is determined by a superblock bit set during filesystem creation. This means that normal use cannot create two files that both match the same filename. Signed-off-by: Olaf Weber --- fs/xfs/libxfs/xfs_dir2_block.c | 17 +++------ fs/xfs/libxfs/xfs_dir2_leaf.c | 37 ++++---------------- fs/xfs/libxfs/xfs_dir2_node.c | 79 ++++++++++++++++-------------------------- fs/xfs/libxfs/xfs_dir2_sf.c | 8 ++--- 4 files changed, 45 insertions(+), 96 deletions(-) diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 9628cec..990bf0c 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -725,28 +725,21 @@ xfs_dir2_block_lookup_int( dep = (xfs_dir2_data_entry_t *) ((char *)hdr + xfs_dir2_dataptr_to_off(args->geo, addr)); /* - * Compare name and if it's an exact match, return the index - * and buffer. If it's the first case-insensitive match, store - * the index and buffer and continue looking for an exact match. + * Compare name and if it's a match, return the + * index and buffer. */ cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); - if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { + if (cmp != XFS_CMP_DIFFERENT) { args->cmpresult = cmp; *bpp = bp; *entno = mid; - if (cmp == XFS_CMP_EXACT) - return 0; + return 0; } } while (++mid < be32_to_cpu(btp->count) && be32_to_cpu(blp[mid].hashval) == hash); ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); - /* - * Here, we can only be doing a lookup (not a rename or replace). - * If a case-insensitive match was found earlier, return success. - */ - if (args->cmpresult == XFS_CMP_CASE) - return 0; + ASSERT(args->cmpresult == XFS_CMP_DIFFERENT); /* * No match, release the buffer and return ENOENT. */ diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index a19174e..3d572ee 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -1226,7 +1226,6 @@ xfs_dir2_leaf_lookup_int( xfs_mount_t *mp; /* filesystem mount point */ xfs_dir2_db_t newdb; /* new data block number */ xfs_trans_t *tp; /* transaction pointer */ - xfs_dir2_db_t cidb = -1; /* case match data block no. */ enum xfs_dacmp cmp; /* name compare result */ struct xfs_dir2_leaf_entry *ents; struct xfs_dir3_icleaf_hdr leafhdr; @@ -1290,46 +1289,22 @@ xfs_dir2_leaf_lookup_int( be32_to_cpu(lep->address))); /* * Compare name and if it's an exact match, return the index - * and buffer. If it's the first case-insensitive match, store - * the index and buffer and continue looking for an exact match. + * and buffer */ cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); - if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { + if (cmp != XFS_CMP_DIFFERENT) { args->cmpresult = cmp; *indexp = index; - /* case exact match: return the current buffer. */ - if (cmp == XFS_CMP_EXACT) { - *dbpp = dbp; - return 0; - } - cidb = curdb; + *dbpp = dbp; + return 0; } } ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); - /* - * Here, we can only be doing a lookup (not a rename or remove). - * If a case-insensitive match was found earlier, re-read the - * appropriate data block if required and return it. - */ - if (args->cmpresult == XFS_CMP_CASE) { - ASSERT(cidb != -1); - if (cidb != curdb) { - xfs_trans_brelse(tp, dbp); - error = xfs_dir3_data_read(tp, dp, - xfs_dir2_db_to_da(args->geo, cidb), - -1, &dbp); - if (error) { - xfs_trans_brelse(tp, lbp); - return error; - } - } - *dbpp = dbp; - return 0; - } + ASSERT(args->cmpresult == XFS_CMP_DIFFERENT); + /* * No match found, return -ENOENT. */ - ASSERT(cidb == -1); if (dbp) xfs_trans_brelse(tp, dbp); xfs_trans_brelse(tp, lbp); diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 2ae6ac2..1778c40 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -679,6 +679,7 @@ xfs_dir2_leafn_lookup_for_entry( xfs_dir2_data_entry_t *dep; /* data block entry */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return value */ + int di = -1; /* data entry index */ int index; /* leaf entry index */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ @@ -709,6 +710,7 @@ xfs_dir2_leafn_lookup_for_entry( if (state->extravalid) { curbp = state->extrablk.bp; curdb = state->extrablk.blkno; + di = state->extrablk.index; } /* * Loop over leaf entries with the right hash value. @@ -734,28 +736,20 @@ xfs_dir2_leafn_lookup_for_entry( */ if (newdb != curdb) { /* - * If we had a block before that we aren't saving - * for a CI name, drop it + * If we had a block, drop it */ - if (curbp && (args->cmpresult == XFS_CMP_DIFFERENT || - curdb != state->extrablk.blkno)) + if (curbp) { xfs_trans_brelse(tp, curbp); + di = -1; + } /* - * If needing the block that is saved with a CI match, - * use it otherwise read in the new data block. + * Read in the new data block. */ - if (args->cmpresult != XFS_CMP_DIFFERENT && - newdb == state->extrablk.blkno) { - ASSERT(state->extravalid); - curbp = state->extrablk.bp; - } else { - error = xfs_dir3_data_read(tp, dp, - xfs_dir2_db_to_da(args->geo, - newdb), + error = xfs_dir3_data_read(tp, dp, + xfs_dir2_db_to_da(args->geo, newdb), -1, &curbp); - if (error) - return error; - } + if (error) + return error; xfs_dir3_data_check(dp, curbp); curdb = newdb; } @@ -766,53 +760,40 @@ xfs_dir2_leafn_lookup_for_entry( xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address))); /* - * Compare the entry and if it's an exact match, return - * EEXIST immediately. If it's the first case-insensitive - * match, store the block & inode number and continue looking. + * Compare the entry and if it's a match, return + * EEXIST immediately. */ cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); - if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { - /* If there is a CI match block, drop it */ - if (args->cmpresult != XFS_CMP_DIFFERENT && - curdb != state->extrablk.blkno) - xfs_trans_brelse(tp, state->extrablk.bp); + if (cmp != XFS_CMP_DIFFERENT) { args->cmpresult = cmp; args->inumber = be64_to_cpu(dep->inumber); args->filetype = dp->d_ops->data_get_ftype(dep); - *indexp = index; - state->extravalid = 1; - state->extrablk.bp = curbp; - state->extrablk.blkno = curdb; - state->extrablk.index = (int)((char *)dep - - (char *)curbp->b_addr); - state->extrablk.magic = XFS_DIR2_DATA_MAGIC; curbp->b_ops = &xfs_dir3_data_buf_ops; xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF); - if (cmp == XFS_CMP_EXACT) - return -EEXIST; + di = (int)((char *)dep - (char *)curbp->b_addr); + error = -EEXIST; + goto out; + } } + /* Didn't find a match */ + error = -ENOENT; ASSERT(index == leafhdr.count || (args->op_flags & XFS_DA_OP_OKNOENT)); +out: if (curbp) { - if (args->cmpresult == XFS_CMP_DIFFERENT) { - /* Giving back last used data block. */ - state->extravalid = 1; - state->extrablk.bp = curbp; - state->extrablk.index = -1; - state->extrablk.blkno = curdb; - state->extrablk.magic = XFS_DIR2_DATA_MAGIC; - curbp->b_ops = &xfs_dir3_data_buf_ops; - xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF); - } else { - /* If the curbp is not the CI match block, drop it */ - if (state->extrablk.bp != curbp) - xfs_trans_brelse(tp, curbp); - } + /* Giving back last used data block. */ + state->extravalid = 1; + state->extrablk.bp = curbp; + state->extrablk.index = di; + state->extrablk.blkno = curdb; + state->extrablk.magic = XFS_DIR2_DATA_MAGIC; + curbp->b_ops = &xfs_dir3_data_buf_ops; + xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF); } else { state->extravalid = 0; } *indexp = index; - return -ENOENT; + return error; } /* diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c index 5079e05..e69fdb7 100644 --- a/fs/xfs/libxfs/xfs_dir2_sf.c +++ b/fs/xfs/libxfs/xfs_dir2_sf.c @@ -757,19 +757,19 @@ xfs_dir2_sf_lookup( for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { /* - * Compare name and if it's an exact match, return the inode - * number. If it's the first case-insensitive match, store the - * inode number and continue looking for an exact match. + * Compare name and if it's a match, return the inode + * number. */ cmp = dp->i_mount->m_dirnameops->compname(args, sfep->name, sfep->namelen); - if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { + if (cmp != XFS_CMP_DIFFERENT) { args->cmpresult = cmp; args->inumber = dp->d_ops->sf_get_ino(sfp, sfep); args->filetype = dp->d_ops->sf_get_ftype(sfep); if (cmp == XFS_CMP_EXACT) return -EEXIST; ci_sfep = sfep; + break; } } ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 15:41:45 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 7FE167F7E for ; Thu, 11 Sep 2014 15:41:45 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id 516A68F8039; Thu, 11 Sep 2014 13:41:45 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 1A22A4266DC; Thu, 11 Sep 2014 15:41:45 -0500 (CDT) Date: Thu, 11 Sep 2014 15:41:45 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 2/9] xfs: rename XFS_CMP_CASE to XFS_CMP_MATCH Message-ID: <20140911204145.GB13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Rename XFS_CMP_CASE to XFS_CMP_MATCH. With unicode filenames and normalization, different strings will match on other criteria than case insensitivity. Signed-off-by: Olaf Weber --- fs/xfs/libxfs/xfs_da_btree.h | 2 +- fs/xfs/libxfs/xfs_dir2.c | 9 ++++++--- fs/xfs/libxfs/xfs_dir2_node.c | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index 6e153e3..9ebcc23 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -52,7 +52,7 @@ struct xfs_da_geometry { enum xfs_dacmp { XFS_CMP_DIFFERENT, /* names are completely different */ XFS_CMP_EXACT, /* names are exactly the same */ - XFS_CMP_CASE /* names are same but differ in case */ + XFS_CMP_MATCH /* names are same but differ in encoding */ }; /* diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 6cef221..32e769b 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -74,7 +74,7 @@ xfs_ascii_ci_compname( continue; if (tolower(args->name[i]) != tolower(name[i])) return XFS_CMP_DIFFERENT; - result = XFS_CMP_CASE; + result = XFS_CMP_MATCH; } return result; @@ -315,8 +315,11 @@ xfs_dir_cilookup_result( { if (args->cmpresult == XFS_CMP_DIFFERENT) return -ENOENT; - if (args->cmpresult != XFS_CMP_CASE || - !(args->op_flags & XFS_DA_OP_CILOOKUP)) + if (args->cmpresult == XFS_CMP_EXACT) + return -EEXIST; + ASSERT(args->cmpresult == XFS_CMP_MATCH); + /* Only dup the found name if XFS_DA_OP_CILOOKUP is set. */ + if (!(args->op_flags & XFS_DA_OP_CILOOKUP)) return -EEXIST; args->value = kmem_alloc(len, KM_NOFS | KM_MAYFAIL); diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 1778c40..9d46e8d 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -2023,7 +2023,7 @@ xfs_dir2_node_lookup( error = xfs_da3_node_lookup_int(state, &rval); if (error) rval = error; - else if (rval == -ENOENT && args->cmpresult == XFS_CMP_CASE) { + else if (rval == -ENOENT && args->cmpresult == XFS_CMP_MATCH) { /* If a CI match, dup the actual name and return -EEXIST */ xfs_dir2_data_entry_t *dep; -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 15:42:55 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id F05DC7F81 for ; Thu, 11 Sep 2014 15:42:55 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id B8D538F8037; Thu, 11 Sep 2014 13:42:55 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 855524266DC; Thu, 11 Sep 2014 15:42:55 -0500 (CDT) Date: Thu, 11 Sep 2014 15:42:55 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 3/9] xfs: add xfs_nameops.normhash Message-ID: <20140911204255.GC13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Add a normhash callout to the xfs_nameops. This callout takes an xfs_da_args structure as its argument, and calculates a hash value over the name. It may in the process create a normalized form of the name, and assign that to the norm/normlen fields in the xfs_da_args structure. Signed-off-by: Olaf Weber --- fs/xfs/libxfs/xfs_da_btree.c | 9 +++++++++ fs/xfs/libxfs/xfs_da_btree.h | 3 +++ fs/xfs/libxfs/xfs_dir2.c | 42 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 2c42ae2..07a3acf 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -1990,8 +1990,17 @@ xfs_default_hashname( return xfs_da_hashname(name->name, name->len); } +STATIC int +xfs_da_normhash( + struct xfs_da_args *args) +{ + args->hashval = xfs_da_hashname(args->name, args->namelen); + return 0; +} + const struct xfs_nameops xfs_default_nameops = { .hashname = xfs_default_hashname, + .normhash = xfs_da_normhash, .compname = xfs_da_compname }; diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index 9ebcc23..6cdafee 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -61,7 +61,9 @@ enum xfs_dacmp { typedef struct xfs_da_args { struct xfs_da_geometry *geo; /* da block geometry */ const __uint8_t *name; /* string (maybe not NULL terminated) */ + const __uint8_t *norm; /* normalized name (may be NULL) */ int namelen; /* length of string (maybe no NULL) */ + int normlen; /* length of normalized name */ __uint8_t filetype; /* filetype of inode for directories */ __uint8_t *value; /* set of bytes (maybe contain NULLs) */ int valuelen; /* length of value */ @@ -150,6 +152,7 @@ typedef struct xfs_da_state { */ struct xfs_nameops { xfs_dahash_t (*hashname)(struct xfs_name *); + int (*normhash)(struct xfs_da_args *); enum xfs_dacmp (*compname)(struct xfs_da_args *, const unsigned char *, int); }; diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 32e769b..55733a6 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -56,6 +56,21 @@ xfs_ascii_ci_hashname( return hash; } +STATIC int +xfs_ascii_ci_normhash( + struct xfs_da_args *args) +{ + xfs_dahash_t hash; + int i; + + for (i = 0, hash = 0; i < args->namelen; i++) + hash = tolower(args->name[i]) ^ rol32(hash, 7); + + args->hashval = hash; + return 0; +} + + STATIC enum xfs_dacmp xfs_ascii_ci_compname( struct xfs_da_args *args, @@ -82,6 +97,7 @@ xfs_ascii_ci_compname( static struct xfs_nameops xfs_ascii_ci_nameops = { .hashname = xfs_ascii_ci_hashname, + .normhash = xfs_ascii_ci_normhash, .compname = xfs_ascii_ci_compname, }; @@ -267,7 +283,6 @@ xfs_dir_createname( args->name = name->name; args->namelen = name->len; args->filetype = name->type; - args->hashval = dp->i_mount->m_dirnameops->hashname(name); args->inumber = inum; args->dp = dp; args->firstblock = first; @@ -276,6 +291,8 @@ xfs_dir_createname( args->whichfork = XFS_DATA_FORK; args->trans = tp; args->op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; + if ((rval = dp->i_mount->m_dirnameops->normhash(args))) + goto out_free; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_addname(args); @@ -299,6 +316,8 @@ xfs_dir_createname( rval = xfs_dir2_node_addname(args); out_free: + if (args->norm) + kmem_free(args->norm); kmem_free(args); return rval; } @@ -365,13 +384,14 @@ xfs_dir_lookup( args->name = name->name; args->namelen = name->len; args->filetype = name->type; - args->hashval = dp->i_mount->m_dirnameops->hashname(name); args->dp = dp; args->whichfork = XFS_DATA_FORK; args->trans = tp; args->op_flags = XFS_DA_OP_OKNOENT; if (ci_name) args->op_flags |= XFS_DA_OP_CILOOKUP; + if ((rval = dp->i_mount->m_dirnameops->normhash(args))) + goto out_free; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_lookup(args); @@ -405,6 +425,9 @@ out_check_rval: } } out_free: + if (args->norm) + kmem_free(args->norm); + kmem_free(args); return rval; } @@ -437,7 +460,6 @@ xfs_dir_removename( args->name = name->name; args->namelen = name->len; args->filetype = name->type; - args->hashval = dp->i_mount->m_dirnameops->hashname(name); args->inumber = ino; args->dp = dp; args->firstblock = first; @@ -445,6 +467,8 @@ xfs_dir_removename( args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; + if ((rval = dp->i_mount->m_dirnameops->normhash(args))) + goto out_free; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_removename(args); @@ -467,6 +491,8 @@ xfs_dir_removename( else rval = xfs_dir2_node_removename(args); out_free: + if (args->norm) + kmem_free(args->norm); kmem_free(args); return rval; } @@ -502,7 +528,6 @@ xfs_dir_replace( args->name = name->name; args->namelen = name->len; args->filetype = name->type; - args->hashval = dp->i_mount->m_dirnameops->hashname(name); args->inumber = inum; args->dp = dp; args->firstblock = first; @@ -510,6 +535,8 @@ xfs_dir_replace( args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; + if ((rval = dp->i_mount->m_dirnameops->normhash(args))) + goto out_free; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_replace(args); @@ -532,6 +559,8 @@ xfs_dir_replace( else rval = xfs_dir2_node_replace(args); out_free: + if (args->norm) + kmem_free(args->norm); kmem_free(args); return rval; } @@ -564,12 +593,13 @@ xfs_dir_canenter( args->name = name->name; args->namelen = name->len; args->filetype = name->type; - args->hashval = dp->i_mount->m_dirnameops->hashname(name); args->dp = dp; args->whichfork = XFS_DATA_FORK; args->trans = tp; args->op_flags = XFS_DA_OP_JUSTCHECK | XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; + if ((rval = dp->i_mount->m_dirnameops->normhash(args))) + goto out_free; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_addname(args); @@ -592,6 +622,8 @@ xfs_dir_canenter( else rval = xfs_dir2_node_addname(args); out_free: + if (args->norm) + kmem_free(args->norm); kmem_free(args); return rval; } -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 15:43:57 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 88DBE7F86 for ; Thu, 11 Sep 2014 15:43:57 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay2.corp.sgi.com (Postfix) with ESMTP id 336F3304032; Thu, 11 Sep 2014 13:43:57 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 05D524266DC; Thu, 11 Sep 2014 15:43:57 -0500 (CDT) Date: Thu, 11 Sep 2014 15:43:56 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 4/9] xfs: change interface of xfs_nameops.normhash Message-ID: <20140911204356.GD13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber With the introduction of the xfs_nameops.normhash callout, all uses of the hashname callout now occur in places where an xfs_name structure must be explicitly created just to match the parameter passing convention of this callout. Change the arguments to a const unsigned char * and int instead. Signed-off-by: Olaf Weber --- fs/xfs/libxfs/xfs_da_btree.c | 9 +-------- fs/xfs/libxfs/xfs_da_btree.h | 2 +- fs/xfs/libxfs/xfs_dir2.c | 7 ++++--- fs/xfs/libxfs/xfs_dir2_block.c | 2 +- fs/xfs/libxfs/xfs_dir2_data.c | 3 ++- 5 files changed, 9 insertions(+), 14 deletions(-) diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 07a3acf..a0608ca 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -1983,13 +1983,6 @@ xfs_da_compname( XFS_CMP_EXACT : XFS_CMP_DIFFERENT; } -static xfs_dahash_t -xfs_default_hashname( - struct xfs_name *name) -{ - return xfs_da_hashname(name->name, name->len); -} - STATIC int xfs_da_normhash( struct xfs_da_args *args) @@ -1999,7 +1992,7 @@ xfs_da_normhash( } const struct xfs_nameops xfs_default_nameops = { - .hashname = xfs_default_hashname, + .hashname = xfs_da_hashname, .normhash = xfs_da_normhash, .compname = xfs_da_compname }; diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index 6cdafee..4d6b36f 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -151,7 +151,7 @@ typedef struct xfs_da_state { * Name ops for directory and/or attr name operations */ struct xfs_nameops { - xfs_dahash_t (*hashname)(struct xfs_name *); + xfs_dahash_t (*hashname)(const unsigned char *, int); int (*normhash)(struct xfs_da_args *); enum xfs_dacmp (*compname)(struct xfs_da_args *, const unsigned char *, int); diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 55733a6..84e5ca9 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -45,13 +45,14 @@ struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2, XFS_DIR3_FT_DIR }; */ STATIC xfs_dahash_t xfs_ascii_ci_hashname( - struct xfs_name *name) + const unsigned char *name, + int len) { xfs_dahash_t hash; int i; - for (i = 0, hash = 0; i < name->len; i++) - hash = tolower(name->name[i]) ^ rol32(hash, 7); + for (i = 0, hash = 0; i < len; i++) + hash = tolower(name[i]) ^ rol32(hash, 7); return hash; } diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 990bf0c..f93c141 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -1231,7 +1231,7 @@ xfs_dir2_sf_to_block( name.name = sfep->name; name.len = sfep->namelen; blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops-> - hashname(&name)); + hashname(sfep->name, sfep->namelen)); blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr( (char *)dep - (char *)hdr)); offset = (int)((char *)(tagp + 1) - (char *)hdr); diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index fdd803f..28c35cf 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -179,7 +179,8 @@ __xfs_dir3_data_check( ((char *)dep - (char *)hdr)); name.name = dep->name; name.len = dep->namelen; - hash = mp->m_dirnameops->hashname(&name); + hash = mp->m_dirnameops->hashname(dep->name, + dep->namelen); for (i = 0; i < be32_to_cpu(btp->count); i++) { if (be32_to_cpu(lep[i].address) == addr && be32_to_cpu(lep[i].hashval) == hash) -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 15:46:07 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 982DC7F85 for ; Thu, 11 Sep 2014 15:46:07 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id 18338AC00D; Thu, 11 Sep 2014 13:46:07 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id C81D44266DC; Thu, 11 Sep 2014 15:46:06 -0500 (CDT) Date: Thu, 11 Sep 2014 15:46:06 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 5/9] xfs: add a superblock feature bit to indicate UTF-8 support. Message-ID: <20140911204606.GE13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber When UTF-8 support is enabled, the xfs_dir_ci_inode_operations must be installed. Add xfs_sb_version_hasci(), which tests both the borgbit and the utf8bit, and returns true if at least one of them is set. Replace calls to xfs_sb_version_hasasciici() as needed. Signed-off-by: Olaf Weber --- fs/xfs/libxfs/xfs_sb.h | 24 +++++++++++++++++++++++- fs/xfs/xfs_fs.h | 1 + fs/xfs/xfs_fsops.c | 4 +++- fs/xfs/xfs_iops.c | 4 ++-- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h index 2e73970..525eacb 100644 --- a/fs/xfs/libxfs/xfs_sb.h +++ b/fs/xfs/libxfs/xfs_sb.h @@ -70,6 +70,7 @@ struct xfs_trans; #define XFS_SB_VERSION2_RESERVED4BIT 0x00000004 #define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ #define XFS_SB_VERSION2_PARENTBIT 0x00000010 /* parent pointers */ +#define XFS_SB_VERSION2_UTF8BIT 0x00000020 /* utf8 names */ #define XFS_SB_VERSION2_PROJID32BIT 0x00000080 /* 32 bit project id */ #define XFS_SB_VERSION2_CRCBIT 0x00000100 /* metadata CRCs */ #define XFS_SB_VERSION2_FTYPE 0x00000200 /* inode type in dir */ @@ -77,6 +78,7 @@ struct xfs_trans; #define XFS_SB_VERSION2_OKBITS \ (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \ XFS_SB_VERSION2_ATTR2BIT | \ + XFS_SB_VERSION2_UTF8BIT | \ XFS_SB_VERSION2_PROJID32BIT | \ XFS_SB_VERSION2_FTYPE) @@ -509,8 +511,10 @@ xfs_sb_has_ro_compat_feature( } #define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ +#define XFS_SB_FEAT_INCOMPAT_UTF8 (1 << 1) /* utf-8 name support */ #define XFS_SB_FEAT_INCOMPAT_ALL \ - (XFS_SB_FEAT_INCOMPAT_FTYPE) + (XFS_SB_FEAT_INCOMPAT_FTYPE | \ + XFS_SB_FEAT_INCOMPAT_UTF8) #define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool @@ -558,6 +562,24 @@ static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp) (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_FINOBT); } +static inline int xfs_sb_version_hasutf8(xfs_sb_t *sbp) +{ + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 && + xfs_sb_has_incompat_feature(sbp, XFS_SB_FEAT_INCOMPAT_UTF8)) || + (xfs_sb_version_hasmorebits(sbp) && + (sbp->sb_features2 & XFS_SB_VERSION2_UTF8BIT)); +} + +/* + * Special case: there are a number of places where we need to test + * both the borgbit and the utf8bit, and take the same action if + * either of those is set. + */ +static inline int xfs_sb_version_hasci(xfs_sb_t *sbp) +{ + return xfs_sb_version_hasasciici(sbp) || xfs_sb_version_hasutf8(sbp); +} + /* * end of superblock version macros */ diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index 18dc721..e845d75 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h @@ -239,6 +239,7 @@ typedef struct xfs_fsop_resblks { #define XFS_FSOP_GEOM_FLAGS_V5SB 0x8000 /* version 5 superblock */ #define XFS_FSOP_GEOM_FLAGS_FTYPE 0x10000 /* inode directory types */ #define XFS_FSOP_GEOM_FLAGS_FINOBT 0x20000 /* free inode btree */ +#define XFS_FSOP_GEOM_FLAGS_UTF8 0x40000 /* utf8 filenames */ /* * Minimum and maximum sizes need for growth checks. diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index f91de1e..1a83eef 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -103,7 +103,9 @@ xfs_fs_geometry( (xfs_sb_version_hasftype(&mp->m_sb) ? XFS_FSOP_GEOM_FLAGS_FTYPE : 0) | (xfs_sb_version_hasfinobt(&mp->m_sb) ? - XFS_FSOP_GEOM_FLAGS_FINOBT : 0); + XFS_FSOP_GEOM_FLAGS_FINOBT : 0) | + (xfs_sb_version_hasutf8(&mp->m_sb) ? + XFS_FSOP_GEOM_FLAGS_UTF8 : 0); geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ? mp->m_sb.sb_logsectsize : BBSIZE; geo->rtsectsize = mp->m_sb.sb_blocksize; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 7212949..cea3d64 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -335,9 +335,9 @@ xfs_vn_unlink( /* * With unlink, the VFS makes the dentry "negative": no inode, * but still hashed. This is incompatible with case-insensitive - * mode, so invalidate (unhash) the dentry in CI-mode. + * or utf8 mode, so invalidate (unhash) the dentry in CI-mode. */ - if (xfs_sb_version_hasasciici(&XFS_M(dir->i_sb)->m_sb)) + if (xfs_sb_version_hasci(&XFS_M(dir->i_sb)->m_sb)) d_invalidate(dentry); return 0; } -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 15:47:01 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 83AA97F77 for ; Thu, 11 Sep 2014 15:47:01 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id 547EA8F8037; Thu, 11 Sep 2014 13:47:01 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 126524266DC; Thu, 11 Sep 2014 15:47:01 -0500 (CDT) Date: Thu, 11 Sep 2014 15:47:01 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 6/9] xfs: add unicode character database files Message-ID: <20140911204700.GF13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Add files from the Unicode Character Database, version 7.0.0, to the source. A helper program that generates a trie used for normalization from these files is part of a separate commit. Signed-off-by: Olaf Weber --- [v2: Removed large unicode files prior to posting. Get them as below. -bpm] cd fs/xfs/support/ucd wget http://www.unicode.org/Public/7.0.0/ucd/CaseFolding.txt wget http://www.unicode.org/Public/7.0.0/ucd/DerivedAge.txt wget http://www.unicode.org/Public/7.0.0/ucd/extracted/DerivedCombiningClass.txt wget http://www.unicode.org/Public/7.0.0/ucd/DerivedCoreProperties.txt wget http://www.unicode.org/Public/7.0.0/ucd/NormalizationCorrections.txt wget http://www.unicode.org/Public/7.0.0/ucd/NormalizationTest.txt wget http://www.unicode.org/Public/7.0.0/ucd/UnicodeData.txt for e in *.txt do base=`basename $e .txt` mv $e $base-7.0.0.txt done --- fs/xfs/support/ucd/README | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 fs/xfs/support/ucd/README diff --git a/fs/xfs/support/ucd/README b/fs/xfs/support/ucd/README new file mode 100644 index 0000000..d713e66 --- /dev/null +++ b/fs/xfs/support/ucd/README @@ -0,0 +1,33 @@ +The files in this directory are part of the Unicode Character Database +for version 7.0.0 of the Unicode standard. + +The full set of files can be found here: + + http://www.unicode.org/Public/7.0.0/ucd/ + +The latest released version of the UCD can be found here: + + http://www.unicode.org/Public/UCD/latest/ + +The files in this directory are identical, except that they have been +renamed with a suffix indicating the unicode version. + +Individual source links: + + http://www.unicode.org/Public/7.0.0/ucd/CaseFolding.txt + http://www.unicode.org/Public/7.0.0/ucd/DerivedAge.txt + http://www.unicode.org/Public/7.0.0/ucd/extracted/DerivedCombiningClass.txt + http://www.unicode.org/Public/7.0.0/ucd/DerivedCoreProperties.txt + http://www.unicode.org/Public/7.0.0/ucd/NormalizationCorrections.txt + http://www.unicode.org/Public/7.0.0/ucd/NormalizationTest.txt + http://www.unicode.org/Public/7.0.0/ucd/UnicodeData.txt + +md5sums + + 9a92b2bfe56c6719def926bab524fefd CaseFolding-7.0.0.txt + 07b8b1027eb824cf0835314e94f23d2e DerivedAge-7.0.0.txt + 90c3340b16821e2f2153acdbe6fc6180 DerivedCombiningClass-7.0.0.txt + c41c0601f808116f623de47110ed4f93 DerivedCoreProperties-7.0.0.txt + 522720ddfc150d8e63a2518634829bce NormalizationCorrections-7.0.0.txt + 1f35175eba4a2ad795db489f789ae352 NormalizationTest-7.0.0.txt + c8355655731d75e6a3de8c20d7e601ba UnicodeData-7.0.0.txt -- 1.7.12.4 From ctest@reunionesecretariales.info Thu Sep 11 15:48:20 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE,MIME_QP_LONG_LINE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 954F07F89 for ; Thu, 11 Sep 2014 15:48:20 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 670918F8037 for ; Thu, 11 Sep 2014 13:48:20 -0700 (PDT) X-ASG-Debug-ID: 1410468498-04bdf0109a9c6f20001-NocioJ Received: from mail3.reunionesecretariales.info ([192.119.13.37]) by cuda.sgi.com with ESMTP id GJxm9PsKnJvVWMFH for ; Thu, 11 Sep 2014 13:48:18 -0700 (PDT) X-Barracuda-Envelope-From: ctest@reunionesecretariales.info X-Barracuda-Apparent-Source-IP: 192.119.13.37 Received: from WIN-LGANGDUB5R8 (192.119.13.34) by mail3.reunionesecretariales.info id h285320our02 for ; Thu, 11 Sep 2014 15:46:40 -0500 (envelope-from ) pix: fd25f39a-7480-48bc-843f-89413644a548 Message-ID: <947d080b8a8b8412bf0f4afa001a51b1@reunionesecretariales.info> From: "Comercializacion Empresarial" To: Subject: Como Vender sus Productos Date: Thu, 11 Sep 2014 15:46:40 -0500 X-ASG-Orig-Subj: Como Vender sus Productos MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=SPLITOR00A_001_42516996D" X-Barracuda-Connect: UNKNOWN[192.119.13.37] X-Barracuda-Start-Time: 1410468498 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.42 X-Barracuda-Spam-Status: No, SCORE=1.42 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_MJ1963, HTML_MESSAGE, MIME_QP_LONG_LINE, MIME_QP_LONG_LINE_2, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9379 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 MIME_QP_LONG_LINE RAW: Quoted-printable line longer than 76 chars 0.82 MIME_QP_LONG_LINE_2 RAW: Quoted-printable line longer than 76 chars 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 This is a multi-part message in MIME format. ------=SPLITOR00A_001_42516996D Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable =20 C=C3=93MO VENDER SUS PRODUCTOS a las GRANDES CADENAS COMERCIALES M=C3=A9xico, D.F. 03 de octubre 2014 Obtenga informaci=C3=B3n Completa (temario, precios, rese=C3=B1a del = instructor), =C3=BAnicamente responda "GC" + Nombre + Tel=C3=A9fono TEMARIO: 1. Con qui=C3=A9n est=C3=A1 tratando=2E a) Qu=C3=A9 hace un comprador de las grandes cadenas=2E b) Qu=C3=A9 considera al seleccionar a un proveedor=2E c) Qu=C3=A9 considera al seleccionar mercanc=C3=ADa=2E 2. =C2=BFSabe a lo que le tira? a) Lo que debe saber de su cliente=2E b) Cu=C3=A1l es la tienda ideal para su producto=2E c) =C2=BFEst=C3=A1 listo su producto? 3. Prepar=C3=A1ndose para el primer contacto con su cliente=2E a) Lo que debe saber de su empresa=2E b) Lo que debe saber de su producto=2E c) Lo que debe saber de su competencia=2E 4. Costos y precios=2E 5. El momento de la verdad=2E 6. El ma=C3=B1ana=2E 7. C=C3=B3mo saldr=C3=A1n sus pedidos=2E 8. Al ojo del amo=2E Mayores informes e inscripci=C3=B3n, - Solic=C3=ADtala ya L=C3=ADnea directa D.F.: 01 800 212 0660 Si no eres el usuario o si deseas ser borrado: xfs@oss.sgi.com de = nuestro listado de env=C3=ADos s=C3=B3lo responda con la palabra (exf3) y = su solicitud ser=C3=A1 procesada en las pr=C3=B3ximas 48 hrs ------=SPLITOR00A_001_42516996D Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable

 

C=C3=93MO VENDER SUS PRODUCTOS a las GRANDES = CADENAS=20 COMERCIALES
M=C3=A9xico, D.F. 03 de octubre=20 = 2014

Obtenga = informaci=C3=B3n=20 Completa (temario, precios, rese=C3=B1a del instructor), = =C3=BAnicamente=20 responda "GC" + = Nombre +=20 = Tel=C3=A9fono

TEMARIO:
1. Con=20 qui=C3=A9n est=C3=A1 tratando.
a) Qu=C3=A9 hace un = comprador de las=20 grandes cadenas.
b) Qu=C3=A9 considera al seleccionar = a un=20 proveedor.
c) Qu=C3=A9 considera al seleccionar = mercanc=C3=ADa.
2.=20 =C2=BFSabe a lo que le tira?
a) Lo que debe saber de = su=20 cliente.
b) Cu=C3=A1l es la tienda ideal para su = producto.
c)=20 =C2=BFEst=C3=A1 listo su producto?
3. = Prepar=C3=A1ndose para el primer=20 contacto con su cliente.
a) Lo que debe saber de su=20 empresa.
b) Lo que debe saber de su producto.
c) = Lo que=20 debe saber de su competencia.
4. Costos y = precios.
5. El=20 momento de la verdad.
6. El ma=C3=B1ana.
7. = C=C3=B3mo saldr=C3=A1n sus=20 pedidos.
8. Al ojo del=20 = amo.

Mayores informes e inscripci=C3=B3n, - = Solic=C3=ADtala=20 ya
L=C3=ADnea directa D.F.: 01 800 212 0660

Si no = eres el=20 usuario o si deseas ser borrado:  xfs@oss.sgi.com =  de=20 nuestro listado de env=C3=ADos s=C3=B3lo responda con la = palabra (exf3)=20 y su solicitud ser=C3=A1 procesada en las pr=C3=B3ximas = 48=20 = hrs

 

------=SPLITOR00A_001_42516996D-- From bpm@sgi.com Thu Sep 11 15:48:19 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD, T_FILL_THIS_FORM_SHORT autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A87B57F85 for ; Thu, 11 Sep 2014 15:48:18 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id EB926AC001; Thu, 11 Sep 2014 13:48:17 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 485F74266DC; Thu, 11 Sep 2014 15:48:17 -0500 (CDT) Date: Thu, 11 Sep 2014 15:48:17 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 7/9] xfs: add trie generator and supporting code for UTF-8. Message-ID: <20140911204817.GG13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber mkutf8data.c is the source for a program that generates utf8data.h, which contains the trie that utf8norm.c uses. The trie is generated from the Unicode 7.0.0 data files. The format of the utf8data[] table is described in utf8norm.c. Supporting functions for UTF-8 normalization are in utf8norm.c with the header utf8norm.h. Two normalization forms are supported: nfkdi and nfkdicf. nfkdi: - Apply unicode normalization form NFKD. - Remove any Default_Ignorable_Code_Point. nfkdicf: - Apply unicode normalization form NFKD. - Remove any Default_Ignorable_Code_Point. - Apply a full casefold (C + F). For the purposes of the code, a string is valid UTF-8 if: - The values encoded are 0x1..0x10FFFF. - The surrogate codepoints 0xD800..0xDFFFF are not encoded. - The shortest possible encoding is used for all values. The supporting functions work on null-terminated strings (utf8 prefix) and on length-limited strings (utf8n prefix). Signed-off-by: Olaf Weber --- fs/xfs/Makefile | 19 + fs/xfs/support/mkutf8data.c | 3239 +++++++++++++++++++++++++++++++++++++++++++ fs/xfs/support/utf8norm.c | 641 +++++++++ fs/xfs/support/utf8norm.h | 111 ++ 4 files changed, 4010 insertions(+) create mode 100644 fs/xfs/support/mkutf8data.c create mode 100644 fs/xfs/support/utf8norm.c create mode 100644 fs/xfs/support/utf8norm.h diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index d617999..0f7b300 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -92,6 +92,25 @@ xfs-y += xfs_aops.o \ kmem.o \ uuid.o +# Objects in support/ +xfs-y += support/utf8norm.o + +hostprogs-y := support/mkutf8data +$(obj)/support/utf8norm.o: $(obj)/support/utf8data.h +$(obj)/support/utf8data.h: $(src)/support/ucd/*.txt +$(obj)/support/utf8data.h: $(obj)/support/mkutf8data FORCE + $(call if_changed,mkutf8data) +quiet_cmd_mkutf8data = MKUTF8DATA $@ + cmd_mkutf8data = $(obj)/support/mkutf8data \ + -a $(src)/support/ucd/DerivedAge-7.0.0.txt \ + -c $(src)/support/ucd/DerivedCombiningClass-7.0.0.txt \ + -p $(src)/support/ucd/DerivedCoreProperties-7.0.0.txt \ + -d $(src)/support/ucd/UnicodeData-7.0.0.txt \ + -f $(src)/support/ucd/CaseFolding-7.0.0.txt \ + -n $(src)/support/ucd/NormalizationCorrections-7.0.0.txt \ + -t $(src)/support/ucd/NormalizationTest-7.0.0.txt \ + -o $@ + # low-level transaction/log code xfs-y += xfs_log.o \ xfs_log_cil.o \ diff --git a/fs/xfs/support/mkutf8data.c b/fs/xfs/support/mkutf8data.c new file mode 100644 index 0000000..cff7a1e --- /dev/null +++ b/fs/xfs/support/mkutf8data.c @@ -0,0 +1,3239 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Generator for a compact trie for unicode normalization */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Default names of the in- and output files. */ + +#define AGE_NAME "DerivedAge.txt" +#define CCC_NAME "DerivedCombiningClass.txt" +#define PROP_NAME "DerivedCoreProperties.txt" +#define DATA_NAME "UnicodeData.txt" +#define FOLD_NAME "CaseFolding.txt" +#define NORM_NAME "NormalizationCorrections.txt" +#define TEST_NAME "NormalizationTest.txt" +#define UTF8_NAME "utf8data.h" + +const char *age_name = AGE_NAME; +const char *ccc_name = CCC_NAME; +const char *prop_name = PROP_NAME; +const char *data_name = DATA_NAME; +const char *fold_name = FOLD_NAME; +const char *norm_name = NORM_NAME; +const char *test_name = TEST_NAME; +const char *utf8_name = UTF8_NAME; + +int verbose = 0; + +/* An arbitrary line size limit on input lines. */ + +#define LINESIZE 1024 +char line[LINESIZE]; +char buf0[LINESIZE]; +char buf1[LINESIZE]; +char buf2[LINESIZE]; +char buf3[LINESIZE]; + +const char *argv0; + +/* ------------------------------------------------------------------ */ + +/* + * Unicode version numbers consist of three parts: major, minor, and a + * revision. These numbers are packed into an unsigned int to obtain + * a single version number. + * + * To save space in the generated trie, the unicode version is not + * stored directly, instead we calculate a generation number from the + * unicode versions seen in the DerivedAge file, and use that as an + * index into a table of unicode versions. + */ +#define UNICODE_MAJ_SHIFT (16) +#define UNICODE_MIN_SHIFT (8) + +#define UNICODE_MAJ_MAX ((unsigned short)-1) +#define UNICODE_MIN_MAX ((unsigned char)-1) +#define UNICODE_REV_MAX ((unsigned char)-1) + +#define UNICODE_AGE(MAJ,MIN,REV) \ + (((unsigned int)(MAJ) << UNICODE_MAJ_SHIFT) | \ + ((unsigned int)(MIN) << UNICODE_MIN_SHIFT) | \ + ((unsigned int)(REV))) + +unsigned int *ages; +int ages_count; + +unsigned int unicode_maxage; + +static int +age_valid(unsigned int major, unsigned int minor, unsigned int revision) +{ + if (major > UNICODE_MAJ_MAX) + return 0; + if (minor > UNICODE_MIN_MAX) + return 0; + if (revision > UNICODE_REV_MAX) + return 0; + return 1; +} + +/* ------------------------------------------------------------------ */ + +/* + * utf8trie_t + * + * A compact binary tree, used to decode UTF-8 characters. + * + * Internal nodes are one byte for the node itself, and up to three + * bytes for an offset into the tree. The first byte contains the + * following information: + * NEXTBYTE - flag - advance to next byte if set + * BITNUM - 3 bit field - the bit number to tested + * OFFLEN - 2 bit field - number of bytes in the offset + * if offlen == 0 (non-branching node) + * RIGHTPATH - 1 bit field - set if the following node is for the + * right-hand path (tested bit is set) + * TRIENODE - 1 bit field - set if the following node is an internal + * node, otherwise it is a leaf node + * if offlen != 0 (branching node) + * LEFTNODE - 1 bit field - set if the left-hand node is internal + * RIGHTNODE - 1 bit field - set if the right-hand node is internal + * + * Due to the way utf8 works, there cannot be branching nodes with + * NEXTBYTE set, and moreover those nodes always have a righthand + * descendant. + */ +typedef unsigned char utf8trie_t; +#define BITNUM 0x07 +#define NEXTBYTE 0x08 +#define OFFLEN 0x30 +#define OFFLEN_SHIFT 4 +#define RIGHTPATH 0x40 +#define TRIENODE 0x80 +#define RIGHTNODE 0x40 +#define LEFTNODE 0x80 + +/* + * utf8leaf_t + * + * The leaves of the trie are embedded in the trie, and so the same + * underlying datatype, unsigned char. + * + * leaf[0]: The unicode version, stored as a generation number that is + * an index into utf8agetab[]. With this we can filter code + * points based on the unicode version in which they were + * defined. The CCC of a non-defined code point is 0. + * leaf[1]: Canonical Combining Class. During normalization, we need + * to do a stable sort into ascending order of all characters + * with a non-zero CCC that occur between two characters with + * a CCC of 0, or at the begin or end of a string. + * The unicode standard guarantees that all CCC values are + * between 0 and 254 inclusive, which leaves 255 available as + * a special value. + * Code points with CCC 0 are known as stoppers. + * leaf[2]: Decomposition. If leaf[1] == 255, then leaf[2] is the + * start of a NUL-terminated string that is the decomposition + * of the character. + * The CCC of a decomposable character is the same as the CCC + * of the first character of its decomposition. + * Some characters decompose as the empty string: these are + * characters with the Default_Ignorable_Code_Point property. + * These do affect normalization, as they all have CCC 0. + * + * The decompositions in the trie have been fully expanded. + * + * Casefolding, if applicable, is also done using decompositions. + */ +typedef unsigned char utf8leaf_t; + +#define LEAF_GEN(LEAF) ((LEAF)[0]) +#define LEAF_CCC(LEAF) ((LEAF)[1]) +#define LEAF_STR(LEAF) ((const char*)((LEAF) + 2)) + +#define MAXGEN (255) + +#define MINCCC (0) +#define MAXCCC (254) +#define STOPPER (0) +#define DECOMPOSE (255) + +struct tree; +static utf8leaf_t *utf8nlookup(struct tree *, const char *, size_t); +static utf8leaf_t *utf8lookup(struct tree *, const char *); + +unsigned char *utf8data; +size_t utf8data_size; + +utf8trie_t *nfkdi; +utf8trie_t *nfkdicf; + +/* ------------------------------------------------------------------ */ + +/* + * UTF8 valid ranges. + * + * The UTF-8 encoding spreads the bits of a 32bit word over several + * bytes. This table gives the ranges that can be held and how they'd + * be represented. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000000 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000000 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * There is an additional requirement on UTF-8, in that only the + * shortest representation of a 32bit value is to be used. A decoder + * must not decode sequences that do not satisfy this requirement. + * Thus the allowed ranges have a lower bound. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000080 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000800 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00010000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00200000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x04000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Actual unicode characters are limited to the range 0x0 - 0x10FFFF, + * 17 planes of 65536 values. This limits the sequences actually seen + * even more, to just the following. + * + * 0 - 0x7f: 0 0x7f + * 0x80 - 0x7ff: 0xc2 0x80 0xdf 0xbf + * 0x800 - 0xffff: 0xe0 0xa0 0x80 0xef 0xbf 0xbf + * 0x10000 - 0x10ffff: 0xf0 0x90 0x80 0x80 0xf4 0x8f 0xbf 0xbf + * + * Even within those ranges not all values are allowed: the surrogates + * 0xd800 - 0xdfff should never be seen. + * + * Note that the longest sequence seen with valid usage is 4 bytes, + * the same a single UTF-32 character. This makes the UTF-8 + * representation of Unicode strictly smaller than UTF-32. + * + * The shortest sequence requirement was introduced by: + * Corrigendum #1: UTF-8 Shortest Form + * It can be found here: + * http://www.unicode.org/versions/corrigendum1.html + * + */ + +#define UTF8_2_BITS 0xC0 +#define UTF8_3_BITS 0xE0 +#define UTF8_4_BITS 0xF0 +#define UTF8_N_BITS 0x80 +#define UTF8_2_MASK 0xE0 +#define UTF8_3_MASK 0xF0 +#define UTF8_4_MASK 0xF8 +#define UTF8_N_MASK 0xC0 +#define UTF8_V_MASK 0x3F +#define UTF8_V_SHIFT 6 + +static int +utf8key(unsigned int key, char keyval[]) +{ + int keylen; + + if (key < 0x80) { + keyval[0] = key; + keylen = 1; + } else if (key < 0x800) { + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_2_BITS; + keylen = 2; + } else if (key < 0x10000) { + keyval[2] = key & UTF8_V_MASK; + keyval[2] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_3_BITS; + keylen = 3; + } else if (key < 0x110000) { + keyval[3] = key & UTF8_V_MASK; + keyval[3] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[2] = key & UTF8_V_MASK; + keyval[2] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_4_BITS; + keylen = 4; + } else { + printf("%#x: illegal key\n", key); + keylen = 0; + } + return keylen; +} + +static unsigned int +utf8code(const char *str) +{ + const unsigned char *s = (const unsigned char*)str; + unsigned int unichar = 0; + + if (*s < 0x80) { + unichar = *s; + } else if (*s < UTF8_3_BITS) { + unichar = *s++ & 0x1F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } else if (*s < UTF8_4_BITS) { + unichar = *s++ & 0x0F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } else { + unichar = *s++ & 0x0F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } + return unichar; +} + +static int +utf32valid(unsigned int unichar) +{ + return unichar < 0x110000; +} + +#define NODE 1 +#define LEAF 0 + +struct tree { + void *root; + int childnode; + const char *type; + unsigned int maxage; + struct tree *next; + int (*leaf_equal)(void *, void *); + void (*leaf_print)(void *, int); + int (*leaf_mark)(void *); + int (*leaf_size)(void *); + int *(*leaf_index)(struct tree *, void *); + unsigned char *(*leaf_emit)(void *, unsigned char *); + int leafindex[0x110000]; + int index; +}; + +struct node { + int index; + int offset; + int mark; + int size; + struct node *parent; + void *left; + void *right; + unsigned char bitnum; + unsigned char nextbyte; + unsigned char leftnode; + unsigned char rightnode; + unsigned int keybits; + unsigned int keymask; +}; + +/* + * Example lookup function for a tree. + */ +static void * +lookup(struct tree *tree, const char *key) +{ + struct node *node; + void *leaf = NULL; + + node = tree->root; + while (!leaf && node) { + if (node->nextbyte) + key++; + if (*key & (1 << (node->bitnum & 7))) { + /* Right leg */ + if (node->rightnode == NODE) { + node = node->right; + } else if (node->rightnode == LEAF) { + leaf = node->right; + } else { + node = NULL; + } + } else { + /* Left leg */ + if (node->leftnode == NODE) { + node = node->left; + } else if (node->leftnode == LEAF) { + leaf = node->left; + } else { + node = NULL; + } + } + } + + return leaf; +} + +/* + * A simple non-recursive tree walker: keep track of visits to the + * left and right branches in the leftmask and rightmask. + */ +static void +tree_walk(struct tree *tree) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int indent = 1; + int nodes, singletons, leaves; + + nodes = singletons = leaves = 0; + + printf("%s_%x root %p\n", tree->type, tree->maxage, tree->root); + if (tree->childnode == LEAF) { + assert(tree->root); + tree->leaf_print(tree->root, indent); + leaves = 1; + } else { + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + printf("%*snode @ %p bitnum %d nextbyte %d" + " left %p right %p mask %x bits %x\n", + indent, "", node, + node->bitnum, node->nextbyte, + node->left, node->right, + node->keymask, node->keybits); + nodes += 1; + if (!(node->left && node->right)) + singletons += 1; + + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + tree->leaf_print(node->left, + indent+1); + leaves += 1; + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + tree->leaf_print(node->right, + indent+1); + leaves += 1; + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } + } + printf("nodes %d leaves %d singletons %d\n", + nodes, leaves, singletons); +} + +/* + * Allocate an initialize a new internal node. + */ +static struct node * +alloc_node(struct node *parent) +{ + struct node *node; + int bitnum; + + node = malloc(sizeof(*node)); + node->left = node->right = NULL; + node->parent = parent; + node->leftnode = NODE; + node->rightnode = NODE; + node->keybits = 0; + node->keymask = 0; + node->mark = 0; + node->index = 0; + node->offset = -1; + node->size = 4; + + if (node->parent) { + bitnum = parent->bitnum; + if ((bitnum & 7) == 0) { + node->bitnum = bitnum + 7 + 8; + node->nextbyte = 1; + } else { + node->bitnum = bitnum - 1; + node->nextbyte = 0; + } + } else { + node->bitnum = 7; + node->nextbyte = 0; + } + + return node; +} + +/* + * Insert a new leaf into the tree, and collapse any subtrees that are + * fully populated and end in identical leaves. A nextbyte tagged + * internal node will not be removed to preserve the tree's integrity. + * Note that due to the structure of utf8, no nextbyte tagged node + * will be a candidate for removal. + */ +static int +insert(struct tree *tree, char *key, int keylen, void *leaf) +{ + struct node *node; + struct node *parent; + void **cursor; + int keybits; + + assert(keylen >= 1 && keylen <= 4); + + node = NULL; + cursor = &tree->root; + keybits = 8 * keylen; + + /* Insert, creating path along the way. */ + while (keybits) { + if (!*cursor) + *cursor = alloc_node(node); + node = *cursor; + if (node->nextbyte) + key++; + if (*key & (1 << (node->bitnum & 7))) + cursor = &node->right; + else + cursor = &node->left; + keybits--; + } + *cursor = leaf; + + /* Merge subtrees if possible. */ + while (node) { + if (*key & (1 << (node->bitnum & 7))) + node->rightnode = LEAF; + else + node->leftnode = LEAF; + if (node->nextbyte) + break; + if (node->leftnode == NODE || node->rightnode == NODE) + break; + assert(node->left); + assert(node->right); + /* Compare */ + if (! tree->leaf_equal(node->left, node->right)) + break; + /* Keep left, drop right leaf. */ + leaf = node->left; + /* Check in parent */ + parent = node->parent; + if (!parent) { + /* root of tree! */ + tree->root = leaf; + tree->childnode = LEAF; + } else if (parent->left == node) { + parent->left = leaf; + parent->leftnode = LEAF; + if (parent->right) { + parent->keymask = 0; + parent->keybits = 0; + } else { + parent->keymask |= (1 << node->bitnum); + } + } else if (parent->right == node) { + parent->right = leaf; + parent->rightnode = LEAF; + if (parent->left) { + parent->keymask = 0; + parent->keybits = 0; + } else { + parent->keymask |= (1 << node->bitnum); + parent->keybits |= (1 << node->bitnum); + } + } else { + /* internal tree error */ + assert(0); + } + free(node); + node = parent; + } + + /* Propagate keymasks up along singleton chains. */ + while (node) { + parent = node->parent; + if (!parent) + break; + /* Nix the mask for parents with two children. */ + if (node->keymask == 0) { + parent->keymask = 0; + parent->keybits = 0; + } else if (parent->left && parent->right) { + parent->keymask = 0; + parent->keybits = 0; + } else { + assert((parent->keymask & node->keymask) == 0); + parent->keymask |= node->keymask; + parent->keymask |= (1 << parent->bitnum); + parent->keybits |= node->keybits; + if (parent->right) + parent->keybits |= (1 << parent->bitnum); + } + node = parent; + } + + return 0; +} + +/* + * Prune internal nodes. + * + * Fully populated subtrees that end at the same leaf have already + * been collapsed. There are still internal nodes that have for both + * their left and right branches a sequence of singletons that make + * identical choices and end in identical leaves. The keymask and + * keybits collected in the nodes describe the choices made in these + * singleton chains. When they are identical for the left and right + * branch of a node, and the two leaves comare identical, the node in + * question can be removed. + * + * Note that nodes with the nextbyte tag set will not be removed by + * this to ensure tree integrity. Note as well that the structure of + * utf8 ensures that these nodes would not have been candidates for + * removal in any case. + */ +static void +prune(struct tree *tree) +{ + struct node *node; + struct node *left; + struct node *right; + struct node *parent; + void *leftleaf; + void *rightleaf; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int count; + + if (verbose > 0) + printf("Pruning %s_%x\n", tree->type, tree->maxage); + + count = 0; + if (tree->childnode == LEAF) + return; + if (!tree->root) + return; + + leftmask = rightmask = 0; + node = tree->root; + while (node) { + if (node->nextbyte) + goto advance; + if (node->leftnode == LEAF) + goto advance; + if (node->rightnode == LEAF) + goto advance; + if (!node->left) + goto advance; + if (!node->right) + goto advance; + left = node->left; + right = node->right; + if (left->keymask == 0) + goto advance; + if (right->keymask == 0) + goto advance; + if (left->keymask != right->keymask) + goto advance; + if (left->keybits != right->keybits) + goto advance; + leftleaf = NULL; + while (!leftleaf) { + assert(left->left || left->right); + if (left->leftnode == LEAF) + leftleaf = left->left; + else if (left->rightnode == LEAF) + leftleaf = left->right; + else if (left->left) + left = left->left; + else if (left->right) + left = left->right; + else + assert(0); + } + rightleaf = NULL; + while (!rightleaf) { + assert(right->left || right->right); + if (right->leftnode == LEAF) + rightleaf = right->left; + else if (right->rightnode == LEAF) + rightleaf = right->right; + else if (right->left) + right = right->left; + else if (right->right) + right = right->right; + else + assert(0); + } + if (! tree->leaf_equal(leftleaf, rightleaf)) + goto advance; + /* + * This node has identical singleton-only subtrees. + * Remove it. + */ + parent = node->parent; + left = node->left; + right = node->right; + if (parent->left == node) + parent->left = left; + else if (parent->right == node) + parent->right = left; + else + assert(0); + left->parent = parent; + left->keymask |= (1 << node->bitnum); + node->left = NULL; + while (node) { + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + if (node->leftnode == NODE && node->left) { + left = node->left; + free(node); + count++; + node = left; + } else if (node->rightnode == NODE && node->right) { + right = node->right; + free(node); + count++; + node = right; + } else { + node = NULL; + } + } + /* Propagate keymasks up along singleton chains. */ + node = parent; + /* Force re-check */ + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + for (;;) { + if (node->left && node->right) + break; + if (node->left) { + left = node->left; + node->keymask |= left->keymask; + node->keybits |= left->keybits; + } + if (node->right) { + right = node->right; + node->keymask |= right->keymask; + node->keybits |= right->keybits; + } + node->keymask |= (1 << node->bitnum); + node = node->parent; + /* Force re-check */ + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + } + advance: + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0 && + node->leftnode == NODE && + node->left) { + leftmask |= bitmask; + node = node->left; + } else if ((rightmask & bitmask) == 0 && + node->rightnode == NODE && + node->right) { + rightmask |= bitmask; + node = node->right; + } else { + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } + } + if (verbose > 0) + printf("Pruned %d nodes\n", count); +} + +/* + * Mark the nodes in the tree that lead to leaves that must be + * emitted. + */ +static void +mark_nodes(struct tree *tree) +{ + struct node *node; + struct node *n; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int marked; + + marked = 0; + if (verbose > 0) + printf("Marking %s_%x\n", tree->type, tree->maxage); + if (tree->childnode == LEAF) + goto done; + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + if (tree->leaf_mark(node->left)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->left) { + assert(node->leftnode == NODE); + node = node->left; + continue; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + if (tree->leaf_mark(node->right)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->right) { + assert(node->rightnode==NODE); + node = node->right; + continue; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } + + /* second pass: left siblings and singletons */ + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + if (tree->leaf_mark(node->left)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->left) { + assert(node->leftnode == NODE); + node = node->left; + if (!node->mark && node->parent->mark) { + marked++; + node->mark = 1; + } + continue; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + if (tree->leaf_mark(node->right)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->right) { + assert(node->rightnode==NODE); + node = node->right; + if (!node->mark && node->parent->mark && + !node->parent->left) { + marked++; + node->mark = 1; + } + continue; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } +done: + if (verbose > 0) + printf("Marked %d nodes\n", marked); +} + +/* + * Compute the index of each node and leaf, which is the offset in the + * emitted trie. These value must be pre-computed because relative + * offsets between nodes are used to navigate the tree. + */ +static int +index_nodes(struct tree *tree, int index) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int count; + int indent; + + /* Align to a cache line (or half a cache line?). */ + while (index % 64) + index++; + tree->index = index; + indent = 1; + count = 0; + + if (verbose > 0) + printf("Indexing %s_%x: %d", tree->type, tree->maxage, index); + if (tree->childnode == LEAF) { + index += tree->leaf_size(tree->root); + goto done; + } + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + count++; + if (node->index != index) + node->index = index; + index += node->size; +skip: + while (node) { + bitmask = 1 << node->bitnum; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + *tree->leaf_index(tree, node->left) = + index; + index += tree->leaf_size(node->left); + count++; + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + *tree->leaf_index(tree, node->right) = index; + index += tree->leaf_size(node->right); + count++; + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +done: + /* Round up to a multiple of 16 */ + while (index % 16) + index++; + if (verbose > 0) + printf("Final index %d\n", index); + return index; +} + +/* + * Compute the size of nodes and leaves. We start by assuming that + * each node needs to store a three-byte offset. The indexes of the + * nodes are calculated based on that, and then this function is + * called to see if the sizes of some nodes can be reduced. This is + * repeated until no more changes are seen. + */ +static int +size_nodes(struct tree *tree) +{ + struct tree *next; + struct node *node; + struct node *right; + struct node *n; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + unsigned int pathbits; + unsigned int pathmask; + int changed; + int offset; + int size; + int indent; + + indent = 1; + changed = 0; + size = 0; + + if (verbose > 0) + printf("Sizing %s_%x", tree->type, tree->maxage); + if (tree->childnode == LEAF) + goto done; + + assert(tree->childnode == NODE); + pathbits = 0; + pathmask = 0; + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + offset = 0; + if (!node->left || !node->right) { + size = 1; + } else { + if (node->rightnode == NODE) { + right = node->right; + next = tree->next; + while (!right->mark) { + assert(next); + n = next->root; + while (n->bitnum != node->bitnum) { + if (pathbits & (1<bitnum)) + n = n->right; + else + n = n->left; + } + n = n->right; + assert(right->bitnum == n->bitnum); + right = n; + next = next->next; + } + offset = right->index - node->index; + } else { + offset = *tree->leaf_index(tree, node->right); + offset -= node->index; + } + assert(offset >= 0); + assert(offset <= 0xffffff); + if (offset <= 0xff) { + size = 2; + } else if (offset <= 0xffff) { + size = 3; + } else { /* offset <= 0xffffff */ + size = 4; + } + } + if (node->size != size || node->offset != offset) { + node->size = size; + node->offset = offset; + changed++; + } +skip: + while (node) { + bitmask = 1 << node->bitnum; + pathmask |= bitmask; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + pathbits |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + pathmask &= ~bitmask; + pathbits &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +done: + if (verbose > 0) + printf("Found %d changes\n", changed); + return changed; +} + +/* + * Emit a trie for the given tree into the data array. + */ +static void +emit(struct tree *tree, unsigned char *data) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int offlen; + int offset; + int index; + int indent; + unsigned char byte; + + index = tree->index; + data += index; + indent = 1; + if (verbose > 0) + printf("Emitting %s_%x\n", tree->type, tree->maxage); + if (tree->childnode == LEAF) { + assert(tree->root); + tree->leaf_emit(tree->root, data); + return; + } + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + assert(node->offset != -1); + assert(node->index == index); + + byte = 0; + if (node->nextbyte) + byte |= NEXTBYTE; + byte |= (node->bitnum & BITNUM); + if (node->left && node->right) { + if (node->leftnode == NODE) + byte |= LEFTNODE; + if (node->rightnode == NODE) + byte |= RIGHTNODE; + if (node->offset <= 0xff) + offlen = 1; + else if (node->offset <= 0xffff) + offlen = 2; + else + offlen = 3; + offset = node->offset; + byte |= offlen << OFFLEN_SHIFT; + *data++ = byte; + index++; + while (offlen--) { + *data++ = offset & 0xff; + index++; + offset >>= 8; + } + } else if (node->left) { + if (node->leftnode == NODE) + byte |= TRIENODE; + *data++ = byte; + index++; + } else if (node->right) { + byte |= RIGHTNODE; + if (node->rightnode == NODE) + byte |= TRIENODE; + *data++ = byte; + index++; + } else { + assert(0); + } +skip: + while (node) { + bitmask = 1 << node->bitnum; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + data = tree->leaf_emit(node->left, + data); + index += tree->leaf_size(node->left); + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + data = tree->leaf_emit(node->right, + data); + index += tree->leaf_size(node->right); + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +} + +/* ------------------------------------------------------------------ */ + +/* + * Unicode data. + * + * We need to keep track of the Canonical Combining Class, the Age, + * and decompositions for a code point. + * + * For the Age, we store the index into the ages table. Effectively + * this is a generation number that the table maps to a unicode + * version. + * + * The correction field is used to indicate that this entry is in the + * corrections array, which contains decompositions that were + * corrected in later revisions. The value of the correction field is + * the Unicode version in which the mapping was corrected. + */ +struct unicode_data { + unsigned int code; + int ccc; + int gen; + int correction; + unsigned int *utf32nfkdi; + unsigned int *utf32nfkdicf; + char *utf8nfkdi; + char *utf8nfkdicf; +}; + +struct unicode_data unicode_data[0x110000]; +struct unicode_data *corrections; +int corrections_count; + +struct tree *nfkdi_tree; +struct tree *nfkdicf_tree; + +struct tree *trees; +int trees_count; + +/* + * Check the corrections array to see if this entry was corrected at + * some point. + */ +static struct unicode_data * +corrections_lookup(struct unicode_data *u) +{ + int i; + + for (i = 0; i != corrections_count; i++) + if (u->code == corrections[i].code) + return &corrections[i]; + return u; +} + +static int +nfkdi_equal(void *l, void *r) +{ + struct unicode_data *left = l; + struct unicode_data *right = r; + + if (left->gen != right->gen) + return 0; + if (left->ccc != right->ccc) + return 0; + if (left->utf8nfkdi && right->utf8nfkdi && + strcmp(left->utf8nfkdi, right->utf8nfkdi) == 0) + return 1; + if (left->utf8nfkdi || right->utf8nfkdi) + return 0; + return 1; +} + +static int +nfkdicf_equal(void *l, void *r) +{ + struct unicode_data *left = l; + struct unicode_data *right = r; + + if (left->gen != right->gen) + return 0; + if (left->ccc != right->ccc) + return 0; + if (left->utf8nfkdicf && right->utf8nfkdicf && + strcmp(left->utf8nfkdicf, right->utf8nfkdicf) == 0) + return 1; + if (left->utf8nfkdicf && right->utf8nfkdicf) + return 0; + if (left->utf8nfkdicf || right->utf8nfkdicf) + return 0; + if (left->utf8nfkdi && right->utf8nfkdi && + strcmp(left->utf8nfkdi, right->utf8nfkdi) == 0) + return 1; + if (left->utf8nfkdi || right->utf8nfkdi) + return 0; + return 1; +} + +static void +nfkdi_print(void *l, int indent) +{ + struct unicode_data *leaf = l; + + printf("%*sleaf @ %p code %X ccc %d gen %d", indent, "", leaf, + leaf->code, leaf->ccc, leaf->gen); + if (leaf->utf8nfkdi) + printf(" nfkdi \"%s\"", (const char*)leaf->utf8nfkdi); + printf("\n"); +} + +static void +nfkdicf_print(void *l, int indent) +{ + struct unicode_data *leaf = l; + + printf("%*sleaf @ %p code %X ccc %d gen %d", indent, "", leaf, + leaf->code, leaf->ccc, leaf->gen); + if (leaf->utf8nfkdicf) + printf(" nfkdicf \"%s\"", (const char*)leaf->utf8nfkdicf); + else if (leaf->utf8nfkdi) + printf(" nfkdi \"%s\"", (const char*)leaf->utf8nfkdi); + printf("\n"); +} + +static int +nfkdi_mark(void *l) +{ + return 1; +} + +static int +nfkdicf_mark(void *l) +{ + struct unicode_data *leaf = l; + + if (leaf->utf8nfkdicf) + return 1; + return 0; +} + +static int +correction_mark(void *l) +{ + struct unicode_data *leaf = l; + + return leaf->correction; +} + +static int +nfkdi_size(void *l) +{ + struct unicode_data *leaf = l; + + int size = 2; + if (leaf->utf8nfkdi) + size += strlen(leaf->utf8nfkdi) + 1; + return size; +} + +static int +nfkdicf_size(void *l) +{ + struct unicode_data *leaf = l; + + int size = 2; + if (leaf->utf8nfkdicf) + size += strlen(leaf->utf8nfkdicf) + 1; + else if (leaf->utf8nfkdi) + size += strlen(leaf->utf8nfkdi) + 1; + return size; +} + +static int * +nfkdi_index(struct tree *tree, void *l) +{ + struct unicode_data *leaf = l; + + return &tree->leafindex[leaf->code]; +} + +static int * +nfkdicf_index(struct tree *tree, void *l) +{ + struct unicode_data *leaf = l; + + return &tree->leafindex[leaf->code]; +} + +static unsigned char * +nfkdi_emit(void *l, unsigned char *data) +{ + struct unicode_data *leaf = l; + unsigned char *s; + + *data++ = leaf->gen; + if (leaf->utf8nfkdi) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdi; + while ((*data++ = *s++) != 0) + ; + } else { + *data++ = leaf->ccc; + } + return data; +} + +static unsigned char * +nfkdicf_emit(void *l, unsigned char *data) +{ + struct unicode_data *leaf = l; + unsigned char *s; + + *data++ = leaf->gen; + if (leaf->utf8nfkdicf) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdicf; + while ((*data++ = *s++) != 0) + ; + } else if (leaf->utf8nfkdi) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdi; + while ((*data++ = *s++) != 0) + ; + } else { + *data++ = leaf->ccc; + } + return data; +} + +static void +utf8_create(struct unicode_data *data) +{ + char utf[18*4+1]; + char *u; + unsigned int *um; + int i; + + u = utf; + um = data->utf32nfkdi; + if (um) { + for (i = 0; um[i]; i++) + u += utf8key(um[i], u); + *u = '\0'; + data->utf8nfkdi = strdup((char*)utf); + } + u = utf; + um = data->utf32nfkdicf; + if (um) { + for (i = 0; um[i]; i++) + u += utf8key(um[i], u); + *u = '\0'; + if (!data->utf8nfkdi || strcmp(data->utf8nfkdi, (char*)utf)) + data->utf8nfkdicf = strdup((char*)utf); + } +} + +static void +utf8_init(void) +{ + unsigned int unichar; + int i; + + for (unichar = 0; unichar != 0x110000; unichar++) + utf8_create(&unicode_data[unichar]); + + for (i = 0; i != corrections_count; i++) + utf8_create(&corrections[i]); +} + +static void +trees_init(void) +{ + struct unicode_data *data; + unsigned int maxage; + unsigned int nextage; + int count; + int i; + int j; + + /* Count the number of different ages. */ + count = 0; + nextage = (unsigned int)-1; + do { + maxage = nextage; + nextage = 0; + for (i = 0; i <= corrections_count; i++) { + data = &corrections[i]; + if (nextage < data->correction && + data->correction < maxage) + nextage = data->correction; + } + count++; + } while (nextage); + + /* Two trees per age: nfkdi and nfkdicf */ + trees_count = count * 2; + trees = calloc(trees_count, sizeof(struct tree)); + + /* Assign ages to the trees. */ + count = trees_count; + nextage = (unsigned int)-1; + do { + maxage = nextage; + trees[--count].maxage = maxage; + trees[--count].maxage = maxage; + nextage = 0; + for (i = 0; i <= corrections_count; i++) { + data = &corrections[i]; + if (nextage < data->correction && + data->correction < maxage) + nextage = data->correction; + } + } while (nextage); + + /* The ages assigned above are off by one. */ + for (i = 0; i != trees_count; i++) { + j = 0; + while (ages[j] < trees[i].maxage) + j++; + trees[i].maxage = ages[j-1]; + } + + /* Set up the forwarding between trees. */ + trees[trees_count-2].next = &trees[trees_count-1]; + trees[trees_count-1].leaf_mark = nfkdi_mark; + trees[trees_count-2].leaf_mark = nfkdicf_mark; + for (i = 0; i != trees_count-2; i += 2) { + trees[i].next = &trees[trees_count-2]; + trees[i].leaf_mark = correction_mark; + trees[i+1].next = &trees[trees_count-1]; + trees[i+1].leaf_mark = correction_mark; + } + + /* Assign the callouts. */ + for (i = 0; i != trees_count; i += 2) { + trees[i].type = "nfkdicf"; + trees[i].leaf_equal = nfkdicf_equal; + trees[i].leaf_print = nfkdicf_print; + trees[i].leaf_size = nfkdicf_size; + trees[i].leaf_index = nfkdicf_index; + trees[i].leaf_emit = nfkdicf_emit; + + trees[i+1].type = "nfkdi"; + trees[i+1].leaf_equal = nfkdi_equal; + trees[i+1].leaf_print = nfkdi_print; + trees[i+1].leaf_size = nfkdi_size; + trees[i+1].leaf_index = nfkdi_index; + trees[i+1].leaf_emit = nfkdi_emit; + } + + /* Finish init. */ + for (i = 0; i != trees_count; i++) + trees[i].childnode = NODE; +} + +static void +trees_populate(void) +{ + struct unicode_data *data; + unsigned int unichar; + char keyval[4]; + int keylen; + int i; + + for (i = 0; i != trees_count; i++) { + if (verbose > 0) { + printf("Populating %s_%x\n", + trees[i].type, trees[i].maxage); + } + for (unichar = 0; unichar != 0x110000; unichar++) { + if (unicode_data[unichar].gen < 0) + continue; + keylen = utf8key(unichar, keyval); + data = corrections_lookup(&unicode_data[unichar]); + if (data->correction <= trees[i].maxage) + data = &unicode_data[unichar]; + insert(&trees[i], keyval, keylen, data); + } + } +} + +static void +trees_reduce(void) +{ + int i; + int size; + int changed; + + for (i = 0; i != trees_count; i++) + prune(&trees[i]); + for (i = 0; i != trees_count; i++) + mark_nodes(&trees[i]); + do { + size = 0; + for (i = 0; i != trees_count; i++) + size = index_nodes(&trees[i], size); + changed = 0; + for (i = 0; i != trees_count; i++) + changed += size_nodes(&trees[i]); + } while (changed); + + utf8data = calloc(size, 1); + utf8data_size = size; + for (i = 0; i != trees_count; i++) + emit(&trees[i], utf8data); + + if (verbose > 0) { + for (i = 0; i != trees_count; i++) { + printf("%s_%x idx %d\n", + trees[i].type, trees[i].maxage, trees[i].index); + } + } + + nfkdi = utf8data + trees[trees_count-1].index; + nfkdicf = utf8data + trees[trees_count-2].index; + + nfkdi_tree = &trees[trees_count-1]; + nfkdicf_tree = &trees[trees_count-2]; +} + +static void +verify(struct tree *tree) +{ + struct unicode_data *data; + utf8leaf_t *leaf; + unsigned int unichar; + char key[4]; + int report; + int nocf; + + if (verbose > 0) + printf("Verifying %s_%x\n", tree->type, tree->maxage); + nocf = strcmp(tree->type, "nfkdicf"); + + for (unichar = 0; unichar != 0x110000; unichar++) { + report = 0; + data = corrections_lookup(&unicode_data[unichar]); + if (data->correction <= tree->maxage) + data = &unicode_data[unichar]; + utf8key(unichar, key); + leaf = utf8lookup(tree, key); + if (!leaf) { + if (data->gen != -1) + report++; + if (unichar < 0xd800 || unichar > 0xdfff) + report++; + } else { + if (unichar >= 0xd800 && unichar <= 0xdfff) + report++; + if (data->gen == -1) + report++; + if (data->gen != LEAF_GEN(leaf)) + report++; + if (LEAF_CCC(leaf) == DECOMPOSE) { + if (nocf) { + if (!data->utf8nfkdi) { + report++; + } else if (strcmp(data->utf8nfkdi, + LEAF_STR(leaf))) { + report++; + } + } else { + if (!data->utf8nfkdicf && + !data->utf8nfkdi) { + report++; + } else if (data->utf8nfkdicf) { + if (strcmp(data->utf8nfkdicf, + LEAF_STR(leaf))) + report++; + } else if (strcmp(data->utf8nfkdi, + LEAF_STR(leaf))) { + report++; + } + } + } else if (data->ccc != LEAF_CCC(leaf)) { + report++; + } + } + if (report) { + printf("%X code %X gen %d ccc %d" + " nfdki -> \"%s\"", + unichar, data->code, data->gen, + data->ccc, + data->utf8nfkdi); + if (leaf) { + printf(" age %d ccc %d" + " nfdki -> \"%s\"\n", + LEAF_GEN(leaf), + LEAF_CCC(leaf), + LEAF_CCC(leaf) == DECOMPOSE ? + LEAF_STR(leaf) : ""); + } + printf("\n"); + } + } +} + +static void +trees_verify(void) +{ + int i; + + for (i = 0; i != trees_count; i++) + verify(&trees[i]); +} + +/* ------------------------------------------------------------------ */ + +static void +help(void) +{ + printf("Usage: %s [options]\n", argv0); + printf("\n"); + printf("This program creates an a data trie used for parsing and\n"); + printf("normalization of UTF-8 strings. The trie is derived from\n"); + printf("a set of input files from the Unicode character database\n"); + printf("found at: http://www.unicode.org/Public/UCD/latest/ucd/\n"); + printf("\n"); + printf("The generated tree supports two normalization forms:\n"); + printf("\n"); + printf("\tnfkdi:\n"); + printf("\t- Apply unicode normalization form NFKD.\n"); + printf("\t- Remove any Default_Ignorable_Code_Point.\n"); + printf("\n"); + printf("\tnfkdicf:\n"); + printf("\t- Apply unicode normalization form NFKD.\n"); + printf("\t- Remove any Default_Ignorable_Code_Point.\n"); + printf("\t- Apply a full casefold (C + F).\n"); + printf("\n"); + printf("These forms were chosen as being most useful when dealing\n"); + printf("with file names: NFKD catches most cases where characters\n"); + printf("should be considered equivalent. The ignorables are mostly\n"); + printf("invisible, making names hard to type.\n"); + printf("\n"); + printf("The options to specify the files to be used are listed\n"); + printf("below with their default values, which are the names used\n"); + printf("by version 7.0.0 of the Unicode Character Database.\n"); + printf("\n"); + printf("The input files:\n"); + printf("\t-a %s\n", AGE_NAME); + printf("\t-c %s\n", CCC_NAME); + printf("\t-p %s\n", PROP_NAME); + printf("\t-d %s\n", DATA_NAME); + printf("\t-f %s\n", FOLD_NAME); + printf("\t-n %s\n", NORM_NAME); + printf("\n"); + printf("Additionally, the generated tables are tested using:\n"); + printf("\t-t %s\n", TEST_NAME); + printf("\n"); + printf("Finally, the output file:\n"); + printf("\t-o %s\n", UTF8_NAME); + printf("\n"); +} + +static void +usage(void) +{ + help(); + exit(1); +} + +static void +open_fail(const char *name, int error) +{ + printf("Error %d opening %s: %s\n", error, name, strerror(error)); + exit(1); +} + +static void +file_fail(const char *filename) +{ + printf("Error parsing %s\n", filename); + exit(1); +} + +static void +line_fail(const char *filename, const char *line) +{ + printf("Error parsing %s:%s\n", filename, line); + exit(1); +} + +/* ------------------------------------------------------------------ */ + +static void +print_utf32(unsigned int *utf32str) +{ + int i; + + for (i = 0; utf32str[i]; i++) + printf(" %X", utf32str[i]); +} + +static void +print_utf32nfkdi(unsigned int unichar) +{ + printf(" %X ->", unichar); + print_utf32(unicode_data[unichar].utf32nfkdi); + printf("\n"); +} + +static void +print_utf32nfkdicf(unsigned int unichar) +{ + printf(" %X ->", unichar); + print_utf32(unicode_data[unichar].utf32nfkdicf); + printf("\n"); +} + +/* ------------------------------------------------------------------ */ + +static void +age_init(void) +{ + FILE *file; + unsigned int first; + unsigned int last; + unsigned int unichar; + unsigned int major; + unsigned int minor; + unsigned int revision; + int gen; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", age_name); + + file = fopen(age_name, "r"); + if (!file) + open_fail(age_name, errno); + count = 0; + + gen = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "# Age=V%d_%d_%d", + &major, &minor, &revision); + if (ret == 3) { + ages_count++; + if (verbose > 1) + printf(" Age V%d_%d_%d\n", + major, minor, revision); + if (!age_valid(major, minor, revision)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "# Age=V%d_%d", &major, &minor); + if (ret == 2) { + ages_count++; + if (verbose > 1) + printf(" Age V%d_%d\n", major, minor); + if (!age_valid(major, minor, 0)) + line_fail(age_name, line); + continue; + } + } + + /* We must have found something above. */ + if (verbose > 1) + printf("%d age entries\n", ages_count); + if (ages_count == 0 || ages_count > MAXGEN) + file_fail(age_name); + + /* There is a 0 entry. */ + ages_count++; + ages = calloc(ages_count + 1, sizeof(*ages)); + /* And a guard entry. */ + ages[ages_count] = (unsigned int)-1; + + rewind(file); + count = 0; + gen = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "# Age=V%d_%d_%d", + &major, &minor, &revision); + if (ret == 3) { + ages[++gen] = + UNICODE_AGE(major, minor, revision); + if (verbose > 1) + printf(" Age V%d_%d_%d = gen %d\n", + major, minor, revision, gen); + if (!age_valid(major, minor, revision)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "# Age=V%d_%d", &major, &minor); + if (ret == 2) { + ages[++gen] = UNICODE_AGE(major, minor, 0); + if (verbose > 1) + printf(" Age V%d_%d = %d\n", + major, minor, gen); + if (!age_valid(major, minor, 0)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "%X..%X ; %d.%d #", + &first, &last, &major, &minor); + if (ret == 4) { + for (unichar = first; unichar <= last; unichar++) + unicode_data[unichar].gen = gen; + count += 1 + last - first; + if (verbose > 1) + printf(" %X..%X gen %d\n", first, last, gen); + if (!utf32valid(first) || !utf32valid(last)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "%X ; %d.%d #", &unichar, &major, &minor); + if (ret == 3) { + unicode_data[unichar].gen = gen; + count++; + if (verbose > 1) + printf(" %X gen %d\n", unichar, gen); + if (!utf32valid(unichar)) + line_fail(age_name, line); + continue; + } + } + unicode_maxage = ages[gen]; + fclose(file); + + /* Nix surrogate block */ + if (verbose > 1) + printf(" Removing surrogate block D800..DFFF\n"); + for (unichar = 0xd800; unichar <= 0xdfff; unichar++) + unicode_data[unichar].gen = -1; + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(age_name); +} + +static void +ccc_init(void) +{ + FILE *file; + unsigned int first; + unsigned int last; + unsigned int unichar; + unsigned int value; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", ccc_name); + + file = fopen(ccc_name, "r"); + if (!file) + open_fail(ccc_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X..%X ; %d #", &first, &last, &value); + if (ret == 3) { + for (unichar = first; unichar <= last; unichar++) { + unicode_data[unichar].ccc = value; + count++; + } + if (verbose > 1) + printf(" %X..%X ccc %d\n", first, last, value); + if (!utf32valid(first) || !utf32valid(last)) + line_fail(ccc_name, line); + continue; + } + ret = sscanf(line, "%X ; %d #", &unichar, &value); + if (ret == 2) { + unicode_data[unichar].ccc = value; + count++; + if (verbose > 1) + printf(" %X ccc %d\n", unichar, value); + if (!utf32valid(unichar)) + line_fail(ccc_name, line); + continue; + } + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(ccc_name); +} + +static void +nfkdi_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char *s; + unsigned int *um; + int count; + int i; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", data_name); + file = fopen(data_name, "r"); + if (!file) + open_fail(data_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%*[^;];%*[^;];%*[^;];%*[^;];%[^;];", + &unichar, buf0); + if (ret != 2) + continue; + if (!utf32valid(unichar)) + line_fail(data_name, line); + + s = buf0; + /* skip over */ + if (*s == '<') + while (*s++ != ' ') + ; + /* decode the decomposition into UTF-32 */ + i = 0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(data_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + + if (verbose > 1) + print_utf32nfkdi(unichar); + count++; + } + fclose(file); + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(data_name); +} + +static void +nfkdicf_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char status; + char *s; + unsigned int *um; + int i; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", fold_name); + file = fopen(fold_name, "r"); + if (!file) + open_fail(fold_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X; %c; %[^;];", &unichar, &status, buf0); + if (ret != 3) + continue; + if (!utf32valid(unichar)) + line_fail(fold_name, line); + /* Use the C+F casefold. */ + if (status != 'C' && status != 'F') + continue; + s = buf0; + if (*s == '<') + while (*s++ != ' ') + ; + i = 0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(fold_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + + if (verbose > 1) + print_utf32nfkdicf(unichar); + count++; + } + fclose(file); + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(fold_name); +} + +static void +ignore_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int first; + unsigned int last; + unsigned int *um; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", prop_name); + file = fopen(prop_name, "r"); + if (!file) + open_fail(prop_name, errno); + assert(file); + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X..%X ; %s # ", &first, &last, buf0); + if (ret == 3) { + if (strcmp(buf0, "Default_Ignorable_Code_Point")) + continue; + if (!utf32valid(first) || !utf32valid(last)) + line_fail(prop_name, line); + for (unichar = first; unichar <= last; unichar++) { + free(unicode_data[unichar].utf32nfkdi); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdi = um; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdicf = um; + count++; + } + if (verbose > 1) + printf(" %X..%X Default_Ignorable_Code_Point\n", + first, last); + continue; + } + ret = sscanf(line, "%X ; %s # ", &unichar, buf0); + if (ret == 2) { + if (strcmp(buf0, "Default_Ignorable_Code_Point")) + continue; + if (!utf32valid(unichar)) + line_fail(prop_name, line); + free(unicode_data[unichar].utf32nfkdi); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdi = um; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdicf = um; + if (verbose > 1) + printf(" %X Default_Ignorable_Code_Point\n", + unichar); + count++; + continue; + } + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(prop_name); +} + +static void +corrections_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int major; + unsigned int minor; + unsigned int revision; + unsigned int age; + unsigned int *um; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char *s; + int i; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", norm_name); + file = fopen(norm_name, "r"); + if (!file) + open_fail(norm_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%[^;];%[^;];%d.%d.%d #", + &unichar, buf0, buf1, + &major, &minor, &revision); + if (ret != 6) + continue; + if (!utf32valid(unichar) || !age_valid(major, minor, revision)) + line_fail(norm_name, line); + count++; + } + corrections = calloc(count, sizeof(struct unicode_data)); + corrections_count = count; + rewind(file); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%[^;];%[^;];%d.%d.%d #", + &unichar, buf0, buf1, + &major, &minor, &revision); + if (ret != 6) + continue; + if (!utf32valid(unichar) || !age_valid(major, minor, revision)) + line_fail(norm_name, line); + corrections[count] = unicode_data[unichar]; + assert(corrections[count].code == unichar); + age = UNICODE_AGE(major, minor, revision); + corrections[count].correction = age; + + i = 0; + s = buf0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(norm_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + corrections[count].utf32nfkdi = um; + + if (verbose > 1) + printf(" %X -> %s -> %s V%d_%d_%d\n", + unichar, buf0, buf1, major, minor, revision); + count++; + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(norm_name); +} + +/* ------------------------------------------------------------------ */ + +/* + * Hangul decomposition (algorithm from Section 3.12 of Unicode 6.3.0) + * + * AC00;;Lo;0;L;;;;;N;;;;; + * D7A3;;Lo;0;L;;;;;N;;;;; + * + * SBase = 0xAC00 + * LBase = 0x1100 + * VBase = 0x1161 + * TBase = 0x11A7 + * LCount = 19 + * VCount = 21 + * TCount = 28 + * NCount = 588 (VCount * TCount) + * SCount = 11172 (LCount * NCount) + * + * Decomposition: + * SIndex = s - SBase + * + * LV (Canonical/Full) + * LIndex = SIndex / NCount + * VIndex = (Sindex % NCount) / TCount + * LPart = LBase + LIndex + * VPart = VBase + VIndex + * + * LVT (Canonical) + * LVIndex = (SIndex / TCount) * TCount + * TIndex = (Sindex % TCount + * LVPart = LBase + LVIndex + * TPart = TBase + TIndex + * + * LVT (Full) + * LIndex = SIndex / NCount + * VIndex = (Sindex % NCount) / TCount + * TIndex = (Sindex % TCount + * LPart = LBase + LIndex + * VPart = VBase + VIndex + * if (TIndex == 0) { + * d = + * } else { + * TPart = TBase + TIndex + * d = + * } + * + */ + +static void +hangul_decompose(void) +{ + unsigned int sb = 0xAC00; + unsigned int lb = 0x1100; + unsigned int vb = 0x1161; + unsigned int tb = 0x11a7; + /* unsigned int lc = 19; */ + unsigned int vc = 21; + unsigned int tc = 28; + unsigned int nc = (vc * tc); + /* unsigned int sc = (lc * nc); */ + unsigned int unichar; + unsigned int mapping[4]; + unsigned int *um; + int count; + int i; + + if (verbose > 0) + printf("Decomposing hangul\n"); + /* Hangul */ + count = 0; + for (unichar = 0xAC00; unichar <= 0xD7A3; unichar++) { + unsigned int si = unichar - sb; + unsigned int li = si / nc; + unsigned int vi = (si % nc) / tc; + unsigned int ti = si % tc; + + i = 0; + mapping[i++] = lb + li; + mapping[i++] = vb + vi; + if (ti) + mapping[i++] = tb + ti; + mapping[i++] = 0; + + assert(!unicode_data[unichar].utf32nfkdi); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + + assert(!unicode_data[unichar].utf32nfkdicf); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + + if (verbose > 1) + print_utf32nfkdi(unichar); + + count++; + } + if (verbose > 0) + printf("Created %d entries\n", count); +} + +static void +nfkdi_decompose(void) +{ + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + unsigned int *um; + unsigned int *dc; + int count; + int i; + int j; + int ret; + + if (verbose > 0) + printf("Decomposing nfkdi\n"); + + count = 0; + for (unichar = 0; unichar != 0x110000; unichar++) { + if (!unicode_data[unichar].utf32nfkdi) + continue; + for (;;) { + ret = 1; + i = 0; + um = unicode_data[unichar].utf32nfkdi; + while (*um) { + dc = unicode_data[*um].utf32nfkdi; + if (dc) { + for (j = 0; dc[j]; j++) + mapping[i++] = dc[j]; + ret = 0; + } else { + mapping[i++] = *um; + } + um++; + } + mapping[i++] = 0; + if (ret) + break; + free(unicode_data[unichar].utf32nfkdi); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + } + /* Add this decomposition to nfkdicf if there is no entry. */ + if (!unicode_data[unichar].utf32nfkdicf) { + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + } + if (verbose > 1) + print_utf32nfkdi(unichar); + count++; + } + if (verbose > 0) + printf("Processed %d entries\n", count); +} + +static void +nfkdicf_decompose(void) +{ + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + unsigned int *um; + unsigned int *dc; + int count; + int i; + int j; + int ret; + + if (verbose > 0) + printf("Decomposing nfkdicf\n"); + count = 0; + for (unichar = 0; unichar != 0x110000; unichar++) { + if (!unicode_data[unichar].utf32nfkdicf) + continue; + for (;;) { + ret = 1; + i = 0; + um = unicode_data[unichar].utf32nfkdicf; + while (*um) { + dc = unicode_data[*um].utf32nfkdicf; + if (dc) { + for (j = 0; dc[j]; j++) + mapping[i++] = dc[j]; + ret = 0; + } else { + mapping[i++] = *um; + } + um++; + } + mapping[i++] = 0; + if (ret) + break; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + } + if (verbose > 1) + print_utf32nfkdicf(unichar); + count++; + } + if (verbose > 0) + printf("Processed %d entries\n", count); +} + +/* ------------------------------------------------------------------ */ + +int utf8agemax(struct tree *, const char *); +int utf8nagemax(struct tree *, const char *, size_t); +int utf8agemin(struct tree *, const char *); +int utf8nagemin(struct tree *, const char *, size_t); +ssize_t utf8len(struct tree *, const char *); +ssize_t utf8nlen(struct tree *, const char *, size_t); +struct utf8cursor; +int utf8cursor(struct utf8cursor *, struct tree *, const char *); +int utf8ncursor(struct utf8cursor *, struct tree *, const char *, size_t); +int utf8byte(struct utf8cursor *); + +/* + * Use trie to scan s, touching at most len bytes. + * Returns the leaf if one exists, NULL otherwise. + * + * A non-NULL return guarantees that the UTF-8 sequence starting at s + * is well-formed and corresponds to a known unicode code point. The + * shorthand for this will be "is valid UTF-8 unicode". + */ +static utf8leaf_t * +utf8nlookup(struct tree *tree, const char *s, size_t len) +{ + utf8trie_t *trie = utf8data + tree->index; + int offlen; + int offset; + int mask; + int node; + + if (!tree) + return NULL; + if (len == 0) + return NULL; + node = 1; + while (node) { + offlen = (*trie & OFFLEN) >> OFFLEN_SHIFT; + if (*trie & NEXTBYTE) { + if (--len == 0) + return NULL; + s++; + } + mask = 1 << (*trie & BITNUM); + if (*s & mask) { + /* Right leg */ + if (offlen) { + /* Right node at offset of trie */ + node = (*trie & RIGHTNODE); + offset = trie[offlen]; + while (--offlen) { + offset <<= 8; + offset |= trie[offlen]; + } + trie += offset; + } else if (*trie & RIGHTPATH) { + /* Right node after this node */ + node = (*trie & TRIENODE); + trie++; + } else { + /* No right node. */ + node = 0; + trie = NULL; + } + } else { + /* Left leg */ + if (offlen) { + /* Left node after this node. */ + node = (*trie & LEFTNODE); + trie += offlen + 1; + } else if (*trie & RIGHTPATH) { + /* No left node. */ + node = 0; + trie = NULL; + } else { + /* Left node after this node */ + node = (*trie & TRIENODE); + trie++; + } + } + } + return trie; +} + +/* + * Use trie to scan s. + * Returns the leaf if one exists, NULL otherwise. + * + * Forwards to trie_nlookup(). + */ +static utf8leaf_t * +utf8lookup(struct tree *tree, const char *s) +{ + return utf8nlookup(tree, s, (size_t)-1); +} + +/* + * Return the number of bytes used by the current UTF-8 sequence. + * Assumes the input points to the first byte of a valid UTF-8 + * sequence. + */ +static inline int +utf8clen(const char *s) +{ + unsigned char c = *s; + return 1 + (c >= 0xC0) + (c >= 0xE0) + (c >= 0xF0); +} + +/* + * Maximum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if only non-assigned code points are used. + */ +int +utf8agemax(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age > age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Minimum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if non-assigned code points are used. + */ +int +utf8agemin(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + int age = tree->maxage; + int leaf_age; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age < age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemax(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age > age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemin(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int leaf_age; + int age = tree->maxage; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age < age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Length of the normalization of s. + * Return -1 if s is not valid UTF-8 unicode. + * + * A string of Default_Ignorable_Code_Point has length 0. + */ +ssize_t +utf8len(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + if (ages[LEAF_GEN(leaf)] > tree->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Length of the normalization of s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +ssize_t +utf8nlen(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + if (ages[LEAF_GEN(leaf)] > tree->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + len -= utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Cursor structure used by the normalizer. + */ +struct utf8cursor { + struct tree *tree; + const char *s; + const char *p; + const char *ss; + const char *sp; + unsigned int len; + unsigned int slen; + short int ccc; + short int nccc; + unsigned int unichar; +}; + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * s : string. + * len : length of s. + * u8c : pointer to cursor. + * trie : utf8trie_t to use for normalization. + * + * Returns -1 on error, 0 on success. + */ +int +utf8ncursor( + struct utf8cursor *u8c, + struct tree *tree, + const char *s, + size_t len) +{ + if (!tree) + return -1; + if (!s) + return -1; + u8c->tree = tree; + u8c->s = s; + u8c->p = NULL; + u8c->ss = NULL; + u8c->sp = NULL; + u8c->len = len; + u8c->slen = 0; + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->unichar = 0; + /* Check we didn't clobber the maximum length. */ + if (u8c->len != len) + return -1; + /* The first byte of s may not be an utf8 continuation. */ + if (len > 0 && (*s & 0xC0) == 0x80) + return -1; + return 0; +} + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * s : NUL-terminated string. + * u8c : pointer to cursor. + * trie : utf8trie_t to use for normalization. + * + * Returns -1 on error, 0 on success. + */ +int +utf8cursor( + struct utf8cursor *u8c, + struct tree *tree, + const char *s) +{ + return utf8ncursor(u8c, tree, s, (unsigned int)-1); +} + +/* + * Get one byte from the normalized form of the string described by u8c. + * + * Returns the byte cast to an unsigned char on succes, and -1 on failure. + * + * The cursor keeps track of the location in the string in u8c->s. + * When a character is decomposed, the current location is stored in + * u8c->p, and u8c->s is set to the start of the decomposition. Note + * that bytes from a decomposition do not count against u8c->len. + * + * Characters are emitted if they match the current CCC in u8c->ccc. + * Hitting end-of-string while u8c->ccc == STOPPER means we're done, + * and the function returns 0 in that case. + * + * Sorting by CCC is done by repeatedly scanning the string. The + * values of u8c->s and u8c->p are stored in u8c->ss and u8c->sp at + * the start of the scan. The first pass finds the lowest CCC to be + * emitted and stores it in u8c->nccc, the second pass emits the + * characters with this CCC and finds the next lowest CCC. This limits + * the number of passes to 1 + the number of different CCCs in the + * sequence being scanned. + * + * Therefore: + * u8c->p != NULL -> a decomposition is being scanned. + * u8c->ss != NULL -> this is a repeating scan. + * u8c->ccc == -1 -> this is the first scan of a repeating scan. + */ +int +utf8byte(struct utf8cursor *u8c) +{ + utf8leaf_t *leaf; + int ccc; + + for (;;) { + /* Check for the end of a decomposed character. */ + if (u8c->p && *u8c->s == '\0') { + u8c->s = u8c->p; + u8c->p = NULL; + } + + /* Check for end-of-string. */ + if (!u8c->p && (u8c->len == 0 || *u8c->s == '\0')) { + /* There is no next byte. */ + if (u8c->ccc == STOPPER) + return 0; + /* End-of-string during a scan counts as a stopper. */ + ccc = STOPPER; + goto ccc_mismatch; + } else if ((*u8c->s & 0xC0) == 0x80) { + /* This is a continuation of the current character. */ + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Look up the data for the current character. */ + if (u8c->p) + leaf = utf8lookup(u8c->tree, u8c->s); + else + leaf = utf8nlookup(u8c->tree, u8c->s, u8c->len); + + /* No leaf found implies that the input is a binary blob. */ + if (!leaf) + return -1; + + /* Characters that are too new have CCC 0. */ + if (ages[LEAF_GEN(leaf)] > u8c->tree->maxage) { + ccc = STOPPER; + } else if ((ccc = LEAF_CCC(leaf)) == DECOMPOSE) { + u8c->len -= utf8clen(u8c->s); + u8c->p = u8c->s + utf8clen(u8c->s); + u8c->s = LEAF_STR(leaf); + /* Empty decomposition implies CCC 0. */ + if (*u8c->s == '\0') { + if (u8c->ccc == STOPPER) + continue; + ccc = STOPPER; + goto ccc_mismatch; + } + leaf = utf8lookup(u8c->tree, u8c->s); + ccc = LEAF_CCC(leaf); + } + u8c->unichar = utf8code(u8c->s); + + /* + * If this is not a stopper, then see if it updates + * the next canonical class to be emitted. + */ + if (ccc != STOPPER && u8c->ccc < ccc && ccc < u8c->nccc) + u8c->nccc = ccc; + + /* + * Return the current byte if this is the current + * combining class. + */ + if (ccc == u8c->ccc) { + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Current combining class mismatch. */ + ccc_mismatch: + if (u8c->nccc == STOPPER) { + /* + * Scan forward for the first canonical class + * to be emitted. Save the position from + * which to restart. + */ + assert(u8c->ccc == STOPPER); + u8c->ccc = MINCCC - 1; + u8c->nccc = ccc; + u8c->sp = u8c->p; + u8c->ss = u8c->s; + u8c->slen = u8c->len; + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (ccc != STOPPER) { + /* Not a stopper, and not the ccc we're emitting. */ + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (u8c->nccc != MAXCCC + 1) { + /* At a stopper, restart for next ccc. */ + u8c->ccc = u8c->nccc; + u8c->nccc = MAXCCC + 1; + u8c->s = u8c->ss; + u8c->p = u8c->sp; + u8c->len = u8c->slen; + } else { + /* All done, proceed from here. */ + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->sp = NULL; + u8c->ss = NULL; + u8c->slen = 0; + } + } +} + +/* ------------------------------------------------------------------ */ + +static int +normalize_line(struct tree *tree) +{ + char *s; + char *t; + int c; + struct utf8cursor u8c; + + /* First test: null-terminated string. */ + s = buf2; + t = buf3; + if (utf8cursor(&u8c, tree, s)) + return -1; + while ((c = utf8byte(&u8c)) > 0) + if (c != (unsigned char)*t++) + return -1; + if (c < 0) + return -1; + if (*t != 0) + return -1; + + /* Second test: length-limited string. */ + s = buf2; + /* Replace NUL with a value that will cause an error if seen. */ + s[strlen(s) + 1] = -1; + t = buf3; + if (utf8cursor(&u8c, tree, s)) + return -1; + while ((c = utf8byte(&u8c)) > 0) + if (c != (unsigned char)*t++) + return -1; + if (c < 0) + return -1; + if (*t != 0) + return -1; + + return 0; +} + +static void +normalization_test(void) +{ + FILE *file; + unsigned int unichar; + struct unicode_data *data; + char *s; + char *t; + int ret; + int ignorables; + int tests = 0; + int failures = 0; + + if (verbose > 0) + printf("Parsing %s\n", test_name); + /* Step one, read data from file. */ + file = fopen(test_name, "r"); + if (!file) + open_fail(test_name, errno); + + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%[^;];%*[^;];%*[^;];%*[^;];%[^;];", + buf0, buf1); + if (ret != 2 || *line == '#') + continue; + s = buf0; + t = buf2; + while (*s) { + unichar = strtoul(s, &s, 16); + t += utf8key(unichar, t); + } + *t = '\0'; + + ignorables = 0; + s = buf1; + t = buf3; + while (*s) { + unichar = strtoul(s, &s, 16); + data = &unicode_data[unichar]; + if (data->utf8nfkdi && !*data->utf8nfkdi) + ignorables = 1; + else + t += utf8key(unichar, t); + } + *t = '\0'; + + tests++; + if (normalize_line(nfkdi_tree) < 0) { + printf("\nline %s -> %s", buf0, buf1); + if (ignorables) + printf(" (ignorables removed)"); + printf(" failure\n"); + failures++; + } + } + fclose(file); + if (verbose > 0) + printf("Ran %d tests with %d failures\n", tests, failures); + if (failures) + file_fail(test_name); +} + +/* ------------------------------------------------------------------ */ + +static void +write_file(void) +{ + FILE *file; + int i; + int j; + int t; + int gen; + + if (verbose > 0) + printf("Writing %s\n", utf8_name); + file = fopen(utf8_name, "w"); + if (!file) + open_fail(utf8_name, errno); + + fprintf(file, "/* This file is generated code, do not edit. */\n"); + fprintf(file, "#ifndef __INCLUDED_FROM_UTF8NORM_C__\n"); + fprintf(file, "#error Only xfs_utf8.c may include this file.\n"); + fprintf(file, "#endif\n"); + fprintf(file, "\n"); + fprintf(file, "const unsigned int utf8version = %#x;\n", + unicode_maxage); + fprintf(file, "\n"); + fprintf(file, "static const unsigned int utf8agetab[] = {\n"); + for (i = 0; i != ages_count; i++) + fprintf(file, "\t%#x%s\n", ages[i], + ages[i] == unicode_maxage ? "" : ","); + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const struct utf8data utf8nfkdicfdata[] = {\n"); + t = 0; + for (gen = 0; gen < ages_count; gen++) { + fprintf(file, "\t{ %#x, %d }%s\n", + ages[gen], trees[t].index, + ages[gen] == unicode_maxage ? "" : ","); + if (trees[t].maxage == ages[gen]) + t += 2; + } + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const struct utf8data utf8nfkdidata[] = {\n"); + t = 1; + for (gen = 0; gen < ages_count; gen++) { + fprintf(file, "\t{ %#x, %d }%s\n", + ages[gen], trees[t].index, + ages[gen] == unicode_maxage ? "" : ","); + if (trees[t].maxage == ages[gen]) + t += 2; + } + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const unsigned char utf8data[%zd] = {\n", + utf8data_size); + t = 0; + for (i = 0; i != utf8data_size; i += 16) { + if (i == trees[t].index) { + fprintf(file, "\t/* %s_%x */\n", + trees[t].type, trees[t].maxage); + if (t < trees_count-1) + t++; + } + fprintf(file, "\t"); + for (j = i; j != i + 16; j++) + fprintf(file, "0x%.2x%s", utf8data[j], + (j < utf8data_size -1 ? "," : "")); + fprintf(file, "\n"); + } + fprintf(file, "};\n"); + fclose(file); +} + +/* ------------------------------------------------------------------ */ + +int +main(int argc, char *argv[]) +{ + unsigned int unichar; + int opt; + + argv0 = argv[0]; + + while ((opt = getopt(argc, argv, "a:c:d:f:hn:o:p:t:v")) != -1) { + switch (opt) { + case 'a': + age_name = optarg; + break; + case 'c': + ccc_name = optarg; + break; + case 'd': + data_name = optarg; + break; + case 'f': + fold_name = optarg; + break; + case 'n': + norm_name = optarg; + break; + case 'o': + utf8_name = optarg; + break; + case 'p': + prop_name = optarg; + break; + case 't': + test_name = optarg; + break; + case 'v': + verbose++; + break; + case 'h': + help(); + exit(0); + default: + usage(); + } + } + + if (verbose > 1) + help(); + for (unichar = 0; unichar != 0x110000; unichar++) + unicode_data[unichar].code = unichar; + age_init(); + ccc_init(); + nfkdi_init(); + nfkdicf_init(); + ignore_init(); + corrections_init(); + hangul_decompose(); + nfkdi_decompose(); + nfkdicf_decompose(); + utf8_init(); + trees_init(); + trees_populate(); + trees_reduce(); + trees_verify(); + /* Prevent "unused function" warning. */ + (void)lookup(nfkdi_tree, " "); + if (verbose > 2) + tree_walk(nfkdi_tree); + if (verbose > 2) + tree_walk(nfkdicf_tree); + normalization_test(); + write_file(); + + return 0; +} diff --git a/fs/xfs/support/utf8norm.c b/fs/xfs/support/utf8norm.c new file mode 100644 index 0000000..3a8b3ab --- /dev/null +++ b/fs/xfs/support/utf8norm.c @@ -0,0 +1,641 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "xfs.h" +#include "xfs_types.h" +#include "utf8norm.h" + +struct utf8data { + unsigned int maxage; + unsigned int offset; +}; + +#define __INCLUDED_FROM_UTF8NORM_C__ +#include "utf8data.h" +#undef __INCLUDED_FROM_UTF8NORM_C__ + +/* + * UTF-8 valid ranges. + * + * The UTF-8 encoding spreads the bits of a 32bit word over several + * bytes. This table gives the ranges that can be held and how they'd + * be represented. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000000 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000000 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * There is an additional requirement on UTF-8, in that only the + * shortest representation of a 32bit value is to be used. A decoder + * must not decode sequences that do not satisfy this requirement. + * Thus the allowed ranges have a lower bound. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000080 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000800 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00010000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00200000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x04000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Actual unicode characters are limited to the range 0x0 - 0x10FFFF, + * 17 planes of 65536 values. This limits the sequences actually seen + * even more, to just the following. + * + * 0 - 0x7F: 0 - 0x7F + * 0x80 - 0x7FF: 0xC2 0x80 - 0xDF 0xBF + * 0x800 - 0xFFFF: 0xE0 0xA0 0x80 - 0xEF 0xBF 0xBF + * 0x10000 - 0x10FFFF: 0xF0 0x90 0x80 0x80 - 0xF4 0x8F 0xBF 0xBF + * + * Within those ranges the surrogates 0xD800 - 0xDFFF are not allowed. + * + * Note that the longest sequence seen with valid usage is 4 bytes, + * the same a single UTF-32 character. This makes the UTF-8 + * representation of Unicode strictly smaller than UTF-32. + * + * The shortest sequence requirement was introduced by: + * Corrigendum #1: UTF-8 Shortest Form + * It can be found here: + * http://www.unicode.org/versions/corrigendum1.html + * + */ + +/* + * Return the number of bytes used by the current UTF-8 sequence. + * Assumes the input points to the first byte of a valid UTF-8 + * sequence. + */ +static inline int +utf8clen(const char *s) +{ + unsigned char c = *s; + return 1 + (c >= 0xC0) + (c >= 0xE0) + (c >= 0xF0); +} + +/* + * utf8trie_t + * + * A compact binary tree, used to decode UTF-8 characters. + * + * Internal nodes are one byte for the node itself, and up to three + * bytes for an offset into the tree. The first byte contains the + * following information: + * NEXTBYTE - flag - advance to next byte if set + * BITNUM - 3 bit field - the bit number to tested + * OFFLEN - 2 bit field - number of bytes in the offset + * if offlen == 0 (non-branching node) + * RIGHTPATH - 1 bit field - set if the following node is for the + * right-hand path (tested bit is set) + * TRIENODE - 1 bit field - set if the following node is an internal + * node, otherwise it is a leaf node + * if offlen != 0 (branching node) + * LEFTNODE - 1 bit field - set if the left-hand node is internal + * RIGHTNODE - 1 bit field - set if the right-hand node is internal + * + * Due to the way utf8 works, there cannot be branching nodes with + * NEXTBYTE set, and moreover those nodes always have a righthand + * descendant. + */ +typedef const unsigned char utf8trie_t; +#define BITNUM 0x07 +#define NEXTBYTE 0x08 +#define OFFLEN 0x30 +#define OFFLEN_SHIFT 4 +#define RIGHTPATH 0x40 +#define TRIENODE 0x80 +#define RIGHTNODE 0x40 +#define LEFTNODE 0x80 + +/* + * utf8leaf_t + * + * The leaves of the trie are embedded in the trie, and so the same + * underlying datatype: unsigned char. + * + * leaf[0]: The unicode version, stored as a generation number that is + * an index into utf8agetab[]. With this we can filter code + * points based on the unicode version in which they were + * defined. The CCC of a non-defined code point is 0. + * leaf[1]: Canonical Combining Class. During normalization, we need + * to do a stable sort into ascending order of all characters + * with a non-zero CCC that occur between two characters with + * a CCC of 0, or at the begin or end of a string. + * The unicode standard guarantees that all CCC values are + * between 0 and 254 inclusive, which leaves 255 available as + * a special value. + * Code points with CCC 0 are known as stoppers. + * leaf[2]: Decomposition. If leaf[1] == 255, then leaf[2] is the + * start of a NUL-terminated string that is the decomposition + * of the character. + * The CCC of a decomposable character is the same as the CCC + * of the first character of its decomposition. + * Some characters decompose as the empty string: these are + * characters with the Default_Ignorable_Code_Point property. + * These do affect normalization, as they all have CCC 0. + * + * The decompositions in the trie have been fully expanded. + * + * Casefolding, if applicable, is also done using decompositions. + * + * The trie is constructed in such a way that leaves exist for all + * UTF-8 sequences that match the criteria from the "UTF-8 valid + * ranges" comment above, and only for those sequences. Therefore a + * lookup in the trie can be used to validate the UTF-8 input. + */ +typedef const unsigned char utf8leaf_t; + +#define LEAF_GEN(LEAF) ((LEAF)[0]) +#define LEAF_CCC(LEAF) ((LEAF)[1]) +#define LEAF_STR(LEAF) ((const char*)((LEAF) + 2)) + +#define MINCCC (0) +#define MAXCCC (254) +#define STOPPER (0) +#define DECOMPOSE (255) + +/* + * Use trie to scan s, touching at most len bytes. + * Returns the leaf if one exists, NULL otherwise. + * + * A non-NULL return guarantees that the UTF-8 sequence starting at s + * is well-formed and corresponds to a known unicode code point. The + * shorthand for this will be "is valid UTF-8 unicode". + */ +static utf8leaf_t * +utf8nlookup(utf8data_t data, const char *s, size_t len) +{ + utf8trie_t *trie = utf8data + data->offset; + int offlen; + int offset; + int mask; + int node; + + if (!data) + return NULL; + if (len == 0) + return NULL; + node = 1; + while (node) { + offlen = (*trie & OFFLEN) >> OFFLEN_SHIFT; + if (*trie & NEXTBYTE) { + if (--len == 0) + return NULL; + s++; + } + mask = 1 << (*trie & BITNUM); + if (*s & mask) { + /* Right leg */ + if (offlen) { + /* Right node at offset of trie */ + node = (*trie & RIGHTNODE); + offset = trie[offlen]; + while (--offlen) { + offset <<= 8; + offset |= trie[offlen]; + } + trie += offset; + } else if (*trie & RIGHTPATH) { + /* Right node after this node */ + node = (*trie & TRIENODE); + trie++; + } else { + /* No right node. */ + node = 0; + trie = NULL; + } + } else { + /* Left leg */ + if (offlen) { + /* Left node after this node. */ + node = (*trie & LEFTNODE); + trie += offlen + 1; + } else if (*trie & RIGHTPATH) { + /* No left node. */ + node = 0; + trie = NULL; + } else { + /* Left node after this node */ + node = (*trie & TRIENODE); + trie++; + } + } + } + return trie; +} + +/* + * Use trie to scan s. + * Returns the leaf if one exists, NULL otherwise. + * + * Forwards to utf8nlookup(). + */ +static utf8leaf_t * +utf8lookup(utf8data_t data, const char *s) +{ + return utf8nlookup(data, s, (size_t)-1); +} + +/* + * Maximum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if only non-assigned code points are used. + */ +int +utf8agemax(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!data) + return -1; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age > age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} +EXPORT_SYMBOL(utf8agemax); + +/* + * Minimum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if non-assigned code points are used. + */ +int +utf8agemin(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + int age; + int leaf_age; + + if (!data) + return -1; + age = data->maxage; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age < age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} +EXPORT_SYMBOL(utf8agemin); + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemax(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!data) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age > age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} +EXPORT_SYMBOL(utf8nagemax); + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemin(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int leaf_age; + int age; + + if (!data) + return -1; + age = data->maxage; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age < age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} +EXPORT_SYMBOL(utf8nagemin); + +/* + * Length of the normalization of s. + * Return -1 if s is not valid UTF-8 unicode. + * + * A string of Default_Ignorable_Code_Point has length 0. + */ +ssize_t +utf8len(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!data) + return -1; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + if (utf8agetab[LEAF_GEN(leaf)] > data->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + s += utf8clen(s); + } + return ret; +} +EXPORT_SYMBOL(utf8len); + +/* + * Length of the normalization of s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +ssize_t +utf8nlen(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!data) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + if (utf8agetab[LEAF_GEN(leaf)] > data->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + len -= utf8clen(s); + s += utf8clen(s); + } + return ret; +} +EXPORT_SYMBOL(utf8nlen); + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * u8c : pointer to cursor. + * data : utf8data_t to use for normalization. + * s : string. + * len : length of s. + * + * Returns -1 on error, 0 on success. + */ +int +utf8ncursor( + struct utf8cursor *u8c, + utf8data_t data, + const char *s, + size_t len) +{ + if (!data) + return -1; + if (!s) + return -1; + u8c->data = data; + u8c->s = s; + u8c->p = NULL; + u8c->ss = NULL; + u8c->sp = NULL; + u8c->len = len; + u8c->slen = 0; + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + /* Check we didn't clobber the maximum length. */ + if (u8c->len != len) + return -1; + /* The first byte of s may not be an utf8 continuation. */ + if (len > 0 && (*s & 0xC0) == 0x80) + return -1; + return 0; +} +EXPORT_SYMBOL(utf8ncursor); + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * u8c : pointer to cursor. + * data : utf8data_t to use for normalization. + * s : NUL-terminated string. + * + * Returns -1 on error, 0 on success. + */ +int +utf8cursor( + struct utf8cursor *u8c, + utf8data_t data, + const char *s) +{ + return utf8ncursor(u8c, data, s, (unsigned int)-1); +} +EXPORT_SYMBOL(utf8cursor); + +/* + * Get one byte from the normalized form of the string described by u8c. + * + * Returns the byte cast to an unsigned char on succes, and -1 on failure. + * + * The cursor keeps track of the location in the string in u8c->s. + * When a character is decomposed, the current location is stored in + * u8c->p, and u8c->s is set to the start of the decomposition. Note + * that bytes from a decomposition do not count against u8c->len. + * + * Characters are emitted if they match the current CCC in u8c->ccc. + * Hitting end-of-string while u8c->ccc == STOPPER means we're done, + * and the function returns 0 in that case. + * + * Sorting by CCC is done by repeatedly scanning the string. The + * values of u8c->s and u8c->p are stored in u8c->ss and u8c->sp at + * the start of the scan. The first pass finds the lowest CCC to be + * emitted and stores it in u8c->nccc, the second pass emits the + * characters with this CCC and finds the next lowest CCC. This limits + * the number of passes to 1 + the number of different CCCs in the + * sequence being scanned. + * + * Therefore: + * u8c->p != NULL -> a decomposition is being scanned. + * u8c->ss != NULL -> this is a repeating scan. + * u8c->ccc == -1 -> this is the first scan of a repeating scan. + */ +int +utf8byte(struct utf8cursor *u8c) +{ + utf8leaf_t *leaf; + int ccc; + + for (;;) { + /* Check for the end of a decomposed character. */ + if (u8c->p && *u8c->s == '\0') { + u8c->s = u8c->p; + u8c->p = NULL; + } + + /* Check for end-of-string. */ + if (!u8c->p && (u8c->len == 0 || *u8c->s == '\0')) { + /* There is no next byte. */ + if (u8c->ccc == STOPPER) + return 0; + /* End-of-string during a scan counts as a stopper. */ + ccc = STOPPER; + goto ccc_mismatch; + } else if ((*u8c->s & 0xC0) == 0x80) { + /* This is a continuation of the current character. */ + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Look up the data for the current character. */ + if (u8c->p) + leaf = utf8lookup(u8c->data, u8c->s); + else + leaf = utf8nlookup(u8c->data, u8c->s, u8c->len); + + /* No leaf found implies that the input is a binary blob. */ + if (!leaf) + return -1; + + /* Characters that are too new have CCC 0. */ + if (utf8agetab[LEAF_GEN(leaf)] > u8c->data->maxage) { + ccc = STOPPER; + } else if ((ccc = LEAF_CCC(leaf)) == DECOMPOSE) { + u8c->len -= utf8clen(u8c->s); + u8c->p = u8c->s + utf8clen(u8c->s); + u8c->s = LEAF_STR(leaf); + /* Empty decomposition implies CCC 0. */ + if (*u8c->s == '\0') { + if (u8c->ccc == STOPPER) + continue; + ccc = STOPPER; + goto ccc_mismatch; + } + leaf = utf8lookup(u8c->data, u8c->s); + ccc = LEAF_CCC(leaf); + } + + /* + * If this is not a stopper, then see if it updates + * the next canonical class to be emitted. + */ + if (ccc != STOPPER && u8c->ccc < ccc && ccc < u8c->nccc) + u8c->nccc = ccc; + + /* + * Return the current byte if this is the current + * combining class. + */ + if (ccc == u8c->ccc) { + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Current combining class mismatch. */ + ccc_mismatch: + if (u8c->nccc == STOPPER) { + /* + * Scan forward for the first canonical class + * to be emitted. Save the position from + * which to restart. + */ + u8c->ccc = MINCCC - 1; + u8c->nccc = ccc; + u8c->sp = u8c->p; + u8c->ss = u8c->s; + u8c->slen = u8c->len; + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (ccc != STOPPER) { + /* Not a stopper, and not the ccc we're emitting. */ + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (u8c->nccc != MAXCCC + 1) { + /* At a stopper, restart for next ccc. */ + u8c->ccc = u8c->nccc; + u8c->nccc = MAXCCC + 1; + u8c->s = u8c->ss; + u8c->p = u8c->sp; + u8c->len = u8c->slen; + } else { + /* All done, proceed from here. */ + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->sp = NULL; + u8c->ss = NULL; + u8c->slen = 0; + } + } +} +EXPORT_SYMBOL(utf8byte); + +const struct utf8data * +utf8nfkdi(unsigned int maxage) +{ + int i = sizeof(utf8nfkdidata)/sizeof(utf8nfkdidata[0]) - 1; + + while (maxage < utf8nfkdidata[i].maxage) + i--; + if (maxage > utf8nfkdidata[i].maxage) + return NULL; + return &utf8nfkdidata[i]; +} +EXPORT_SYMBOL(utf8nfkdi); + +const struct utf8data * +utf8nfkdicf(unsigned int maxage) +{ + int i = sizeof(utf8nfkdicfdata)/sizeof(utf8nfkdicfdata[0]) - 1; + + while (maxage < utf8nfkdicfdata[i].maxage) + i--; + if (maxage > utf8nfkdicfdata[i].maxage) + return NULL; + return &utf8nfkdicfdata[i]; +} +EXPORT_SYMBOL(utf8nfkdicf); diff --git a/fs/xfs/support/utf8norm.h b/fs/xfs/support/utf8norm.h new file mode 100644 index 0000000..6aa3391 --- /dev/null +++ b/fs/xfs/support/utf8norm.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef UTF8NORM_H +#define UTF8NORM_H + +/* An opaque type used to determine the normalization in use. */ +typedef const struct utf8data *utf8data_t; + +/* Encoding a unicode version number as a single unsigned int. */ +#define UNICODE_MAJ_SHIFT (16) +#define UNICODE_MIN_SHIFT (8) + +#define UNICODE_AGE(MAJ,MIN,REV) \ + (((unsigned int)(MAJ) << UNICODE_MAJ_SHIFT) | \ + ((unsigned int)(MIN) << UNICODE_MIN_SHIFT) | \ + ((unsigned int)(REV))) + +/* Highest unicode version supported by the data tables. */ +extern const unsigned int utf8version; + +/* + * Look for the correct utf8data_t for a unicode version. + * Returns NULL if the version requested is too new. + * + * Two normalization forms are supported: nfkdi and nfkdicf. + * + * nfkdi: + * - Apply unicode normalization form NFKD. + * - Remove any Default_Ignorable_Code_Point. + * + * nfkdicf: + * - Apply unicode normalization form NFKD. + * - Remove any Default_Ignorable_Code_Point. + * - Apply a full casefold (C + F). + */ +extern utf8data_t utf8nfkdi(unsigned int); +extern utf8data_t utf8nfkdicf(unsigned int); + +/* + * Determine the maximum age of any unicode character in the string. + * Returns 0 if only unassigned code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern int utf8agemax(utf8data_t, const char *); +extern int utf8nagemax(utf8data_t, const char *, size_t); + +/* + * Determine the minimum age of any unicode character in the string. + * Returns 0 if any unassigned code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern int utf8agemin(utf8data_t, const char *); +extern int utf8nagemin(utf8data_t, const char *, size_t); + +/* + * Determine the length of the normalized from of the string, + * excluding any terminating NULL byte. + * Returns 0 if only ignorable code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern ssize_t utf8len(utf8data_t, const char *); +extern ssize_t utf8nlen(utf8data_t, const char *, size_t); + +/* + * Cursor structure used by the normalizer. + */ +struct utf8cursor { + utf8data_t data; + const char *s; + const char *p; + const char *ss; + const char *sp; + unsigned int len; + unsigned int slen; + short int ccc; + short int nccc; +}; + +/* + * Initialize a utf8cursor to normalize a string. + * Returns 0 on success. + * Returns -1 on failure. + */ +extern int utf8cursor(struct utf8cursor *, utf8data_t, const char *); +extern int utf8ncursor(struct utf8cursor *, utf8data_t, const char *, size_t); + +/* + * Get the next byte in the normalization. + * Returns a value > 0 && < 256 on success. + * Returns 0 when the end of the normalization is reached. + * Returns -1 if the string being normalized is not valid UTF-8. + */ +extern int utf8byte(struct utf8cursor *); + +#endif /* UTF8NORM_H */ -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 15:49:27 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B2C197F85 for ; Thu, 11 Sep 2014 15:49:27 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2DE8FAC00D; Thu, 11 Sep 2014 13:49:27 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id CA6CC4266DC; Thu, 11 Sep 2014 15:49:26 -0500 (CDT) Date: Thu, 11 Sep 2014 15:49:26 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 8/9] xfs: add xfs_nameops for utf8 and utf8+casefold. Message-ID: <20140911204926.GH13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber The xfs_utf8_nameops use the nfkdi normalization when comparing filenames, and are installed if the utf8bit is set in the super block. The xfs_utf8_ci_nameops use the nfkdicf normalization when comparing filenames, and are installed if both the utf8bit and the borgbit are set in the superblock. Normalized filenames are not stored on disk. Normalization will fail if a filename is not valid UTF-8, in which case the filename is treated as an opaque blob. Signed-off-by: Olaf Weber --- fs/xfs/Makefile | 1 + fs/xfs/libxfs/xfs_dir2.c | 16 +++- fs/xfs/xfs_iops.c | 2 +- fs/xfs/xfs_utf8.c | 242 +++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_utf8.h | 25 +++++ 5 files changed, 281 insertions(+), 5 deletions(-) create mode 100644 fs/xfs/xfs_utf8.c create mode 100644 fs/xfs/xfs_utf8.h diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 0f7b300..5cc10f5 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -88,6 +88,7 @@ xfs-y += xfs_aops.o \ xfs_symlink.o \ xfs_sysfs.o \ xfs_trans.o \ + xfs_utf8.o \ xfs_xattr.o \ kmem.o \ uuid.o diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 84e5ca9..651ff94 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -35,6 +35,7 @@ #include "xfs_error.h" #include "xfs_trace.h" #include "xfs_dinode.h" +#include "xfs_utf8.h" struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2, XFS_DIR3_FT_DIR }; @@ -156,10 +157,17 @@ xfs_da_mount( (uint)sizeof(xfs_da_node_entry_t); dageo->magicpct = (dageo->blksize * 37) / 100; - if (xfs_sb_version_hasasciici(&mp->m_sb)) - mp->m_dirnameops = &xfs_ascii_ci_nameops; - else - mp->m_dirnameops = &xfs_default_nameops; + if (xfs_sb_version_hasutf8(&mp->m_sb)) { + if (xfs_sb_version_hasasciici(&mp->m_sb)) + mp->m_dirnameops = &xfs_utf8_ci_nameops; + else + mp->m_dirnameops = &xfs_utf8_nameops; + } else { + if (xfs_sb_version_hasasciici(&mp->m_sb)) + mp->m_dirnameops = &xfs_ascii_ci_nameops; + else + mp->m_dirnameops = &xfs_default_nameops; + } return 0; } diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index cea3d64..fbfb1bb 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -1257,7 +1257,7 @@ xfs_setup_inode( break; case S_IFDIR: lockdep_set_class(&ip->i_lock.mr_lock, &xfs_dir_ilock_class); - if (xfs_sb_version_hasasciici(&XFS_M(inode->i_sb)->m_sb)) + if (xfs_sb_version_hasci(&XFS_M(inode->i_sb)->m_sb)) inode->i_op = &xfs_dir_ci_inode_operations; else inode->i_op = &xfs_dir_inode_operations; diff --git a/fs/xfs/xfs_utf8.c b/fs/xfs/xfs_utf8.c new file mode 100644 index 0000000..7c18e43 --- /dev/null +++ b/fs/xfs/xfs_utf8.c @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "xfs.h" +#include "xfs_fs.h" +#include "xfs_types.h" +#include "xfs_bit.h" +#include "xfs_log_format.h" +#include "xfs_inum.h" +#include "xfs_trans.h" +#include "xfs_trans_resv.h" +#include "xfs_sb.h" +#include "xfs_ag.h" +#include "xfs_da_format.h" +#include "xfs_da_btree.h" +#include "xfs_dir2.h" +#include "xfs_mount.h" +#include "xfs_da_btree.h" +#include "xfs_format.h" +#include "xfs_bmap_btree.h" +#include "xfs_alloc_btree.h" +#include "xfs_dinode.h" +#include "xfs_inode.h" +#include "xfs_inode_item.h" +#include "xfs_bmap.h" +#include "xfs_error.h" +#include "xfs_trace.h" +#include "xfs_utf8.h" +#include + +/* + * xfs nameops using nfkdi + */ + +static xfs_dahash_t +xfs_utf8_hashname( + const unsigned char *name, + int len) +{ + utf8data_t nfkdi; + struct utf8cursor u8c; + xfs_dahash_t hash; + int val; + + nfkdi = utf8nfkdi(utf8version); + hash = 0; + if (utf8ncursor(&u8c, nfkdi, name, len) < 0) + goto blob; + while ((val = utf8byte(&u8c)) > 0) + hash = val ^ rol32(hash, 7); + /* In case of error treat the name as a binary blob. */ + if (val == 0) + return hash; +blob: + return xfs_da_hashname(name, len); +} + +static int +xfs_utf8_normhash( + struct xfs_da_args *args) +{ + utf8data_t nfkdi; + struct utf8cursor u8c; + unsigned char *norm; + ssize_t normlen; + int c; + + nfkdi = utf8nfkdi(utf8version); + /* Failure to normalize is treated as a blob. */ + if ((normlen = utf8nlen(nfkdi, args->name, args->namelen)) < 0) + goto blob; + if (utf8ncursor(&u8c, nfkdi, args->name, args->namelen) < 0) + goto blob; + if (!(norm = kmem_alloc(normlen + 1, KM_NOFS|KM_MAYFAIL))) + return -ENOMEM; + args->norm = norm; + args->normlen = normlen; + while ((c = utf8byte(&u8c)) > 0) + *norm++ = c; + if (c == 0) { + *norm = '\0'; + args->hashval = xfs_da_hashname(args->norm, args->normlen); + return 0; + } + kmem_free(args->norm); +blob: + args->norm = NULL; + args->normlen = -1; + args->hashval = xfs_da_hashname(args->name, args->namelen); + return 0; +} + +static enum xfs_dacmp +xfs_utf8_compname( + struct xfs_da_args *args, + const unsigned char *name, + int len) +{ + utf8data_t nfkdi; + struct utf8cursor u8c; + const unsigned char *norm; + int c; + + ASSERT(args->norm || args->normlen == -1); + + /* Check for an exact match first. */ + if (args->namelen == len && memcmp(args->name, name, len) == 0) + return XFS_CMP_EXACT; + /* xfs_utf8_normhash() set args->normlen to -1 for a blob */ + if (args->normlen < 0) + return XFS_CMP_DIFFERENT; + nfkdi = utf8nfkdi(utf8version); + if (utf8ncursor(&u8c, nfkdi, name, len) < 0) + return XFS_CMP_DIFFERENT; + norm = args->norm; + while ((c = utf8byte(&u8c)) > 0) + if (c != *norm++) + return XFS_CMP_DIFFERENT; + if (c < 0 || *norm != '\0') + return XFS_CMP_DIFFERENT; + return XFS_CMP_MATCH; +} + +struct xfs_nameops xfs_utf8_nameops = { + .hashname = xfs_utf8_hashname, + .normhash = xfs_utf8_normhash, + .compname = xfs_utf8_compname, +}; + +/* + * xfs nameops using nfkdicf + */ + +static xfs_dahash_t +xfs_utf8_ci_hashname( + const unsigned char *name, + int len) +{ + utf8data_t nfkdicf; + struct utf8cursor u8c; + xfs_dahash_t hash; + int val; + + nfkdicf = utf8nfkdicf(utf8version); + hash = 0; + if (utf8ncursor(&u8c, nfkdicf, name, len) < 0) + goto blob; + while ((val = utf8byte(&u8c)) > 0) + hash = val ^ rol32(hash, 7); + /* In case of error treat the name as a binary blob. */ + if (val == 0) + return hash; +blob: + return xfs_da_hashname(name, len); +} + +static int +xfs_utf8_ci_normhash( + struct xfs_da_args *args) +{ + utf8data_t nfkdicf; + struct utf8cursor u8c; + unsigned char *norm; + ssize_t normlen; + int c; + + nfkdicf = utf8nfkdicf(utf8version); + /* Failure to normalize is treated as a blob. */ + if ((normlen = utf8nlen(nfkdicf, args->name, args->namelen)) < 0) + goto blob; + if (utf8ncursor(&u8c, nfkdicf, args->name, args->namelen) < 0) + goto blob; + if (!(norm = kmem_alloc(normlen + 1, KM_NOFS|KM_MAYFAIL))) + return -ENOMEM; + args->norm = norm; + args->normlen = normlen; + while ((c = utf8byte(&u8c)) > 0) + *norm++ = c; + if (c == 0) { + *norm = '\0'; + args->hashval = xfs_da_hashname(args->norm, args->normlen); + return 0; + } + kmem_free(args->norm); +blob: + args->norm = NULL; + args->normlen = -1; + args->hashval = xfs_da_hashname(args->name, args->namelen); + return 0; +} + +static enum xfs_dacmp +xfs_utf8_ci_compname( + struct xfs_da_args *args, + const unsigned char *name, + int len) +{ + utf8data_t nfkdicf; + struct utf8cursor u8c; + const unsigned char *norm; + int c; + + ASSERT(args->norm || args->normlen == -1); + + /* Check for an exact match first. */ + if (args->namelen == len && memcmp(args->name, name, len) == 0) + return XFS_CMP_EXACT; + /* xfs_utf8_ci_normhash() set args->normlen to -1 for a blob */ + if (args->normlen < 0) + return XFS_CMP_DIFFERENT; + nfkdicf = utf8nfkdicf(utf8version); + if (utf8ncursor(&u8c, nfkdicf, name, len) < 0) + return XFS_CMP_DIFFERENT; + norm = args->norm; + while ((c = utf8byte(&u8c)) > 0) + if (c != *norm++) + return XFS_CMP_DIFFERENT; + if (c < 0 || *norm != '\0') + return XFS_CMP_DIFFERENT; + return XFS_CMP_MATCH; +} + +struct xfs_nameops xfs_utf8_ci_nameops = { + .hashname = xfs_utf8_ci_hashname, + .normhash = xfs_utf8_ci_normhash, + .compname = xfs_utf8_ci_compname, +}; diff --git a/fs/xfs/xfs_utf8.h b/fs/xfs/xfs_utf8.h new file mode 100644 index 0000000..97b6a91 --- /dev/null +++ b/fs/xfs/xfs_utf8.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef XFS_UTF8_H +#define XFS_UTF8_H + +extern struct xfs_nameops xfs_utf8_nameops; +extern struct xfs_nameops xfs_utf8_ci_nameops; + +#endif /* XFS_UTF8_H */ -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 15:50:24 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 507FA7F85 for ; Thu, 11 Sep 2014 15:50:24 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1E9958F8037; Thu, 11 Sep 2014 13:50:24 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id E19E04266DC; Thu, 11 Sep 2014 15:50:23 -0500 (CDT) Date: Thu, 11 Sep 2014 15:50:23 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 9/9] xfs: apply utf-8 normalization rules to user extended attribute names Message-ID: <20140911205023.GI13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Apply the same rules for UTF-8 normalization to the names of user-defined extended attributes. System attributes are excluded because they are not user-visible in the first place, and the kernel is expected to know what it is doing when naming them. Signed-off-by: Olaf Weber --- fs/xfs/libxfs/xfs_attr.c | 56 ++++++++++++++++++++++++++++++++++++------- fs/xfs/libxfs/xfs_attr_leaf.c | 11 +++++++-- fs/xfs/xfs_attr_list.c | 11 ++++++++- fs/xfs/xfs_utf8.c | 7 ++++++ 4 files changed, 74 insertions(+), 11 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 353fb42..68e7ce3 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -83,12 +83,14 @@ xfs_attr_args_init( const unsigned char *name, int flags) { + struct xfs_mount *mp = dp->i_mount; + int error; if (!name) return -EINVAL; memset(args, 0, sizeof(*args)); - args->geo = dp->i_mount->m_attr_geo; + args->geo = mp->m_attr_geo; args->whichfork = XFS_ATTR_FORK; args->dp = dp; args->flags = flags; @@ -97,7 +99,11 @@ xfs_attr_args_init( if (args->namelen >= MAXNAMELEN) return -EFAULT; /* match IRIX behaviour */ - args->hashval = xfs_da_hashname(args->name, args->namelen); + if (!xfs_sb_version_hasutf8(&mp->m_sb)) + args->hashval = xfs_da_hashname(args->name, args->namelen); + else if ((error = mp->m_dirnameops->normhash(args)) != 0) + return error; + return 0; } @@ -154,6 +160,9 @@ xfs_attr_get( error = xfs_attr_node_get(&args); xfs_iunlock(ip, lock_mode); + if (args.norm) + kmem_free(args.norm); + *valuelenp = args.valuelen; return error == -EEXIST ? 0 : error; } @@ -216,8 +225,11 @@ xfs_attr_set( return -EIO; error = xfs_attr_args_init(&args, dp, name, flags); - if (error) + if (error) { + if (args.norm) + kmem_free(args.norm); return error; + } args.value = value; args.valuelen = valuelen; @@ -227,8 +239,11 @@ xfs_attr_set( args.total = xfs_attr_calc_size(&args, &local); error = xfs_qm_dqattach(dp, 0); - if (error) + if (error) { + if (args.norm) + kmem_free(args.norm); return error; + } /* * If the inode doesn't have an attribute fork, add one. @@ -239,8 +254,11 @@ xfs_attr_set( XFS_ATTR_SF_ENTSIZE_BYNAME(args.namelen, valuelen); error = xfs_bmap_add_attrfork(dp, sf_size, rsvd); - if (error) + if (error) { + if (args.norm) + kmem_free(args.norm); return error; + } } /* @@ -270,6 +288,8 @@ xfs_attr_set( error = xfs_trans_reserve(args.trans, &tres, args.total, 0); if (error) { xfs_trans_cancel(args.trans, 0); + if (args.norm) + kmem_free(args.norm); return error; } xfs_ilock(dp, XFS_ILOCK_EXCL); @@ -280,6 +300,8 @@ xfs_attr_set( if (error) { xfs_iunlock(dp, XFS_ILOCK_EXCL); xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES); + if (args.norm) + kmem_free(args.norm); return error; } @@ -327,6 +349,8 @@ xfs_attr_set( XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (args.norm) + kmem_free(args.norm); return error ? error : err2; } @@ -388,7 +412,8 @@ xfs_attr_set( xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE); error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); - + if (args.norm) + kmem_free(args.norm); return error; out: @@ -397,6 +422,8 @@ out: XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); } xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (args.norm) + kmem_free(args.norm); return error; } @@ -425,8 +452,11 @@ xfs_attr_remove( return -ENOATTR; error = xfs_attr_args_init(&args, dp, name, flags); - if (error) + if (error) { + if (args.norm) + kmem_free(args.norm); return error; + } args.firstblock = &firstblock; args.flist = &flist; @@ -439,8 +469,11 @@ xfs_attr_remove( args.op_flags = XFS_DA_OP_OKNOENT; error = xfs_qm_dqattach(dp, 0); - if (error) + if (error) { + if (args.norm) + kmem_free(args.norm); return error; + } /* * Start our first transaction of the day. @@ -466,6 +499,8 @@ xfs_attr_remove( XFS_ATTRRM_SPACE_RES(mp), 0); if (error) { xfs_trans_cancel(args.trans, 0); + if (args.norm) + kmem_free(args.norm); return error; } @@ -506,6 +541,8 @@ xfs_attr_remove( xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE); error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (args.norm) + kmem_free(args.norm); return error; @@ -515,6 +552,9 @@ out: XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); } xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (args.norm) + kmem_free(args.norm); + return error; } diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index b1f73db..c991a88 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -661,6 +661,7 @@ int xfs_attr_shortform_to_leaf(xfs_da_args_t *args) { xfs_inode_t *dp; + struct xfs_mount *mp; xfs_attr_shortform_t *sf; xfs_attr_sf_entry_t *sfe; xfs_da_args_t nargs; @@ -673,6 +674,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) trace_xfs_attr_sf_to_leaf(args); dp = args->dp; + mp = dp->i_mount; ifp = dp->i_afp; sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; size = be16_to_cpu(sf->hdr.totsize); @@ -726,13 +728,18 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) nargs.namelen = sfe->namelen; nargs.value = &sfe->nameval[nargs.namelen]; nargs.valuelen = sfe->valuelen; - nargs.hashval = xfs_da_hashname(sfe->nameval, - sfe->namelen); nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags); + if (!xfs_sb_version_hasutf8(&mp->m_sb)) + nargs.hashval = xfs_da_hashname(sfe->nameval, + sfe->namelen); + else if ((error = mp->m_dirnameops->normhash(&nargs)) != 0) + goto out; error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */ ASSERT(error == -ENOATTR); error = xfs_attr3_leaf_add(bp, &nargs); ASSERT(error != -ENOSPC); + if (nargs.norm) + kmem_free(nargs.norm); if (error) goto out; sfe = XFS_ATTR_SF_NEXTENTRY(sfe); diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index 62db83a..4075d54 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c @@ -76,12 +76,14 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) xfs_attr_shortform_t *sf; xfs_attr_sf_entry_t *sfe; xfs_inode_t *dp; + struct xfs_mount *mp; int sbsize, nsbuf, count, i; int error; ASSERT(context != NULL); dp = context->dp; ASSERT(dp != NULL); + mp = dp->i_mount; ASSERT(dp->i_afp != NULL); sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data; ASSERT(sf != NULL); @@ -154,7 +156,14 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) } sbp->entno = i; - sbp->hash = xfs_da_hashname(sfe->nameval, sfe->namelen); + /* ATTR_ROOT and ATTR_SECURE are never normalized. */ + if (!xfs_sb_version_hasutf8(&mp->m_sb) || + (sfe->flags & (ATTR_ROOT|ATTR_SECURE))) { + sbp->hash = xfs_da_hashname(sfe->nameval, sfe->namelen); + } else { + sbp->hash = mp->m_dirnameops->hashname(sfe->nameval, + sfe->namelen); + } sbp->name = sfe->nameval; sbp->namelen = sfe->namelen; /* These are bytes, and both on-disk, don't endian-flip */ diff --git a/fs/xfs/xfs_utf8.c b/fs/xfs/xfs_utf8.c index 7c18e43..8df05fe 100644 --- a/fs/xfs/xfs_utf8.c +++ b/fs/xfs/xfs_utf8.c @@ -38,6 +38,7 @@ #include "xfs_inode.h" #include "xfs_inode_item.h" #include "xfs_bmap.h" +#include "xfs_attr.h" #include "xfs_error.h" #include "xfs_trace.h" #include "xfs_utf8.h" @@ -80,6 +81,9 @@ xfs_utf8_normhash( ssize_t normlen; int c; + /* Don't normalize system attribute names. */ + if (args->flags & (ATTR_ROOT|ATTR_SECURE)) + goto blob; nfkdi = utf8nfkdi(utf8version); /* Failure to normalize is treated as a blob. */ if ((normlen = utf8nlen(nfkdi, args->name, args->namelen)) < 0) @@ -179,6 +183,9 @@ xfs_utf8_ci_normhash( ssize_t normlen; int c; + /* Don't normalize system attribute names. */ + if (args->flags & (ATTR_ROOT|ATTR_SECURE)) + goto blob; nfkdicf = utf8nfkdicf(utf8version); /* Failure to normalize is treated as a blob. */ if ((normlen = utf8nlen(nfkdicf, args->name, args->namelen)) < 0) -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 15:51:47 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 64F057F85 for ; Thu, 11 Sep 2014 15:51:47 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id DC3EFAC00E; Thu, 11 Sep 2014 13:51:46 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 8263F4266DC; Thu, 11 Sep 2014 15:51:46 -0500 (CDT) Date: Thu, 11 Sep 2014 15:51:46 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 01/13] libxfs: return the first match during case-insensitive lookup Message-ID: <20140911205146.GJ13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Change the XFS case-insensitive lookup code to return the first match found, even if it is not an exact match. Whether a filesystem uses case-insensitive lookups is determined by a superblock bit set during filesystem creation. This means that normal use cannot create two files that both match the same filename. Signed-off-by: Olaf Weber --- libxfs/xfs_dir2_block.c | 17 ++++------- libxfs/xfs_dir2_leaf.c | 38 ++++------------------- libxfs/xfs_dir2_node.c | 80 ++++++++++++++++++------------------------------- libxfs/xfs_dir2_sf.c | 8 ++--- 4 files changed, 44 insertions(+), 99 deletions(-) diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c index cede01f..2880431 100644 --- a/libxfs/xfs_dir2_block.c +++ b/libxfs/xfs_dir2_block.c @@ -705,28 +705,21 @@ xfs_dir2_block_lookup_int( dep = (xfs_dir2_data_entry_t *) ((char *)hdr + xfs_dir2_dataptr_to_off(mp, addr)); /* - * Compare name and if it's an exact match, return the index - * and buffer. If it's the first case-insensitive match, store - * the index and buffer and continue looking for an exact match. + * Compare name and if it's a match, return the + * index and buffer. */ cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); - if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { + if (cmp != XFS_CMP_DIFFERENT) { args->cmpresult = cmp; *bpp = bp; *entno = mid; - if (cmp == XFS_CMP_EXACT) - return 0; + return 0; } } while (++mid < be32_to_cpu(btp->count) && be32_to_cpu(blp[mid].hashval) == hash); ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); - /* - * Here, we can only be doing a lookup (not a rename or replace). - * If a case-insensitive match was found earlier, return success. - */ - if (args->cmpresult == XFS_CMP_CASE) - return 0; + ASSERT(args->cmpresult == XFS_CMP_DIFFERENT); /* * No match, release the buffer and return ENOENT. */ diff --git a/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c index 8e0cbc9..b1901d3 100644 --- a/libxfs/xfs_dir2_leaf.c +++ b/libxfs/xfs_dir2_leaf.c @@ -1246,7 +1246,6 @@ xfs_dir2_leaf_lookup_int( xfs_mount_t *mp; /* filesystem mount point */ xfs_dir2_db_t newdb; /* new data block number */ xfs_trans_t *tp; /* transaction pointer */ - xfs_dir2_db_t cidb = -1; /* case match data block no. */ enum xfs_dacmp cmp; /* name compare result */ struct xfs_dir2_leaf_entry *ents; struct xfs_dir3_icleaf_hdr leafhdr; @@ -1307,47 +1306,22 @@ xfs_dir2_leaf_lookup_int( dep = (xfs_dir2_data_entry_t *)((char *)dbp->b_addr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); /* - * Compare name and if it's an exact match, return the index - * and buffer. If it's the first case-insensitive match, store - * the index and buffer and continue looking for an exact match. + * Compare name and if it's a match, return the index + * and buffer. */ cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); - if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { + if (cmp != XFS_CMP_DIFFERENT) { args->cmpresult = cmp; *indexp = index; - /* case exact match: return the current buffer. */ - if (cmp == XFS_CMP_EXACT) { - *dbpp = dbp; - return 0; - } - cidb = curdb; + *dbpp = dbp; + return 0; } } ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); - /* - * Here, we can only be doing a lookup (not a rename or remove). - * If a case-insensitive match was found earlier, re-read the - * appropriate data block if required and return it. - */ - if (args->cmpresult == XFS_CMP_CASE) { - ASSERT(cidb != -1); - if (cidb != curdb) { - xfs_trans_brelse(tp, dbp); - error = xfs_dir3_data_read(tp, dp, - xfs_dir2_db_to_da(mp, cidb), - -1, &dbp); - if (error) { - xfs_trans_brelse(tp, lbp); - return error; - } - } - *dbpp = dbp; - return 0; - } + ASSERT(args->cmpresult == XFS_CMP_DIFFERENT); /* * No match found, return ENOENT. */ - ASSERT(cidb == -1); if (dbp) xfs_trans_brelse(tp, dbp); xfs_trans_brelse(tp, lbp); diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c index 3737e4e..fb27506 100644 --- a/libxfs/xfs_dir2_node.c +++ b/libxfs/xfs_dir2_node.c @@ -702,6 +702,7 @@ xfs_dir2_leafn_lookup_for_entry( xfs_dir2_db_t curdb = -1; /* current data block number */ xfs_dir2_data_entry_t *dep; /* data block entry */ xfs_inode_t *dp; /* incore directory inode */ + int di = -1; /* data entry index */ int error; /* error return value */ int index; /* leaf entry index */ xfs_dir2_leaf_t *leaf; /* leaf structure */ @@ -733,6 +734,7 @@ xfs_dir2_leafn_lookup_for_entry( if (state->extravalid) { curbp = state->extrablk.bp; curdb = state->extrablk.blkno; + di = state->extrablk.index; } /* * Loop over leaf entries with the right hash value. @@ -757,27 +759,20 @@ xfs_dir2_leafn_lookup_for_entry( */ if (newdb != curdb) { /* - * If we had a block before that we aren't saving - * for a CI name, drop it + * If we had a block, drop it */ - if (curbp && (args->cmpresult == XFS_CMP_DIFFERENT || - curdb != state->extrablk.blkno)) + if (curbp) { xfs_trans_brelse(tp, curbp); + di = -1; + } /* - * If needing the block that is saved with a CI match, - * use it otherwise read in the new data block. + * Read in the new data block. */ - if (args->cmpresult != XFS_CMP_DIFFERENT && - newdb == state->extrablk.blkno) { - ASSERT(state->extravalid); - curbp = state->extrablk.bp; - } else { - error = xfs_dir3_data_read(tp, dp, - xfs_dir2_db_to_da(mp, newdb), - -1, &curbp); - if (error) - return error; - } + error = xfs_dir3_data_read(tp, dp, + xfs_dir2_db_to_da(mp, newdb), + -1, &curbp); + if (error) + return error; xfs_dir3_data_check(dp, curbp); curdb = newdb; } @@ -787,53 +782,36 @@ xfs_dir2_leafn_lookup_for_entry( dep = (xfs_dir2_data_entry_t *)((char *)curbp->b_addr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); /* - * Compare the entry and if it's an exact match, return - * EEXIST immediately. If it's the first case-insensitive - * match, store the block & inode number and continue looking. + * Compare the entry and if it's a match, return + * EEXIST immediately. */ cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); - if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { - /* If there is a CI match block, drop it */ - if (args->cmpresult != XFS_CMP_DIFFERENT && - curdb != state->extrablk.blkno) - xfs_trans_brelse(tp, state->extrablk.bp); + if (cmp != XFS_CMP_DIFFERENT) { args->cmpresult = cmp; args->inumber = be64_to_cpu(dep->inumber); args->filetype = xfs_dir3_dirent_get_ftype(mp, dep); - *indexp = index; - state->extravalid = 1; - state->extrablk.bp = curbp; - state->extrablk.blkno = curdb; - state->extrablk.index = (int)((char *)dep - - (char *)curbp->b_addr); - state->extrablk.magic = XFS_DIR2_DATA_MAGIC; - curbp->b_ops = &xfs_dir3_data_buf_ops; - xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF); - if (cmp == XFS_CMP_EXACT) - return XFS_ERROR(EEXIST); + error = EEXIST; + goto out; } } + /* Didn't find a match */ + error = ENOENT; ASSERT(index == leafhdr.count || (args->op_flags & XFS_DA_OP_OKNOENT)); +out: if (curbp) { - if (args->cmpresult == XFS_CMP_DIFFERENT) { - /* Giving back last used data block. */ - state->extravalid = 1; - state->extrablk.bp = curbp; - state->extrablk.index = -1; - state->extrablk.blkno = curdb; - state->extrablk.magic = XFS_DIR2_DATA_MAGIC; - curbp->b_ops = &xfs_dir3_data_buf_ops; - xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF); - } else { - /* If the curbp is not the CI match block, drop it */ - if (state->extrablk.bp != curbp) - xfs_trans_brelse(tp, curbp); - } + /* Giving back last used data block. */ + state->extravalid = 1; + state->extrablk.bp = curbp; + state->extrablk.index = di; + state->extrablk.blkno = curdb; + state->extrablk.magic = XFS_DIR2_DATA_MAGIC; + curbp->b_ops = &xfs_dir3_data_buf_ops; + xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF); } else { state->extravalid = 0; } *indexp = index; - return XFS_ERROR(ENOENT); + return XFS_ERROR(error); } /* diff --git a/libxfs/xfs_dir2_sf.c b/libxfs/xfs_dir2_sf.c index 7580333..7b01d43 100644 --- a/libxfs/xfs_dir2_sf.c +++ b/libxfs/xfs_dir2_sf.c @@ -833,13 +833,12 @@ xfs_dir2_sf_lookup( for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep)) { /* - * Compare name and if it's an exact match, return the inode - * number. If it's the first case-insensitive match, store the - * inode number and continue looking for an exact match. + * Compare name and if it's a match, return the inode + * number. */ cmp = dp->i_mount->m_dirnameops->compname(args, sfep->name, sfep->namelen); - if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { + if (cmp != XFS_CMP_DIFFERENT) { args->cmpresult = cmp; args->inumber = xfs_dir3_sfe_get_ino(dp->i_mount, sfp, sfep); @@ -848,6 +847,7 @@ xfs_dir2_sf_lookup( if (cmp == XFS_CMP_EXACT) return XFS_ERROR(EEXIST); ci_sfep = sfep; + break; } } ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 15:52:39 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 7426E7F82 for ; Thu, 11 Sep 2014 15:52:39 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id 046E8AC001; Thu, 11 Sep 2014 13:52:39 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id B87544266DC; Thu, 11 Sep 2014 15:52:38 -0500 (CDT) Date: Thu, 11 Sep 2014 15:52:38 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 02/13] libxfs: rename XFS_CMP_CASE to XFS_CMP_MATCH Message-ID: <20140911205238.GK13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Rename XFS_CMP_CASE to XFS_CMP_MATCH. With unicode filenames and normalization, different strings will match on other criteria than case insensitivity. Signed-off-by: Olaf Weber --- include/xfs_da_btree.h | 2 +- libxfs/xfs_dir2.c | 9 ++++++--- libxfs/xfs_dir2_node.c | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/xfs_da_btree.h b/include/xfs_da_btree.h index e492dca..3d9f9dd 100644 --- a/include/xfs_da_btree.h +++ b/include/xfs_da_btree.h @@ -34,7 +34,7 @@ struct zone; enum xfs_dacmp { XFS_CMP_DIFFERENT, /* names are completely different */ XFS_CMP_EXACT, /* names are exactly the same */ - XFS_CMP_CASE /* names are same but differ in case */ + XFS_CMP_MATCH /* names are same but differ in encoding */ }; /* diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index 4c8c836..57e98a3 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -72,7 +72,7 @@ xfs_ascii_ci_compname( continue; if (tolower(args->name[i]) != tolower(name[i])) return XFS_CMP_DIFFERENT; - result = XFS_CMP_CASE; + result = XFS_CMP_MATCH; } return result; @@ -248,8 +248,11 @@ xfs_dir_cilookup_result( { if (args->cmpresult == XFS_CMP_DIFFERENT) return ENOENT; - if (args->cmpresult != XFS_CMP_CASE || - !(args->op_flags & XFS_DA_OP_CILOOKUP)) + if (args->cmpresult == XFS_CMP_EXACT) + return EEXIST; + ASSERT(args->cmpresult == XFS_CMP_MATCH); + /* Only dup the found name if XFS_DA_OP_CILOOKUP is set. */ + if (!(args->op_flags & XFS_DA_OP_CILOOKUP)) return EEXIST; args->value = kmem_alloc(len, KM_NOFS | KM_MAYFAIL); diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c index fb27506..550ca99 100644 --- a/libxfs/xfs_dir2_node.c +++ b/libxfs/xfs_dir2_node.c @@ -2034,7 +2034,7 @@ xfs_dir2_node_lookup( error = xfs_da3_node_lookup_int(state, &rval); if (error) rval = error; - else if (rval == ENOENT && args->cmpresult == XFS_CMP_CASE) { + else if (rval == ENOENT && args->cmpresult == XFS_CMP_MATCH) { /* If a CI match, dup the actual name and return EEXIST */ xfs_dir2_data_entry_t *dep; -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 15:53:57 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 410317F86 for ; Thu, 11 Sep 2014 15:53:57 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id 103D18F8037; Thu, 11 Sep 2014 13:53:57 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id CF8A44266DC; Thu, 11 Sep 2014 15:53:56 -0500 (CDT) Date: Thu, 11 Sep 2014 15:53:56 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 03/13] libxfs: add xfs_nameops.normhash Message-ID: <20140911205356.GL13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Add a normhash callout to the xfs_nameops. This callout takes an xfs_da_args structure as its argument, and calculates a hash value over the name. It may in the process create a normalized form of the name, and assign that to the norm/normlen fields in the xfs_da_args structure. Changes: The pointer in kmem_free() was type converted to suppress compiler warnings. Signed-off-by: Olaf Weber --- include/xfs_da_btree.h | 5 ++++- libxfs/xfs_da_btree.c | 9 ++++++++ libxfs/xfs_dir2.c | 56 +++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/include/xfs_da_btree.h b/include/xfs_da_btree.h index 3d9f9dd..06b50bf 100644 --- a/include/xfs_da_btree.h +++ b/include/xfs_da_btree.h @@ -42,7 +42,9 @@ enum xfs_dacmp { */ typedef struct xfs_da_args { const __uint8_t *name; /* string (maybe not NULL terminated) */ - int namelen; /* length of string (maybe no NULL) */ + const __uint8_t *norm; /* normalized name (may be NULL) */ + int namelen; /* length of string (maybe no NULL) */ + int normlen; /* length of normalized name */ __uint8_t filetype; /* filetype of inode for directories */ __uint8_t *value; /* set of bytes (maybe contain NULLs) */ int valuelen; /* length of value */ @@ -131,6 +133,7 @@ typedef struct xfs_da_state { */ struct xfs_nameops { xfs_dahash_t (*hashname)(struct xfs_name *); + int (*normhash)(struct xfs_da_args *); enum xfs_dacmp (*compname)(struct xfs_da_args *, const unsigned char *, int); }; diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c index b731b54..eb97317 100644 --- a/libxfs/xfs_da_btree.c +++ b/libxfs/xfs_da_btree.c @@ -2000,8 +2000,17 @@ xfs_default_hashname( return xfs_da_hashname(name->name, name->len); } +STATIC int +xfs_da_normhash( + struct xfs_da_args *args) +{ + args->hashval = xfs_da_hashname(args->name, args->namelen); + return 0; +} + const struct xfs_nameops xfs_default_nameops = { .hashname = xfs_default_hashname, + .normhash = xfs_da_normhash, .compname = xfs_da_compname }; diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index 57e98a3..e52d082 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -54,6 +54,21 @@ xfs_ascii_ci_hashname( return hash; } +STATIC int +xfs_ascii_ci_normhash( + struct xfs_da_args *args) +{ + xfs_dahash_t hash; + int i; + + for (i = 0, hash = 0; i < args->namelen; i++) + hash = tolower(args->name[i]) ^ rol32(hash, 7); + + args->hashval = hash; + return 0; +} + + STATIC enum xfs_dacmp xfs_ascii_ci_compname( struct xfs_da_args *args, @@ -80,6 +95,7 @@ xfs_ascii_ci_compname( static struct xfs_nameops xfs_ascii_ci_nameops = { .hashname = xfs_ascii_ci_hashname, + .normhash = xfs_ascii_ci_normhash, .compname = xfs_ascii_ci_compname, }; @@ -211,7 +227,6 @@ xfs_dir_createname( args.name = name->name; args.namelen = name->len; args.filetype = name->type; - args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = inum; args.dp = dp; args.firstblock = first; @@ -220,19 +235,24 @@ xfs_dir_createname( args.whichfork = XFS_DATA_FORK; args.trans = tp; args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; + if ((rval = dp->i_mount->m_dirnameops->normhash(&args))) + return rval; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_addname(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_block_addname(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_leaf_addname(&args); else rval = xfs_dir2_node_addname(&args); +out_free: + if (args.norm) + kmem_free((void *)args.norm); return rval; } @@ -289,22 +309,23 @@ xfs_dir_lookup( args.name = name->name; args.namelen = name->len; args.filetype = name->type; - args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.dp = dp; args.whichfork = XFS_DATA_FORK; args.trans = tp; args.op_flags = XFS_DA_OP_OKNOENT; if (ci_name) args.op_flags |= XFS_DA_OP_CILOOKUP; + if ((rval = dp->i_mount->m_dirnameops->normhash(&args))) + return rval; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_lookup(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_block_lookup(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_leaf_lookup(&args); else @@ -318,6 +339,9 @@ xfs_dir_lookup( ci_name->len = args.valuelen; } } +out_free: + if (args.norm) + kmem_free((void *)args.norm); return rval; } @@ -345,7 +369,6 @@ xfs_dir_removename( args.name = name->name; args.namelen = name->len; args.filetype = name->type; - args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = ino; args.dp = dp; args.firstblock = first; @@ -353,19 +376,24 @@ xfs_dir_removename( args.total = total; args.whichfork = XFS_DATA_FORK; args.trans = tp; + if ((rval = dp->i_mount->m_dirnameops->normhash(&args))) + return rval; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_removename(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_block_removename(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_leaf_removename(&args); else rval = xfs_dir2_node_removename(&args); +out_free: + if (args.norm) + kmem_free((void *)args.norm); return rval; } @@ -395,7 +423,6 @@ xfs_dir_replace( args.name = name->name; args.namelen = name->len; args.filetype = name->type; - args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = inum; args.dp = dp; args.firstblock = first; @@ -403,19 +430,24 @@ xfs_dir_replace( args.total = total; args.whichfork = XFS_DATA_FORK; args.trans = tp; + if ((rval = dp->i_mount->m_dirnameops->normhash(&args))) + return rval; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_replace(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_block_replace(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_leaf_replace(&args); else rval = xfs_dir2_node_replace(&args); +out_free: + if (args.norm) + kmem_free((void *)args.norm); return rval; } -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 15:55:35 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 297D27F99 for ; Thu, 11 Sep 2014 15:55:35 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9E2C1AC001; Thu, 11 Sep 2014 13:55:34 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 405CD4266DC; Thu, 11 Sep 2014 15:55:34 -0500 (CDT) Date: Thu, 11 Sep 2014 15:55:34 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 04/13] libxfs: change interface of xfs_nameops.normhash Message-ID: <20140911205534.GM13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber With the introduction of the xfs_nameops.normhash callout, all uses of the hashname callout now occur in places where an xfs_name structure must be explicitly created just to match the parameter passing convention of this callout. Change the arguments to a const unsigned char * and int instead. Signed-off-by: Olaf Weber --- db/check.c | 6 ++---- include/xfs_da_btree.h | 2 +- libxfs/xfs_da_btree.c | 9 +-------- libxfs/xfs_dir2.c | 10 ++++++---- libxfs/xfs_dir2_block.c | 5 +---- libxfs/xfs_dir2_data.c | 6 ++---- repair/phase6.c | 2 +- 7 files changed, 14 insertions(+), 26 deletions(-) diff --git a/db/check.c b/db/check.c index 4fd9fd0..49359d7 100644 --- a/db/check.c +++ b/db/check.c @@ -2212,7 +2212,6 @@ process_data_dir_v2( int stale = 0; int tag_err; __be16 *tagp; - struct xfs_name xname; data = iocur_top->data; block = iocur_top->data; @@ -2323,9 +2322,8 @@ process_data_dir_v2( tag_err += be16_to_cpu(*tagp) != (char *)dep - (char *)data; addr = xfs_dir2_db_off_to_dataptr(mp, db, (char *)dep - (char *)data); - xname.name = dep->name; - xname.len = dep->namelen; - dir_hash_add(mp->m_dirnameops->hashname(&xname), addr); + dir_hash_add(mp->m_dirnameops->hashname(dep->name, + dep->namelen), addr); ptr += xfs_dir3_data_entsize(mp, dep->namelen); count++; lastfree = 0; diff --git a/include/xfs_da_btree.h b/include/xfs_da_btree.h index 06b50bf..9674bed 100644 --- a/include/xfs_da_btree.h +++ b/include/xfs_da_btree.h @@ -132,7 +132,7 @@ typedef struct xfs_da_state { * Name ops for directory and/or attr name operations */ struct xfs_nameops { - xfs_dahash_t (*hashname)(struct xfs_name *); + xfs_dahash_t (*hashname)(const unsigned char *, int); int (*normhash)(struct xfs_da_args *); enum xfs_dacmp (*compname)(struct xfs_da_args *, const unsigned char *, int); diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c index eb97317..7be5eaf 100644 --- a/libxfs/xfs_da_btree.c +++ b/libxfs/xfs_da_btree.c @@ -1993,13 +1993,6 @@ xfs_da_compname( XFS_CMP_EXACT : XFS_CMP_DIFFERENT; } -static xfs_dahash_t -xfs_default_hashname( - struct xfs_name *name) -{ - return xfs_da_hashname(name->name, name->len); -} - STATIC int xfs_da_normhash( struct xfs_da_args *args) @@ -2009,7 +2002,7 @@ xfs_da_normhash( } const struct xfs_nameops xfs_default_nameops = { - .hashname = xfs_default_hashname, + .hashname = xfs_da_hashname, .normhash = xfs_da_normhash, .compname = xfs_da_compname }; diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index e52d082..1893931 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -43,13 +43,14 @@ const unsigned char xfs_mode_to_ftype[S_IFMT >> S_SHIFT] = { */ STATIC xfs_dahash_t xfs_ascii_ci_hashname( - struct xfs_name *name) + const unsigned char *name, + int len) { xfs_dahash_t hash; int i; - for (i = 0, hash = 0; i < name->len; i++) - hash = tolower(name->name[i]) ^ rol32(hash, 7); + for (i = 0, hash = 0; i < len; i++) + hash = tolower(name[i]) ^ rol32(hash, 7); return hash; } @@ -475,7 +476,8 @@ xfs_dir_canenter( args.name = name->name; args.namelen = name->len; args.filetype = name->type; - args.hashval = dp->i_mount->m_dirnameops->hashname(name); + args.hashval = dp->i_mount->m_dirnameops->hashname(name->name, + name->len); args.dp = dp; args.whichfork = XFS_DATA_FORK; args.trans = tp; diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c index 2880431..1a8b5f5 100644 --- a/libxfs/xfs_dir2_block.c +++ b/libxfs/xfs_dir2_block.c @@ -1047,7 +1047,6 @@ xfs_dir2_sf_to_block( xfs_dir2_sf_hdr_t *sfp; /* shortform header */ __be16 *tagp; /* end of data entry */ xfs_trans_t *tp; /* transaction pointer */ - struct xfs_name name; struct xfs_ifork *ifp; trace_xfs_dir2_sf_to_block(args); @@ -1205,10 +1204,8 @@ xfs_dir2_sf_to_block( tagp = xfs_dir3_data_entry_tag_p(mp, dep); *tagp = cpu_to_be16((char *)dep - (char *)hdr); xfs_dir2_data_log_entry(tp, bp, dep); - name.name = sfep->name; - name.len = sfep->namelen; blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops-> - hashname(&name)); + hashname(sfep->name, sfep->namelen)); blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, (char *)dep - (char *)hdr)); offset = (int)((char *)(tagp + 1) - (char *)hdr); diff --git a/libxfs/xfs_dir2_data.c b/libxfs/xfs_dir2_data.c index dc9df4d..9b3f750 100644 --- a/libxfs/xfs_dir2_data.c +++ b/libxfs/xfs_dir2_data.c @@ -46,7 +46,6 @@ __xfs_dir3_data_check( xfs_mount_t *mp; /* filesystem mount point */ char *p; /* current data position */ int stale; /* count of stale leaves */ - struct xfs_name name; mp = bp->b_target->bt_mount; hdr = bp->b_addr; @@ -142,9 +141,8 @@ __xfs_dir3_data_check( addr = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, (xfs_dir2_data_aoff_t) ((char *)dep - (char *)hdr)); - name.name = dep->name; - name.len = dep->namelen; - hash = mp->m_dirnameops->hashname(&name); + hash = mp->m_dirnameops-> + hashname(dep->name, dep->namelen); for (i = 0; i < be32_to_cpu(btp->count); i++) { if (be32_to_cpu(lep[i].address) == addr && be32_to_cpu(lep[i].hashval) == hash) diff --git a/repair/phase6.c b/repair/phase6.c index f13069f..f374fd0 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -195,7 +195,7 @@ dir_hash_add( dup = 0; if (!junk) { - hash = mp->m_dirnameops->hashname(&xname); + hash = mp->m_dirnameops->hashname(name, namelen); byhash = DIR_HASH_FUNC(hashtab, hash); /* -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 15:56:32 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 628F07F9C for ; Thu, 11 Sep 2014 15:56:32 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id E39ACAC001; Thu, 11 Sep 2014 13:56:31 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 8E7FC4266DC; Thu, 11 Sep 2014 15:56:31 -0500 (CDT) Date: Thu, 11 Sep 2014 15:56:31 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 05/13] libxfs: add a superblock feature bit to indicate UTF-8 support. Message-ID: <20140911205631.GN13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber When UTF-8 support is enabled, the xfs_dir_ci_inode_operations must be installed. Add xfs_sb_version_hasci(), which tests both the borgbit and the utf8bit, and returns true if at least one of them is set. Replace calls to xfs_sb_version_hasasciici() as needed. Signed-off-by: Olaf Weber --- include/xfs_fs.h | 2 +- include/xfs_sb.h | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/include/xfs_fs.h b/include/xfs_fs.h index 59c40fc..1be539d 100644 --- a/include/xfs_fs.h +++ b/include/xfs_fs.h @@ -239,7 +239,7 @@ typedef struct xfs_fsop_resblks { #define XFS_FSOP_GEOM_FLAGS_V5SB 0x8000 /* version 5 superblock */ #define XFS_FSOP_GEOM_FLAGS_FTYPE 0x10000 /* inode directory types */ #define XFS_FSOP_GEOM_FLAGS_FINOBT 0x20000 /* free inode btree */ - +#define XFS_FSOP_GEOM_FLAGS_UTF8 0x40000 /* utf8 filenames */ /* * Minimum and maximum sizes need for growth checks. diff --git a/include/xfs_sb.h b/include/xfs_sb.h index 950d1ea..5ac7f06 100644 --- a/include/xfs_sb.h +++ b/include/xfs_sb.h @@ -82,6 +82,8 @@ struct xfs_trans; #define XFS_SB_VERSION2_RESERVED4BIT 0x00000004 #define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ #define XFS_SB_VERSION2_PARENTBIT 0x00000010 /* parent pointers */ +#define XFS_SB_VERSION2_PARENTBIT 0x00000010 /* parent pointers */ +#define XFS_SB_VERSION2_UTF8BIT 0x00000020 /* utf8 names */ #define XFS_SB_VERSION2_PROJID32BIT 0x00000080 /* 32 bit project id */ #define XFS_SB_VERSION2_CRCBIT 0x00000100 /* metadata CRCs */ #define XFS_SB_VERSION2_FTYPE 0x00000200 /* inode type in dir */ @@ -89,6 +91,7 @@ struct xfs_trans; #define XFS_SB_VERSION2_OKREALFBITS \ (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \ XFS_SB_VERSION2_ATTR2BIT | \ + XFS_SB_VERSION2_UTF8BIT | \ XFS_SB_VERSION2_PROJID32BIT | \ XFS_SB_VERSION2_FTYPE) #define XFS_SB_VERSION2_OKSASHFBITS \ @@ -600,8 +603,10 @@ xfs_sb_has_ro_compat_feature( } #define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ +#define XFS_SB_FEAT_INCOMPAT_UTF8 (1 << 1) /* utf-8 name support */ #define XFS_SB_FEAT_INCOMPAT_ALL \ - (XFS_SB_FEAT_INCOMPAT_FTYPE) + (XFS_SB_FEAT_INCOMPAT_FTYPE | \ + XFS_SB_FEAT_INCOMPAT_UTF8) #define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool @@ -649,6 +654,24 @@ static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp) (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_FINOBT); } +static inline int xfs_sb_version_hasutf8(xfs_sb_t *sbp) +{ + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 && + xfs_sb_has_incompat_feature(sbp, XFS_SB_FEAT_INCOMPAT_UTF8)) || + (xfs_sb_version_hasmorebits(sbp) && + (sbp->sb_features2 & XFS_SB_VERSION2_UTF8BIT)); +} + +/* + * Special case: there are a number of places where we need to test + * both the borgbit and the utf8bit, and take the same action if + * either of those is set. + */ +static inline int xfs_sb_version_hasci(xfs_sb_t *sbp) +{ + return xfs_sb_version_hasasciici(sbp) || xfs_sb_version_hasutf8(sbp); +} + /* * end of superblock version macros */ -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 15:57:51 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 960097F9C for ; Thu, 11 Sep 2014 15:57:51 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7A4C38F8037; Thu, 11 Sep 2014 13:57:51 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 49D264266DC; Thu, 11 Sep 2014 15:57:51 -0500 (CDT) Date: Thu, 11 Sep 2014 15:57:51 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 06/13] xfsprogs: add unicode character database files Message-ID: <20140911205751.GO13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Add files from the Unicode Character Database, version 7.0.0, to the source. A helper program that generates a trie used for normalization from these files is part of a separate commit. Signed-off-by: Olaf Weber --- [v2: removed large unicode files. download them as below. -bpm] cd support/ucd-7.0.0 wget http://www.unicode.org/Public/7.0.0/ucd/CaseFolding.txt wget http://www.unicode.org/Public/7.0.0/ucd/DerivedAge.txt wget http://www.unicode.org/Public/7.0.0/ucd/extracted/DerivedCombiningClass.txt wget http://www.unicode.org/Public/7.0.0/ucd/DerivedCoreProperties.txt wget http://www.unicode.org/Public/7.0.0/ucd/NormalizationCorrections.txt wget http://www.unicode.org/Public/7.0.0/ucd/NormalizationTest.txt wget http://www.unicode.org/Public/7.0.0/ucd/UnicodeData.txt --- support/ucd-7.0.0/README | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 support/ucd-7.0.0/README diff --git a/support/ucd-7.0.0/README b/support/ucd-7.0.0/README new file mode 100644 index 0000000..d713e66 --- /dev/null +++ b/support/ucd-7.0.0/README @@ -0,0 +1,33 @@ +The files in this directory are part of the Unicode Character Database +for version 7.0.0 of the Unicode standard. + +The full set of files can be found here: + + http://www.unicode.org/Public/7.0.0/ucd/ + +The latest released version of the UCD can be found here: + + http://www.unicode.org/Public/UCD/latest/ + +The files in this directory are identical, except that they have been +renamed with a suffix indicating the unicode version. + +Individual source links: + + http://www.unicode.org/Public/7.0.0/ucd/CaseFolding.txt + http://www.unicode.org/Public/7.0.0/ucd/DerivedAge.txt + http://www.unicode.org/Public/7.0.0/ucd/extracted/DerivedCombiningClass.txt + http://www.unicode.org/Public/7.0.0/ucd/DerivedCoreProperties.txt + http://www.unicode.org/Public/7.0.0/ucd/NormalizationCorrections.txt + http://www.unicode.org/Public/7.0.0/ucd/NormalizationTest.txt + http://www.unicode.org/Public/7.0.0/ucd/UnicodeData.txt + +md5sums + + 9a92b2bfe56c6719def926bab524fefd CaseFolding-7.0.0.txt + 07b8b1027eb824cf0835314e94f23d2e DerivedAge-7.0.0.txt + 90c3340b16821e2f2153acdbe6fc6180 DerivedCombiningClass-7.0.0.txt + c41c0601f808116f623de47110ed4f93 DerivedCoreProperties-7.0.0.txt + 522720ddfc150d8e63a2518634829bce NormalizationCorrections-7.0.0.txt + 1f35175eba4a2ad795db489f789ae352 NormalizationTest-7.0.0.txt + c8355655731d75e6a3de8c20d7e601ba UnicodeData-7.0.0.txt -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 15:59:02 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD, T_FILL_THIS_FORM_SHORT autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 181C77F9C for ; Thu, 11 Sep 2014 15:59:02 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay2.corp.sgi.com (Postfix) with ESMTP id B3CB6304032; Thu, 11 Sep 2014 13:59:01 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 1AD8A4266DC; Thu, 11 Sep 2014 15:59:01 -0500 (CDT) Date: Thu, 11 Sep 2014 15:59:01 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 07/13] libxfs: add trie generator and supporting code for UTF-8. Message-ID: <20140911205901.GP13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber mkutf8data.c is the source for a program that generates utf8data.h, which contains the trie that utf8norm.c uses. The trie is generated from the Unicode 7.0.0 data files. The format of the utf8data[] table is described in utf8norm.c. Supporting functions for UTF-8 normalization are in utf8norm.c with the header utf8norm.h. Two normalization forms are supported: nfkdi and nfkdicf. nfkdi: - Apply unicode normalization form NFKD. - Remove any Default_Ignorable_Code_Point. nfkdicf: - Apply unicode normalization form NFKD. - Remove any Default_Ignorable_Code_Point. - Apply a full casefold (C + F). For the purposes of the code, a string is valid UTF-8 if: - The values encoded are 0x1..0x10FFFF. - The surrogate codepoints 0xD800..0xDFFFF are not encoded. - The shortest possible encoding is used for all values. The supporting functions work on null-terminated strings (utf8 prefix) and on length-limited strings (utf8n prefix). Signed-off-by: Olaf Weber --- include/utf8norm.h | 111 ++ libxfs/utf8norm.c | 628 ++++++++++ support/mkutf8data.c | 3232 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 3971 insertions(+) create mode 100644 include/utf8norm.h create mode 100644 libxfs/utf8norm.c create mode 100644 support/mkutf8data.c diff --git a/include/utf8norm.h b/include/utf8norm.h new file mode 100644 index 0000000..6aa3391 --- /dev/null +++ b/include/utf8norm.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef UTF8NORM_H +#define UTF8NORM_H + +/* An opaque type used to determine the normalization in use. */ +typedef const struct utf8data *utf8data_t; + +/* Encoding a unicode version number as a single unsigned int. */ +#define UNICODE_MAJ_SHIFT (16) +#define UNICODE_MIN_SHIFT (8) + +#define UNICODE_AGE(MAJ,MIN,REV) \ + (((unsigned int)(MAJ) << UNICODE_MAJ_SHIFT) | \ + ((unsigned int)(MIN) << UNICODE_MIN_SHIFT) | \ + ((unsigned int)(REV))) + +/* Highest unicode version supported by the data tables. */ +extern const unsigned int utf8version; + +/* + * Look for the correct utf8data_t for a unicode version. + * Returns NULL if the version requested is too new. + * + * Two normalization forms are supported: nfkdi and nfkdicf. + * + * nfkdi: + * - Apply unicode normalization form NFKD. + * - Remove any Default_Ignorable_Code_Point. + * + * nfkdicf: + * - Apply unicode normalization form NFKD. + * - Remove any Default_Ignorable_Code_Point. + * - Apply a full casefold (C + F). + */ +extern utf8data_t utf8nfkdi(unsigned int); +extern utf8data_t utf8nfkdicf(unsigned int); + +/* + * Determine the maximum age of any unicode character in the string. + * Returns 0 if only unassigned code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern int utf8agemax(utf8data_t, const char *); +extern int utf8nagemax(utf8data_t, const char *, size_t); + +/* + * Determine the minimum age of any unicode character in the string. + * Returns 0 if any unassigned code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern int utf8agemin(utf8data_t, const char *); +extern int utf8nagemin(utf8data_t, const char *, size_t); + +/* + * Determine the length of the normalized from of the string, + * excluding any terminating NULL byte. + * Returns 0 if only ignorable code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern ssize_t utf8len(utf8data_t, const char *); +extern ssize_t utf8nlen(utf8data_t, const char *, size_t); + +/* + * Cursor structure used by the normalizer. + */ +struct utf8cursor { + utf8data_t data; + const char *s; + const char *p; + const char *ss; + const char *sp; + unsigned int len; + unsigned int slen; + short int ccc; + short int nccc; +}; + +/* + * Initialize a utf8cursor to normalize a string. + * Returns 0 on success. + * Returns -1 on failure. + */ +extern int utf8cursor(struct utf8cursor *, utf8data_t, const char *); +extern int utf8ncursor(struct utf8cursor *, utf8data_t, const char *, size_t); + +/* + * Get the next byte in the normalization. + * Returns a value > 0 && < 256 on success. + * Returns 0 when the end of the normalization is reached. + * Returns -1 if the string being normalized is not valid UTF-8. + */ +extern int utf8byte(struct utf8cursor *); + +#endif /* UTF8NORM_H */ diff --git a/libxfs/utf8norm.c b/libxfs/utf8norm.c new file mode 100644 index 0000000..6232d1a --- /dev/null +++ b/libxfs/utf8norm.c @@ -0,0 +1,628 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "xfs.h" +#include "xfs_types.h" +#include + +struct utf8data { + unsigned int maxage; + unsigned int offset; +}; + +#define __INCLUDED_FROM_UTF8NORM_C__ +#include +#undef __INCLUDED_FROM_UTF8NORM_C__ + +/* + * UTF-8 valid ranges. + * + * The UTF-8 encoding spreads the bits of a 32bit word over several + * bytes. This table gives the ranges that can be held and how they'd + * be represented. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000000 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000000 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * There is an additional requirement on UTF-8, in that only the + * shortest representation of a 32bit value is to be used. A decoder + * must not decode sequences that do not satisfy this requirement. + * Thus the allowed ranges have a lower bound. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000080 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000800 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00010000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00200000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x04000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Actual unicode characters are limited to the range 0x0 - 0x10FFFF, + * 17 planes of 65536 values. This limits the sequences actually seen + * even more, to just the following. + * + * 0 - 0x7F: 0 - 0x7F + * 0x80 - 0x7FF: 0xC2 0x80 - 0xDF 0xBF + * 0x800 - 0xFFFF: 0xE0 0xA0 0x80 - 0xEF 0xBF 0xBF + * 0x10000 - 0x10FFFF: 0xF0 0x90 0x80 0x80 - 0xF4 0x8F 0xBF 0xBF + * + * Within those ranges the surrogates 0xD800 - 0xDFFF are not allowed. + * + * Note that the longest sequence seen with valid usage is 4 bytes, + * the same a single UTF-32 character. This makes the UTF-8 + * representation of Unicode strictly smaller than UTF-32. + * + * The shortest sequence requirement was introduced by: + * Corrigendum #1: UTF-8 Shortest Form + * It can be found here: + * http://www.unicode.org/versions/corrigendum1.html + * + */ + +/* + * Return the number of bytes used by the current UTF-8 sequence. + * Assumes the input points to the first byte of a valid UTF-8 + * sequence. + */ +static inline int +utf8clen(const char *s) +{ + unsigned char c = *s; + return 1 + (c >= 0xC0) + (c >= 0xE0) + (c >= 0xF0); +} + +/* + * utf8trie_t + * + * A compact binary tree, used to decode UTF-8 characters. + * + * Internal nodes are one byte for the node itself, and up to three + * bytes for an offset into the tree. The first byte contains the + * following information: + * NEXTBYTE - flag - advance to next byte if set + * BITNUM - 3 bit field - the bit number to tested + * OFFLEN - 2 bit field - number of bytes in the offset + * if offlen == 0 (non-branching node) + * RIGHTPATH - 1 bit field - set if the following node is for the + * right-hand path (tested bit is set) + * TRIENODE - 1 bit field - set if the following node is an internal + * node, otherwise it is a leaf node + * if offlen != 0 (branching node) + * LEFTNODE - 1 bit field - set if the left-hand node is internal + * RIGHTNODE - 1 bit field - set if the right-hand node is internal + * + * Due to the way utf8 works, there cannot be branching nodes with + * NEXTBYTE set, and moreover those nodes always have a righthand + * descendant. + */ +typedef const unsigned char utf8trie_t; +#define BITNUM 0x07 +#define NEXTBYTE 0x08 +#define OFFLEN 0x30 +#define OFFLEN_SHIFT 4 +#define RIGHTPATH 0x40 +#define TRIENODE 0x80 +#define RIGHTNODE 0x40 +#define LEFTNODE 0x80 + +/* + * utf8leaf_t + * + * The leaves of the trie are embedded in the trie, and so the same + * underlying datatype: unsigned char. + * + * leaf[0]: The unicode version, stored as a generation number that is + * an index into utf8agetab[]. With this we can filter code + * points based on the unicode version in which they were + * defined. The CCC of a non-defined code point is 0. + * leaf[1]: Canonical Combining Class. During normalization, we need + * to do a stable sort into ascending order of all characters + * with a non-zero CCC that occur between two characters with + * a CCC of 0, or at the begin or end of a string. + * The unicode standard guarantees that all CCC values are + * between 0 and 254 inclusive, which leaves 255 available as + * a special value. + * Code points with CCC 0 are known as stoppers. + * leaf[2]: Decomposition. If leaf[1] == 255, then leaf[2] is the + * start of a NUL-terminated string that is the decomposition + * of the character. + * The CCC of a decomposable character is the same as the CCC + * of the first character of its decomposition. + * Some characters decompose as the empty string: these are + * characters with the Default_Ignorable_Code_Point property. + * These do affect normalization, as they all have CCC 0. + * + * The decompositions in the trie have been fully expanded. + * + * Casefolding, if applicable, is also done using decompositions. + * + * The trie is constructed in such a way that leaves exist for all + * UTF-8 sequences that match the criteria from the "UTF-8 valid + * ranges" comment above, and only for those sequences. Therefore a + * lookup in the trie can be used to validate the UTF-8 input. + */ +typedef const unsigned char utf8leaf_t; + +#define LEAF_GEN(LEAF) ((LEAF)[0]) +#define LEAF_CCC(LEAF) ((LEAF)[1]) +#define LEAF_STR(LEAF) ((const char*)((LEAF) + 2)) + +#define MINCCC (0) +#define MAXCCC (254) +#define STOPPER (0) +#define DECOMPOSE (255) + +/* + * Use trie to scan s, touching at most len bytes. + * Returns the leaf if one exists, NULL otherwise. + * + * A non-NULL return guarantees that the UTF-8 sequence starting at s + * is well-formed and corresponds to a known unicode code point. The + * shorthand for this will be "is valid UTF-8 unicode". + */ +static utf8leaf_t * +utf8nlookup(utf8data_t data, const char *s, size_t len) +{ + utf8trie_t *trie = utf8data + data->offset; + int offlen; + int offset; + int mask; + int node; + + if (!data) + return NULL; + if (len == 0) + return NULL; + node = 1; + while (node) { + offlen = (*trie & OFFLEN) >> OFFLEN_SHIFT; + if (*trie & NEXTBYTE) { + if (--len == 0) + return NULL; + s++; + } + mask = 1 << (*trie & BITNUM); + if (*s & mask) { + /* Right leg */ + if (offlen) { + /* Right node at offset of trie */ + node = (*trie & RIGHTNODE); + offset = trie[offlen]; + while (--offlen) { + offset <<= 8; + offset |= trie[offlen]; + } + trie += offset; + } else if (*trie & RIGHTPATH) { + /* Right node after this node */ + node = (*trie & TRIENODE); + trie++; + } else { + /* No right node. */ + node = 0; + trie = NULL; + } + } else { + /* Left leg */ + if (offlen) { + /* Left node after this node. */ + node = (*trie & LEFTNODE); + trie += offlen + 1; + } else if (*trie & RIGHTPATH) { + /* No left node. */ + node = 0; + trie = NULL; + } else { + /* Left node after this node */ + node = (*trie & TRIENODE); + trie++; + } + } + } + return trie; +} + +/* + * Use trie to scan s. + * Returns the leaf if one exists, NULL otherwise. + * + * Forwards to utf8nlookup(). + */ +static utf8leaf_t * +utf8lookup(utf8data_t data, const char *s) +{ + return utf8nlookup(data, s, (size_t)-1); +} + +/* + * Maximum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if only non-assigned code points are used. + */ +int +utf8agemax(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!data) + return -1; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age > age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Minimum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if non-assigned code points are used. + */ +int +utf8agemin(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + int age = data->maxage; + int leaf_age; + + if (!data) + return -1; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age < age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemax(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!data) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age > age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemin(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int leaf_age; + int age = data->maxage; + + if (!data) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age < age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Length of the normalization of s. + * Return -1 if s is not valid UTF-8 unicode. + * + * A string of Default_Ignorable_Code_Point has length 0. + */ +ssize_t +utf8len(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!data) + return -1; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + if (utf8agetab[LEAF_GEN(leaf)] > data->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Length of the normalization of s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +ssize_t +utf8nlen(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!data) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + if (utf8agetab[LEAF_GEN(leaf)] > data->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + len -= utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * u8c : pointer to cursor. + * data : utf8data_t to use for normalization. + * s : string. + * len : length of s. + * + * Returns -1 on error, 0 on success. + */ +int +utf8ncursor( + struct utf8cursor *u8c, + utf8data_t data, + const char *s, + size_t len) +{ + if (!data) + return -1; + if (!s) + return -1; + u8c->data = data; + u8c->s = s; + u8c->p = NULL; + u8c->ss = NULL; + u8c->sp = NULL; + u8c->len = len; + u8c->slen = 0; + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + /* Check we didn't clobber the maximum length. */ + if (u8c->len != len) + return -1; + /* The first byte of s may not be an utf8 continuation. */ + if (len > 0 && (*s & 0xC0) == 0x80) + return -1; + return 0; +} + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * u8c : pointer to cursor. + * data : utf8data_t to use for normalization. + * s : NUL-terminated string. + * + * Returns -1 on error, 0 on success. + */ +int +utf8cursor( + struct utf8cursor *u8c, + utf8data_t data, + const char *s) +{ + return utf8ncursor(u8c, data, s, (unsigned int)-1); +} + +/* + * Get one byte from the normalized form of the string described by u8c. + * + * Returns the byte cast to an unsigned char on succes, and -1 on failure. + * + * The cursor keeps track of the location in the string in u8c->s. + * When a character is decomposed, the current location is stored in + * u8c->p, and u8c->s is set to the start of the decomposition. Note + * that bytes from a decomposition do not count against u8c->len. + * + * Characters are emitted if they match the current CCC in u8c->ccc. + * Hitting end-of-string while u8c->ccc == STOPPER means we're done, + * and the function returns 0 in that case. + * + * Sorting by CCC is done by repeatedly scanning the string. The + * values of u8c->s and u8c->p are stored in u8c->ss and u8c->sp at + * the start of the scan. The first pass finds the lowest CCC to be + * emitted and stores it in u8c->nccc, the second pass emits the + * characters with this CCC and finds the next lowest CCC. This limits + * the number of passes to 1 + the number of different CCCs in the + * sequence being scanned. + * + * Therefore: + * u8c->p != NULL -> a decomposition is being scanned. + * u8c->ss != NULL -> this is a repeating scan. + * u8c->ccc == -1 -> this is the first scan of a repeating scan. + */ +int +utf8byte(struct utf8cursor *u8c) +{ + utf8leaf_t *leaf; + int ccc; + + for (;;) { + /* Check for the end of a decomposed character. */ + if (u8c->p && *u8c->s == '\0') { + u8c->s = u8c->p; + u8c->p = NULL; + } + + /* Check for end-of-string. */ + if (!u8c->p && (u8c->len == 0 || *u8c->s == '\0')) { + /* There is no next byte. */ + if (u8c->ccc == STOPPER) + return 0; + /* End-of-string during a scan counts as a stopper. */ + ccc = STOPPER; + goto ccc_mismatch; + } else if ((*u8c->s & 0xC0) == 0x80) { + /* This is a continuation of the current character. */ + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Look up the data for the current character. */ + if (u8c->p) + leaf = utf8lookup(u8c->data, u8c->s); + else + leaf = utf8nlookup(u8c->data, u8c->s, u8c->len); + + /* No leaf found implies that the input is a binary blob. */ + if (!leaf) + return -1; + + /* Characters that are too new have CCC 0. */ + if (utf8agetab[LEAF_GEN(leaf)] > u8c->data->maxage) { + ccc = STOPPER; + } else if ((ccc = LEAF_CCC(leaf)) == DECOMPOSE) { + u8c->len -= utf8clen(u8c->s); + u8c->p = u8c->s + utf8clen(u8c->s); + u8c->s = LEAF_STR(leaf); + /* Empty decomposition implies CCC 0. */ + if (*u8c->s == '\0') { + if (u8c->ccc == STOPPER) + continue; + ccc = STOPPER; + goto ccc_mismatch; + } + leaf = utf8lookup(u8c->data, u8c->s); + ccc = LEAF_CCC(leaf); + } + + /* + * If this is not a stopper, then see if it updates + * the next canonical class to be emitted. + */ + if (ccc != STOPPER && u8c->ccc < ccc && ccc < u8c->nccc) + u8c->nccc = ccc; + + /* + * Return the current byte if this is the current + * combining class. + */ + if (ccc == u8c->ccc) { + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Current combining class mismatch. */ + ccc_mismatch: + if (u8c->nccc == STOPPER) { + /* + * Scan forward for the first canonical class + * to be emitted. Save the position from + * which to restart. + */ + u8c->ccc = MINCCC - 1; + u8c->nccc = ccc; + u8c->sp = u8c->p; + u8c->ss = u8c->s; + u8c->slen = u8c->len; + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (ccc != STOPPER) { + /* Not a stopper, and not the ccc we're emitting. */ + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (u8c->nccc != MAXCCC + 1) { + /* At a stopper, restart for next ccc. */ + u8c->ccc = u8c->nccc; + u8c->nccc = MAXCCC + 1; + u8c->s = u8c->ss; + u8c->p = u8c->sp; + u8c->len = u8c->slen; + } else { + /* All done, proceed from here. */ + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->sp = NULL; + u8c->ss = NULL; + u8c->slen = 0; + } + } +} + +const struct utf8data * +utf8nfkdi(unsigned int maxage) +{ + int i = sizeof(utf8nfkdidata)/sizeof(utf8nfkdidata[0]) - 1; + + while (maxage < utf8nfkdidata[i].maxage) + i--; + if (maxage > utf8nfkdidata[i].maxage) + return NULL; + return &utf8nfkdidata[i]; +} + +const struct utf8data * +utf8nfkdicf(unsigned int maxage) +{ + int i = sizeof(utf8nfkdicfdata)/sizeof(utf8nfkdicfdata[0]) - 1; + + while (maxage < utf8nfkdicfdata[i].maxage) + i--; + if (maxage > utf8nfkdicfdata[i].maxage) + return NULL; + return &utf8nfkdicfdata[i]; +} diff --git a/support/mkutf8data.c b/support/mkutf8data.c new file mode 100644 index 0000000..e5c3507 --- /dev/null +++ b/support/mkutf8data.c @@ -0,0 +1,3232 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Generator for a compact trie for unicode normalization */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Default names of the in- and output files. */ + +#define AGE_NAME "DerivedAge.txt" +#define CCC_NAME "DerivedCombiningClass.txt" +#define PROP_NAME "DerivedCoreProperties.txt" +#define DATA_NAME "UnicodeData.txt" +#define FOLD_NAME "CaseFolding.txt" +#define NORM_NAME "NormalizationCorrections.txt" +#define TEST_NAME "NormalizationTest.txt" +#define UTF8_NAME "utf8data.h" + +const char *age_name = AGE_NAME; +const char *ccc_name = CCC_NAME; +const char *prop_name = PROP_NAME; +const char *data_name = DATA_NAME; +const char *fold_name = FOLD_NAME; +const char *norm_name = NORM_NAME; +const char *test_name = TEST_NAME; +const char *utf8_name = UTF8_NAME; + +int verbose = 0; + +/* An arbitrary line size limit on input lines. */ + +#define LINESIZE 1024 +char line[LINESIZE]; +char buf0[LINESIZE]; +char buf1[LINESIZE]; +char buf2[LINESIZE]; +char buf3[LINESIZE]; + +const char *argv0; + +/* ------------------------------------------------------------------ */ + +/* + * Unicode version numbers consist of three parts: major, minor, and a + * revision. These numbers are packed into an unsigned int to obtain + * a single version number. + * + * To save space in the generated trie, the unicode version is not + * stored directly, instead we calculate a generation number from the + * unicode versions seen in the DerivedAge file, and use that as an + * index into a table of unicode versions. + */ +#define UNICODE_MAJ_SHIFT (16) +#define UNICODE_MIN_SHIFT (8) + +#define UNICODE_MAJ_MAX ((unsigned short)-1) +#define UNICODE_MIN_MAX ((unsigned char)-1) +#define UNICODE_REV_MAX ((unsigned char)-1) + +#define UNICODE_AGE(MAJ,MIN,REV) \ + (((unsigned int)(MAJ) << UNICODE_MAJ_SHIFT) | \ + ((unsigned int)(MIN) << UNICODE_MIN_SHIFT) | \ + ((unsigned int)(REV))) + +unsigned int *ages; +int ages_count; + +unsigned int unicode_maxage; + +static int +age_valid(unsigned int major, unsigned int minor, unsigned int revision) +{ + if (major > UNICODE_MAJ_MAX) + return 0; + if (minor > UNICODE_MIN_MAX) + return 0; + if (revision > UNICODE_REV_MAX) + return 0; + return 1; +} + +/* ------------------------------------------------------------------ */ + +/* + * utf8trie_t + * + * A compact binary tree, used to decode UTF-8 characters. + * + * Internal nodes are one byte for the node itself, and up to three + * bytes for an offset into the tree. The first byte contains the + * following information: + * NEXTBYTE - flag - advance to next byte if set + * BITNUM - 3 bit field - the bit number to tested + * OFFLEN - 2 bit field - number of bytes in the offset + * if offlen == 0 (non-branching node) + * RIGHTPATH - 1 bit field - set if the following node is for the + * right-hand path (tested bit is set) + * TRIENODE - 1 bit field - set if the following node is an internal + * node, otherwise it is a leaf node + * if offlen != 0 (branching node) + * LEFTNODE - 1 bit field - set if the left-hand node is internal + * RIGHTNODE - 1 bit field - set if the right-hand node is internal + * + * Due to the way utf8 works, there cannot be branching nodes with + * NEXTBYTE set, and moreover those nodes always have a righthand + * descendant. + */ +typedef unsigned char utf8trie_t; +#define BITNUM 0x07 +#define NEXTBYTE 0x08 +#define OFFLEN 0x30 +#define OFFLEN_SHIFT 4 +#define RIGHTPATH 0x40 +#define TRIENODE 0x80 +#define RIGHTNODE 0x40 +#define LEFTNODE 0x80 + +/* + * utf8leaf_t + * + * The leaves of the trie are embedded in the trie, and so the same + * underlying datatype, unsigned char. + * + * leaf[0]: The unicode version, stored as a generation number that is + * an index into utf8agetab[]. With this we can filter code + * points based on the unicode version in which they were + * defined. The CCC of a non-defined code point is 0. + * leaf[1]: Canonical Combining Class. During normalization, we need + * to do a stable sort into ascending order of all characters + * with a non-zero CCC that occur between two characters with + * a CCC of 0, or at the begin or end of a string. + * The unicode standard guarantees that all CCC values are + * between 0 and 254 inclusive, which leaves 255 available as + * a special value. + * Code points with CCC 0 are known as stoppers. + * leaf[2]: Decomposition. If leaf[1] == 255, then leaf[2] is the + * start of a NUL-terminated string that is the decomposition + * of the character. + * The CCC of a decomposable character is the same as the CCC + * of the first character of its decomposition. + * Some characters decompose as the empty string: these are + * characters with the Default_Ignorable_Code_Point property. + * These do affect normalization, as they all have CCC 0. + * + * The decompositions in the trie have been fully expanded. + * + * Casefolding, if applicable, is also done using decompositions. + */ +typedef unsigned char utf8leaf_t; + +#define LEAF_GEN(LEAF) ((LEAF)[0]) +#define LEAF_CCC(LEAF) ((LEAF)[1]) +#define LEAF_STR(LEAF) ((const char*)((LEAF) + 2)) + +#define MAXGEN (255) + +#define MINCCC (0) +#define MAXCCC (254) +#define STOPPER (0) +#define DECOMPOSE (255) + +struct tree; +static utf8leaf_t *utf8nlookup(struct tree *, const char *, size_t); +static utf8leaf_t *utf8lookup(struct tree *, const char *); + +unsigned char *utf8data; +size_t utf8data_size; + +utf8trie_t *nfkdi; +utf8trie_t *nfkdicf; + +/* ------------------------------------------------------------------ */ + +/* + * UTF8 valid ranges. + * + * The UTF-8 encoding spreads the bits of a 32bit word over several + * bytes. This table gives the ranges that can be held and how they'd + * be represented. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000000 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000000 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * There is an additional requirement on UTF-8, in that only the + * shortest representation of a 32bit value is to be used. A decoder + * must not decode sequences that do not satisfy this requirement. + * Thus the allowed ranges have a lower bound. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000080 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000800 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00010000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00200000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x04000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Actual unicode characters are limited to the range 0x0 - 0x10FFFF, + * 17 planes of 65536 values. This limits the sequences actually seen + * even more, to just the following. + * + * 0 - 0x7f: 0 0x7f + * 0x80 - 0x7ff: 0xc2 0x80 0xdf 0xbf + * 0x800 - 0xffff: 0xe0 0xa0 0x80 0xef 0xbf 0xbf + * 0x10000 - 0x10ffff: 0xf0 0x90 0x80 0x80 0xf4 0x8f 0xbf 0xbf + * + * Even within those ranges not all values are allowed: the surrogates + * 0xd800 - 0xdfff should never be seen. + * + * Note that the longest sequence seen with valid usage is 4 bytes, + * the same a single UTF-32 character. This makes the UTF-8 + * representation of Unicode strictly smaller than UTF-32. + * + * The shortest sequence requirement was introduced by: + * Corrigendum #1: UTF-8 Shortest Form + * It can be found here: + * http://www.unicode.org/versions/corrigendum1.html + * + */ + +#define UTF8_2_BITS 0xC0 +#define UTF8_3_BITS 0xE0 +#define UTF8_4_BITS 0xF0 +#define UTF8_N_BITS 0x80 +#define UTF8_2_MASK 0xE0 +#define UTF8_3_MASK 0xF0 +#define UTF8_4_MASK 0xF8 +#define UTF8_N_MASK 0xC0 +#define UTF8_V_MASK 0x3F +#define UTF8_V_SHIFT 6 + +static int +utf8key(unsigned int key, char keyval[]) +{ + int keylen; + + if (key < 0x80) { + keyval[0] = key; + keylen = 1; + } else if (key < 0x800) { + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_2_BITS; + keylen = 2; + } else if (key < 0x10000) { + keyval[2] = key & UTF8_V_MASK; + keyval[2] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_3_BITS; + keylen = 3; + } else if (key < 0x110000) { + keyval[3] = key & UTF8_V_MASK; + keyval[3] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[2] = key & UTF8_V_MASK; + keyval[2] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_4_BITS; + keylen = 4; + } else { + printf("%#x: illegal key\n", key); + keylen = 0; + } + return keylen; +} + +static unsigned int +utf8code(const char *str) +{ + const unsigned char *s = (const unsigned char*)str; + unsigned int unichar = 0; + + if (*s < 0x80) { + unichar = *s; + } else if (*s < UTF8_3_BITS) { + unichar = *s++ & 0x1F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } else if (*s < UTF8_4_BITS) { + unichar = *s++ & 0x0F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } else { + unichar = *s++ & 0x0F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } + return unichar; +} + +static int +utf32valid(unsigned int unichar) +{ + return unichar < 0x110000; +} + +#define NODE 1 +#define LEAF 0 + +struct tree { + void *root; + int childnode; + const char *type; + unsigned int maxage; + struct tree *next; + int (*leaf_equal)(void *, void *); + void (*leaf_print)(void *, int); + int (*leaf_mark)(void *); + int (*leaf_size)(void *); + int *(*leaf_index)(struct tree *, void *); + unsigned char *(*leaf_emit)(void *, unsigned char *); + int leafindex[0x110000]; + int index; +}; + +struct node { + int index; + int offset; + int mark; + int size; + struct node *parent; + void *left; + void *right; + unsigned char bitnum; + unsigned char nextbyte; + unsigned char leftnode; + unsigned char rightnode; + unsigned int keybits; + unsigned int keymask; +}; + +/* + * Example lookup function for a tree. + */ +static void * +lookup(struct tree *tree, const char *key) +{ + struct node *node; + void *leaf = NULL; + + node = tree->root; + while (!leaf && node) { + if (node->nextbyte) + key++; + if (*key & (1 << (node->bitnum & 7))) { + /* Right leg */ + if (node->rightnode == NODE) { + node = node->right; + } else if (node->rightnode == LEAF) { + leaf = node->right; + } else { + node = NULL; + } + } else { + /* Left leg */ + if (node->leftnode == NODE) { + node = node->left; + } else if (node->leftnode == LEAF) { + leaf = node->left; + } else { + node = NULL; + } + } + } + + return leaf; +} + +/* + * A simple non-recursive tree walker: keep track of visits to the + * left and right branches in the leftmask and rightmask. + */ +static void +tree_walk(struct tree *tree) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int indent = 1; + int nodes, singletons, leaves; + + nodes = singletons = leaves = 0; + + printf("%s_%x root %p\n", tree->type, tree->maxage, tree->root); + if (tree->childnode == LEAF) { + assert(tree->root); + tree->leaf_print(tree->root, indent); + leaves = 1; + } else { + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + printf("%*snode @ %p bitnum %d nextbyte %d" + " left %p right %p mask %x bits %x\n", + indent, "", node, + node->bitnum, node->nextbyte, + node->left, node->right, + node->keymask, node->keybits); + nodes += 1; + if (!(node->left && node->right)) + singletons += 1; + + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + tree->leaf_print(node->left, + indent+1); + leaves += 1; + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + tree->leaf_print(node->right, + indent+1); + leaves += 1; + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } + } + printf("nodes %d leaves %d singletons %d\n", + nodes, leaves, singletons); +} + +/* + * Allocate an initialize a new internal node. + */ +static struct node * +alloc_node(struct node *parent) +{ + struct node *node; + int bitnum; + + node = malloc(sizeof(*node)); + node->left = node->right = NULL; + node->parent = parent; + node->leftnode = NODE; + node->rightnode = NODE; + node->keybits = 0; + node->keymask = 0; + node->mark = 0; + node->index = 0; + node->offset = -1; + node->size = 4; + + if (node->parent) { + bitnum = parent->bitnum; + if ((bitnum & 7) == 0) { + node->bitnum = bitnum + 7 + 8; + node->nextbyte = 1; + } else { + node->bitnum = bitnum - 1; + node->nextbyte = 0; + } + } else { + node->bitnum = 7; + node->nextbyte = 0; + } + + return node; +} + +/* + * Insert a new leaf into the tree, and collapse any subtrees that are + * fully populated and end in identical leaves. A nextbyte tagged + * internal node will not be removed to preserve the tree's integrity. + * Note that due to the structure of utf8, no nextbyte tagged node + * will be a candidate for removal. + */ +static int +insert(struct tree *tree, char *key, int keylen, void *leaf) +{ + struct node *node; + struct node *parent; + void **cursor; + int keybits; + + assert(keylen >= 1 && keylen <= 4); + + node = NULL; + cursor = &tree->root; + keybits = 8 * keylen; + + /* Insert, creating path along the way. */ + while (keybits) { + if (!*cursor) + *cursor = alloc_node(node); + node = *cursor; + if (node->nextbyte) + key++; + if (*key & (1 << (node->bitnum & 7))) + cursor = &node->right; + else + cursor = &node->left; + keybits--; + } + *cursor = leaf; + + /* Merge subtrees if possible. */ + while (node) { + if (*key & (1 << (node->bitnum & 7))) + node->rightnode = LEAF; + else + node->leftnode = LEAF; + if (node->nextbyte) + break; + if (node->leftnode == NODE || node->rightnode == NODE) + break; + assert(node->left); + assert(node->right); + /* Compare */ + if (! tree->leaf_equal(node->left, node->right)) + break; + /* Keep left, drop right leaf. */ + leaf = node->left; + /* Check in parent */ + parent = node->parent; + if (!parent) { + /* root of tree! */ + tree->root = leaf; + tree->childnode = LEAF; + } else if (parent->left == node) { + parent->left = leaf; + parent->leftnode = LEAF; + if (parent->right) { + parent->keymask = 0; + parent->keybits = 0; + } else { + parent->keymask |= (1 << node->bitnum); + } + } else if (parent->right == node) { + parent->right = leaf; + parent->rightnode = LEAF; + if (parent->left) { + parent->keymask = 0; + parent->keybits = 0; + } else { + parent->keymask |= (1 << node->bitnum); + parent->keybits |= (1 << node->bitnum); + } + } else { + /* internal tree error */ + assert(0); + } + free(node); + node = parent; + } + + /* Propagate keymasks up along singleton chains. */ + while (node) { + parent = node->parent; + if (!parent) + break; + /* Nix the mask for parents with two children. */ + if (node->keymask == 0) { + parent->keymask = 0; + parent->keybits = 0; + } else if (parent->left && parent->right) { + parent->keymask = 0; + parent->keybits = 0; + } else { + assert((parent->keymask & node->keymask) == 0); + parent->keymask |= node->keymask; + parent->keymask |= (1 << parent->bitnum); + parent->keybits |= node->keybits; + if (parent->right) + parent->keybits |= (1 << parent->bitnum); + } + node = parent; + } + + return 0; +} + +/* + * Prune internal nodes. + * + * Fully populated subtrees that end at the same leaf have already + * been collapsed. There are still internal nodes that have for both + * their left and right branches a sequence of singletons that make + * identical choices and end in identical leaves. The keymask and + * keybits collected in the nodes describe the choices made in these + * singleton chains. When they are identical for the left and right + * branch of a node, and the two leaves comare identical, the node in + * question can be removed. + * + * Note that nodes with the nextbyte tag set will not be removed by + * this to ensure tree integrity. Note as well that the structure of + * utf8 ensures that these nodes would not have been candidates for + * removal in any case. + */ +static void +prune(struct tree *tree) +{ + struct node *node; + struct node *left; + struct node *right; + struct node *parent; + void *leftleaf; + void *rightleaf; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int count; + + if (verbose > 0) + printf("Pruning %s_%x\n", tree->type, tree->maxage); + + count = 0; + if (tree->childnode == LEAF) + return; + if (!tree->root) + return; + + leftmask = rightmask = 0; + node = tree->root; + while (node) { + if (node->nextbyte) + goto advance; + if (node->leftnode == LEAF) + goto advance; + if (node->rightnode == LEAF) + goto advance; + if (!node->left) + goto advance; + if (!node->right) + goto advance; + left = node->left; + right = node->right; + if (left->keymask == 0) + goto advance; + if (right->keymask == 0) + goto advance; + if (left->keymask != right->keymask) + goto advance; + if (left->keybits != right->keybits) + goto advance; + leftleaf = NULL; + while (!leftleaf) { + assert(left->left || left->right); + if (left->leftnode == LEAF) + leftleaf = left->left; + else if (left->rightnode == LEAF) + leftleaf = left->right; + else if (left->left) + left = left->left; + else if (left->right) + left = left->right; + else + assert(0); + } + rightleaf = NULL; + while (!rightleaf) { + assert(right->left || right->right); + if (right->leftnode == LEAF) + rightleaf = right->left; + else if (right->rightnode == LEAF) + rightleaf = right->right; + else if (right->left) + right = right->left; + else if (right->right) + right = right->right; + else + assert(0); + } + if (! tree->leaf_equal(leftleaf, rightleaf)) + goto advance; + /* + * This node has identical singleton-only subtrees. + * Remove it. + */ + parent = node->parent; + left = node->left; + right = node->right; + if (parent->left == node) + parent->left = left; + else if (parent->right == node) + parent->right = left; + else + assert(0); + left->parent = parent; + left->keymask |= (1 << node->bitnum); + node->left = NULL; + while (node) { + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + if (node->leftnode == NODE && node->left) { + left = node->left; + free(node); + count++; + node = left; + } else if (node->rightnode == NODE && node->right) { + right = node->right; + free(node); + count++; + node = right; + } else { + node = NULL; + } + } + /* Propagate keymasks up along singleton chains. */ + node = parent; + /* Force re-check */ + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + for (;;) { + if (node->left && node->right) + break; + if (node->left) { + left = node->left; + node->keymask |= left->keymask; + node->keybits |= left->keybits; + } + if (node->right) { + right = node->right; + node->keymask |= right->keymask; + node->keybits |= right->keybits; + } + node->keymask |= (1 << node->bitnum); + node = node->parent; + /* Force re-check */ + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + } + advance: + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0 && + node->leftnode == NODE && + node->left) { + leftmask |= bitmask; + node = node->left; + } else if ((rightmask & bitmask) == 0 && + node->rightnode == NODE && + node->right) { + rightmask |= bitmask; + node = node->right; + } else { + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } + } + if (verbose > 0) + printf("Pruned %d nodes\n", count); +} + +/* + * Mark the nodes in the tree that lead to leaves that must be + * emitted. + */ +static void +mark_nodes(struct tree *tree) +{ + struct node *node; + struct node *n; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int marked; + + marked = 0; + if (verbose > 0) + printf("Marking %s_%x\n", tree->type, tree->maxage); + if (tree->childnode == LEAF) + goto done; + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + if (tree->leaf_mark(node->left)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->left) { + assert(node->leftnode == NODE); + node = node->left; + continue; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + if (tree->leaf_mark(node->right)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->right) { + assert(node->rightnode==NODE); + node = node->right; + continue; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } + + /* second pass: left siblings and singletons */ + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + if (tree->leaf_mark(node->left)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->left) { + assert(node->leftnode == NODE); + node = node->left; + if (!node->mark && node->parent->mark) { + marked++; + node->mark = 1; + } + continue; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + if (tree->leaf_mark(node->right)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->right) { + assert(node->rightnode==NODE); + node = node->right; + if (!node->mark && node->parent->mark && + !node->parent->left) { + marked++; + node->mark = 1; + } + continue; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } +done: + if (verbose > 0) + printf("Marked %d nodes\n", marked); +} + +/* + * Compute the index of each node and leaf, which is the offset in the + * emitted trie. These value must be pre-computed because relative + * offsets between nodes are used to navigate the tree. + */ +static int +index_nodes(struct tree *tree, int index) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int count; + int indent; + + /* Align to a cache line (or half a cache line?). */ + while (index % 64) + index++; + tree->index = index; + indent = 1; + count = 0; + + if (verbose > 0) + printf("Indexing %s_%x: %d", tree->type, tree->maxage, index); + if (tree->childnode == LEAF) { + index += tree->leaf_size(tree->root); + goto done; + } + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + count++; + if (node->index != index) + node->index = index; + index += node->size; +skip: + while (node) { + bitmask = 1 << node->bitnum; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + *tree->leaf_index(tree, node->left) = + index; + index += tree->leaf_size(node->left); + count++; + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + *tree->leaf_index(tree, node->right) = index; + index += tree->leaf_size(node->right); + count++; + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +done: + /* Round up to a multiple of 16 */ + while (index % 16) + index++; + if (verbose > 0) + printf("Final index %d\n", index); + return index; +} + +/* + * Compute the size of nodes and leaves. We start by assuming that + * each node needs to store a three-byte offset. The indexes of the + * nodes are calculated based on that, and then this function is + * called to see if the sizes of some nodes can be reduced. This is + * repeated until no more changes are seen. + */ +static int +size_nodes(struct tree *tree) +{ + struct tree *next; + struct node *node; + struct node *right; + struct node *n; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + unsigned int pathbits; + unsigned int pathmask; + int changed; + int offset; + int size; + int indent; + + indent = 1; + changed = 0; + size = 0; + + if (verbose > 0) + printf("Sizing %s_%x", tree->type, tree->maxage); + if (tree->childnode == LEAF) + goto done; + + assert(tree->childnode == NODE); + pathbits = 0; + pathmask = 0; + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + offset = 0; + if (!node->left || !node->right) { + size = 1; + } else { + if (node->rightnode == NODE) { + right = node->right; + next = tree->next; + while (!right->mark) { + assert(next); + n = next->root; + while (n->bitnum != node->bitnum) { + if (pathbits & (1<bitnum)) + n = n->right; + else + n = n->left; + } + n = n->right; + assert(right->bitnum == n->bitnum); + right = n; + next = next->next; + } + offset = right->index - node->index; + } else { + offset = *tree->leaf_index(tree, node->right); + offset -= node->index; + } + assert(offset >= 0); + assert(offset <= 0xffffff); + if (offset <= 0xff) { + size = 2; + } else if (offset <= 0xffff) { + size = 3; + } else { /* offset <= 0xffffff */ + size = 4; + } + } + if (node->size != size || node->offset != offset) { + node->size = size; + node->offset = offset; + changed++; + } +skip: + while (node) { + bitmask = 1 << node->bitnum; + pathmask |= bitmask; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + pathbits |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + pathmask &= ~bitmask; + pathbits &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +done: + if (verbose > 0) + printf("Found %d changes\n", changed); + return changed; +} + +/* + * Emit a trie for the given tree into the data array. + */ +static void +emit(struct tree *tree, unsigned char *data) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int offlen; + int offset; + int index; + int indent; + unsigned char byte; + + index = tree->index; + data += index; + indent = 1; + if (verbose > 0) + printf("Emitting %s_%x\n", tree->type, tree->maxage); + if (tree->childnode == LEAF) { + assert(tree->root); + tree->leaf_emit(tree->root, data); + return; + } + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + assert(node->offset != -1); + assert(node->index == index); + + byte = 0; + if (node->nextbyte) + byte |= NEXTBYTE; + byte |= (node->bitnum & BITNUM); + if (node->left && node->right) { + if (node->leftnode == NODE) + byte |= LEFTNODE; + if (node->rightnode == NODE) + byte |= RIGHTNODE; + if (node->offset <= 0xff) + offlen = 1; + else if (node->offset <= 0xffff) + offlen = 2; + else + offlen = 3; + offset = node->offset; + byte |= offlen << OFFLEN_SHIFT; + *data++ = byte; + index++; + while (offlen--) { + *data++ = offset & 0xff; + index++; + offset >>= 8; + } + } else if (node->left) { + if (node->leftnode == NODE) + byte |= TRIENODE; + *data++ = byte; + index++; + } else if (node->right) { + byte |= RIGHTNODE; + if (node->rightnode == NODE) + byte |= TRIENODE; + *data++ = byte; + index++; + } else { + assert(0); + } +skip: + while (node) { + bitmask = 1 << node->bitnum; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + data = tree->leaf_emit(node->left, + data); + index += tree->leaf_size(node->left); + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + data = tree->leaf_emit(node->right, + data); + index += tree->leaf_size(node->right); + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +} + +/* ------------------------------------------------------------------ */ + +/* + * Unicode data. + * + * We need to keep track of the Canonical Combining Class, the Age, + * and decompositions for a code point. + * + * For the Age, we store the index into the ages table. Effectively + * this is a generation number that the table maps to a unicode + * version. + * + * The correction field is used to indicate that this entry is in the + * corrections array, which contains decompositions that were + * corrected in later revisions. The value of the correction field is + * the Unicode version in which the mapping was corrected. + */ +struct unicode_data { + unsigned int code; + int ccc; + int gen; + int correction; + unsigned int *utf32nfkdi; + unsigned int *utf32nfkdicf; + char *utf8nfkdi; + char *utf8nfkdicf; +}; + +struct unicode_data unicode_data[0x110000]; +struct unicode_data *corrections; +int corrections_count; + +struct tree *nfkdi_tree; +struct tree *nfkdicf_tree; + +struct tree *trees; +int trees_count; + +/* + * Check the corrections array to see if this entry was corrected at + * some point. + */ +static struct unicode_data * +corrections_lookup(struct unicode_data *u) +{ + int i; + + for (i = 0; i != corrections_count; i++) + if (u->code == corrections[i].code) + return &corrections[i]; + return u; +} + +static int +nfkdi_equal(void *l, void *r) +{ + struct unicode_data *left = l; + struct unicode_data *right = r; + + if (left->gen != right->gen) + return 0; + if (left->ccc != right->ccc) + return 0; + if (left->utf8nfkdi && right->utf8nfkdi && + strcmp(left->utf8nfkdi, right->utf8nfkdi) == 0) + return 1; + if (left->utf8nfkdi || right->utf8nfkdi) + return 0; + return 1; +} + +static int +nfkdicf_equal(void *l, void *r) +{ + struct unicode_data *left = l; + struct unicode_data *right = r; + + if (left->gen != right->gen) + return 0; + if (left->ccc != right->ccc) + return 0; + if (left->utf8nfkdicf && right->utf8nfkdicf && + strcmp(left->utf8nfkdicf, right->utf8nfkdicf) == 0) + return 1; + if (left->utf8nfkdicf && right->utf8nfkdicf) + return 0; + if (left->utf8nfkdicf || right->utf8nfkdicf) + return 0; + if (left->utf8nfkdi && right->utf8nfkdi && + strcmp(left->utf8nfkdi, right->utf8nfkdi) == 0) + return 1; + if (left->utf8nfkdi || right->utf8nfkdi) + return 0; + return 1; +} + +static void +nfkdi_print(void *l, int indent) +{ + struct unicode_data *leaf = l; + + printf("%*sleaf @ %p code %X ccc %d gen %d", indent, "", leaf, + leaf->code, leaf->ccc, leaf->gen); + if (leaf->utf8nfkdi) + printf(" nfkdi \"%s\"", (const char*)leaf->utf8nfkdi); + printf("\n"); +} + +static void +nfkdicf_print(void *l, int indent) +{ + struct unicode_data *leaf = l; + + printf("%*sleaf @ %p code %X ccc %d gen %d", indent, "", leaf, + leaf->code, leaf->ccc, leaf->gen); + if (leaf->utf8nfkdicf) + printf(" nfkdicf \"%s\"", (const char*)leaf->utf8nfkdicf); + else if (leaf->utf8nfkdi) + printf(" nfkdi \"%s\"", (const char*)leaf->utf8nfkdi); + printf("\n"); +} + +static int +nfkdi_mark(void *l) +{ + return 1; +} + +static int +nfkdicf_mark(void *l) +{ + struct unicode_data *leaf = l; + if (leaf->utf8nfkdicf) + return 1; + return 0; +} + +static int +correction_mark(void *l) +{ + struct unicode_data *leaf = l; + return leaf->correction; +} + +static int +nfkdi_size(void *l) +{ + struct unicode_data *leaf = l; + int size = 2; + if (leaf->utf8nfkdi) + size += strlen(leaf->utf8nfkdi) + 1; + return size; +} + +static int +nfkdicf_size(void *l) +{ + struct unicode_data *leaf = l; + int size = 2; + if (leaf->utf8nfkdicf) + size += strlen(leaf->utf8nfkdicf) + 1; + else if (leaf->utf8nfkdi) + size += strlen(leaf->utf8nfkdi) + 1; + return size; +} + +static int * +nfkdi_index(struct tree *tree, void *l) +{ + struct unicode_data *leaf = l; + return &tree->leafindex[leaf->code]; +} + +static int * +nfkdicf_index(struct tree *tree, void *l) +{ + struct unicode_data *leaf = l; + return &tree->leafindex[leaf->code]; +} + +static unsigned char * +nfkdi_emit(void *l, unsigned char *data) +{ + struct unicode_data *leaf = l; + unsigned char *s; + + *data++ = leaf->gen; + if (leaf->utf8nfkdi) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdi; + while ((*data++ = *s++) != 0) + ; + } else { + *data++ = leaf->ccc; + } + return data; +} + +static unsigned char * +nfkdicf_emit(void *l, unsigned char *data) +{ + struct unicode_data *leaf = l; + unsigned char *s; + + *data++ = leaf->gen; + if (leaf->utf8nfkdicf) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdicf; + while ((*data++ = *s++) != 0) + ; + } else if (leaf->utf8nfkdi) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdi; + while ((*data++ = *s++) != 0) + ; + } else { + *data++ = leaf->ccc; + } + return data; +} + +static void +utf8_create(struct unicode_data *data) +{ + char utf[18*4+1]; + char *u; + unsigned int *um; + int i; + + u = utf; + um = data->utf32nfkdi; + if (um) { + for (i = 0; um[i]; i++) + u += utf8key(um[i], u); + *u = '\0'; + data->utf8nfkdi = strdup((char*)utf); + } + u = utf; + um = data->utf32nfkdicf; + if (um) { + for (i = 0; um[i]; i++) + u += utf8key(um[i], u); + *u = '\0'; + if (!data->utf8nfkdi || strcmp(data->utf8nfkdi, (char*)utf)) + data->utf8nfkdicf = strdup((char*)utf); + } +} + +static void +utf8_init(void) +{ + unsigned int unichar; + int i; + + for (unichar = 0; unichar != 0x110000; unichar++) + utf8_create(&unicode_data[unichar]); + + for (i = 0; i != corrections_count; i++) + utf8_create(&corrections[i]); +} + +static void +trees_init(void) +{ + struct unicode_data *data; + unsigned int maxage; + unsigned int nextage; + int count; + int i; + int j; + + /* Count the number of different ages. */ + count = 0; + nextage = (unsigned int)-1; + do { + maxage = nextage; + nextage = 0; + for (i = 0; i <= corrections_count; i++) { + data = &corrections[i]; + if (nextage < data->correction && + data->correction < maxage) + nextage = data->correction; + } + count++; + } while (nextage); + + /* Two trees per age: nfkdi and nfkdicf */ + trees_count = count * 2; + trees = calloc(trees_count, sizeof(struct tree)); + + /* Assign ages to the trees. */ + count = trees_count; + nextage = (unsigned int)-1; + do { + maxage = nextage; + trees[--count].maxage = maxage; + trees[--count].maxage = maxage; + nextage = 0; + for (i = 0; i <= corrections_count; i++) { + data = &corrections[i]; + if (nextage < data->correction && + data->correction < maxage) + nextage = data->correction; + } + } while (nextage); + + /* The ages assigned above are off by one. */ + for (i = 0; i != trees_count; i++) { + j = 0; + while (ages[j] < trees[i].maxage) + j++; + trees[i].maxage = ages[j-1]; + } + + /* Set up the forwarding between trees. */ + trees[trees_count-2].next = &trees[trees_count-1]; + trees[trees_count-1].leaf_mark = nfkdi_mark; + trees[trees_count-2].leaf_mark = nfkdicf_mark; + for (i = 0; i != trees_count-2; i += 2) { + trees[i].next = &trees[trees_count-2]; + trees[i].leaf_mark = correction_mark; + trees[i+1].next = &trees[trees_count-1]; + trees[i+1].leaf_mark = correction_mark; + } + + /* Assign the callouts. */ + for (i = 0; i != trees_count; i += 2) { + trees[i].type = "nfkdicf"; + trees[i].leaf_equal = nfkdicf_equal; + trees[i].leaf_print = nfkdicf_print; + trees[i].leaf_size = nfkdicf_size; + trees[i].leaf_index = nfkdicf_index; + trees[i].leaf_emit = nfkdicf_emit; + + trees[i+1].type = "nfkdi"; + trees[i+1].leaf_equal = nfkdi_equal; + trees[i+1].leaf_print = nfkdi_print; + trees[i+1].leaf_size = nfkdi_size; + trees[i+1].leaf_index = nfkdi_index; + trees[i+1].leaf_emit = nfkdi_emit; + } + + /* Finish init. */ + for (i = 0; i != trees_count; i++) + trees[i].childnode = NODE; +} + +static void +trees_populate(void) +{ + struct unicode_data *data; + unsigned int unichar; + char keyval[4]; + int keylen; + int i; + + for (i = 0; i != trees_count; i++) { + if (verbose > 0) { + printf("Populating %s_%x\n", + trees[i].type, trees[i].maxage); + } + for (unichar = 0; unichar != 0x110000; unichar++) { + if (unicode_data[unichar].gen < 0) + continue; + keylen = utf8key(unichar, keyval); + data = corrections_lookup(&unicode_data[unichar]); + if (data->correction <= trees[i].maxage) + data = &unicode_data[unichar]; + insert(&trees[i], keyval, keylen, data); + } + } +} + +static void +trees_reduce(void) +{ + int i; + int size; + int changed; + + for (i = 0; i != trees_count; i++) + prune(&trees[i]); + for (i = 0; i != trees_count; i++) + mark_nodes(&trees[i]); + do { + size = 0; + for (i = 0; i != trees_count; i++) + size = index_nodes(&trees[i], size); + changed = 0; + for (i = 0; i != trees_count; i++) + changed += size_nodes(&trees[i]); + } while (changed); + + utf8data = calloc(size, 1); + utf8data_size = size; + for (i = 0; i != trees_count; i++) + emit(&trees[i], utf8data); + + if (verbose > 0) { + for (i = 0; i != trees_count; i++) { + printf("%s_%x idx %d\n", + trees[i].type, trees[i].maxage, trees[i].index); + } + } + + nfkdi = utf8data + trees[trees_count-1].index; + nfkdicf = utf8data + trees[trees_count-2].index; + + nfkdi_tree = &trees[trees_count-1]; + nfkdicf_tree = &trees[trees_count-2]; +} + +static void +verify(struct tree *tree) +{ + struct unicode_data *data; + utf8leaf_t *leaf; + unsigned int unichar; + char key[4]; + int report; + int nocf; + + if (verbose > 0) + printf("Verifying %s_%x\n", tree->type, tree->maxage); + nocf = strcmp(tree->type, "nfkdicf"); + + for (unichar = 0; unichar != 0x110000; unichar++) { + report = 0; + data = corrections_lookup(&unicode_data[unichar]); + if (data->correction <= tree->maxage) + data = &unicode_data[unichar]; + utf8key(unichar, key); + leaf = utf8lookup(tree, key); + if (!leaf) { + if (data->gen != -1) + report++; + if (unichar < 0xd800 || unichar > 0xdfff) + report++; + } else { + if (unichar >= 0xd800 && unichar <= 0xdfff) + report++; + if (data->gen == -1) + report++; + if (data->gen != LEAF_GEN(leaf)) + report++; + if (LEAF_CCC(leaf) == DECOMPOSE) { + if (nocf) { + if (!data->utf8nfkdi) { + report++; + } else if (strcmp(data->utf8nfkdi, + LEAF_STR(leaf))) { + report++; + } + } else { + if (!data->utf8nfkdicf && + !data->utf8nfkdi) { + report++; + } else if (data->utf8nfkdicf) { + if (strcmp(data->utf8nfkdicf, + LEAF_STR(leaf))) + report++; + } else if (strcmp(data->utf8nfkdi, + LEAF_STR(leaf))) { + report++; + } + } + } else if (data->ccc != LEAF_CCC(leaf)) { + report++; + } + } + if (report) { + printf("%X code %X gen %d ccc %d" + " nfdki -> \"%s\"", + unichar, data->code, data->gen, + data->ccc, + data->utf8nfkdi); + if (leaf) { + printf(" age %d ccc %d" + " nfdki -> \"%s\"\n", + LEAF_GEN(leaf), + LEAF_CCC(leaf), + LEAF_CCC(leaf) == DECOMPOSE ? + LEAF_STR(leaf) : ""); + } + printf("\n"); + } + } +} + +static void +trees_verify(void) +{ + int i; + + for (i = 0; i != trees_count; i++) + verify(&trees[i]); +} + +/* ------------------------------------------------------------------ */ + +static void +help(void) +{ + printf("Usage: %s [options]\n", argv0); + printf("\n"); + printf("This program creates an a data trie used for parsing and\n"); + printf("normalization of UTF-8 strings. The trie is derived from\n"); + printf("a set of input files from the Unicode character database\n"); + printf("found at: http://www.unicode.org/Public/UCD/latest/ucd/\n"); + printf("\n"); + printf("The generated tree supports two normalization forms:\n"); + printf("\n"); + printf("\tnfkdi:\n"); + printf("\t- Apply unicode normalization form NFKD.\n"); + printf("\t- Remove any Default_Ignorable_Code_Point.\n"); + printf("\n"); + printf("\tnfkdicf:\n"); + printf("\t- Apply unicode normalization form NFKD.\n"); + printf("\t- Remove any Default_Ignorable_Code_Point.\n"); + printf("\t- Apply a full casefold (C + F).\n"); + printf("\n"); + printf("These forms were chosen as being most useful when dealing\n"); + printf("with file names: NFKD catches most cases where characters\n"); + printf("should be considered equivalent. The ignorables are mostly\n"); + printf("invisible, making names hard to type.\n"); + printf("\n"); + printf("The options to specify the files to be used are listed\n"); + printf("below with their default values, which are the names used\n"); + printf("by version 7.0.0 of the Unicode Character Database.\n"); + printf("\n"); + printf("The input files:\n"); + printf("\t-a %s\n", AGE_NAME); + printf("\t-c %s\n", CCC_NAME); + printf("\t-p %s\n", PROP_NAME); + printf("\t-d %s\n", DATA_NAME); + printf("\t-f %s\n", FOLD_NAME); + printf("\t-n %s\n", NORM_NAME); + printf("\n"); + printf("Additionally, the generated tables are tested using:\n"); + printf("\t-t %s\n", TEST_NAME); + printf("\n"); + printf("Finally, the output file:\n"); + printf("\t-o %s\n", UTF8_NAME); + printf("\n"); +} + +static void +usage(void) +{ + help(); + exit(1); +} + +static void +open_fail(const char *name, int error) +{ + printf("Error %d opening %s: %s\n", error, name, strerror(error)); + exit(1); +} + +static void +file_fail(const char *filename) +{ + printf("Error parsing %s\n", filename); + exit(1); +} + +static void +line_fail(const char *filename, const char *line) +{ + printf("Error parsing %s:%s\n", filename, line); + exit(1); +} + +/* ------------------------------------------------------------------ */ + +static void +print_utf32(unsigned int *utf32str) +{ + int i; + for (i = 0; utf32str[i]; i++) + printf(" %X", utf32str[i]); +} + +static void +print_utf32nfkdi(unsigned int unichar) +{ + printf(" %X ->", unichar); + print_utf32(unicode_data[unichar].utf32nfkdi); + printf("\n"); +} + +static void +print_utf32nfkdicf(unsigned int unichar) +{ + printf(" %X ->", unichar); + print_utf32(unicode_data[unichar].utf32nfkdicf); + printf("\n"); +} + +/* ------------------------------------------------------------------ */ + +static void +age_init(void) +{ + FILE *file; + unsigned int first; + unsigned int last; + unsigned int unichar; + unsigned int major; + unsigned int minor; + unsigned int revision; + int gen; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", age_name); + + file = fopen(age_name, "r"); + if (!file) + open_fail(age_name, errno); + count = 0; + + gen = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "# Age=V%d_%d_%d", + &major, &minor, &revision); + if (ret == 3) { + ages_count++; + if (verbose > 1) + printf(" Age V%d_%d_%d\n", + major, minor, revision); + if (!age_valid(major, minor, revision)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "# Age=V%d_%d", &major, &minor); + if (ret == 2) { + ages_count++; + if (verbose > 1) + printf(" Age V%d_%d\n", major, minor); + if (!age_valid(major, minor, 0)) + line_fail(age_name, line); + continue; + } + } + + /* We must have found something above. */ + if (verbose > 1) + printf("%d age entries\n", ages_count); + if (ages_count == 0 || ages_count > MAXGEN) + file_fail(age_name); + + /* There is a 0 entry. */ + ages_count++; + ages = calloc(ages_count + 1, sizeof(*ages)); + /* And a guard entry. */ + ages[ages_count] = (unsigned int)-1; + + rewind(file); + count = 0; + gen = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "# Age=V%d_%d_%d", + &major, &minor, &revision); + if (ret == 3) { + ages[++gen] = + UNICODE_AGE(major, minor, revision); + if (verbose > 1) + printf(" Age V%d_%d_%d = gen %d\n", + major, minor, revision, gen); + if (!age_valid(major, minor, revision)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "# Age=V%d_%d", &major, &minor); + if (ret == 2) { + ages[++gen] = UNICODE_AGE(major, minor, 0); + if (verbose > 1) + printf(" Age V%d_%d = %d\n", + major, minor, gen); + if (!age_valid(major, minor, 0)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "%X..%X ; %d.%d #", + &first, &last, &major, &minor); + if (ret == 4) { + for (unichar = first; unichar <= last; unichar++) + unicode_data[unichar].gen = gen; + count += 1 + last - first; + if (verbose > 1) + printf(" %X..%X gen %d\n", first, last, gen); + if (!utf32valid(first) || !utf32valid(last)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "%X ; %d.%d #", &unichar, &major, &minor); + if (ret == 3) { + unicode_data[unichar].gen = gen; + count++; + if (verbose > 1) + printf(" %X gen %d\n", unichar, gen); + if (!utf32valid(unichar)) + line_fail(age_name, line); + continue; + } + } + unicode_maxage = ages[gen]; + fclose(file); + + /* Nix surrogate block */ + if (verbose > 1) + printf(" Removing surrogate block D800..DFFF\n"); + for (unichar = 0xd800; unichar <= 0xdfff; unichar++) + unicode_data[unichar].gen = -1; + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(age_name); +} + +static void +ccc_init(void) +{ + FILE *file; + unsigned int first; + unsigned int last; + unsigned int unichar; + unsigned int value; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", ccc_name); + + file = fopen(ccc_name, "r"); + if (!file) + open_fail(ccc_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X..%X ; %d #", &first, &last, &value); + if (ret == 3) { + for (unichar = first; unichar <= last; unichar++) { + unicode_data[unichar].ccc = value; + count++; + } + if (verbose > 1) + printf(" %X..%X ccc %d\n", first, last, value); + if (!utf32valid(first) || !utf32valid(last)) + line_fail(ccc_name, line); + continue; + } + ret = sscanf(line, "%X ; %d #", &unichar, &value); + if (ret == 2) { + unicode_data[unichar].ccc = value; + count++; + if (verbose > 1) + printf(" %X ccc %d\n", unichar, value); + if (!utf32valid(unichar)) + line_fail(ccc_name, line); + continue; + } + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(ccc_name); +} + +static void +nfkdi_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char *s; + unsigned int *um; + int count; + int i; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", data_name); + file = fopen(data_name, "r"); + if (!file) + open_fail(data_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%*[^;];%*[^;];%*[^;];%*[^;];%[^;];", + &unichar, buf0); + if (ret != 2) + continue; + if (!utf32valid(unichar)) + line_fail(data_name, line); + + s = buf0; + /* skip over */ + if (*s == '<') + while (*s++ != ' ') + ; + /* decode the decomposition into UTF-32 */ + i = 0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(data_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + + if (verbose > 1) + print_utf32nfkdi(unichar); + count++; + } + fclose(file); + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(data_name); +} + +static void +nfkdicf_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char status; + char *s; + unsigned int *um; + int i; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", fold_name); + file = fopen(fold_name, "r"); + if (!file) + open_fail(fold_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X; %c; %[^;];", &unichar, &status, buf0); + if (ret != 3) + continue; + if (!utf32valid(unichar)) + line_fail(fold_name, line); + /* Use the C+F casefold. */ + if (status != 'C' && status != 'F') + continue; + s = buf0; + if (*s == '<') + while (*s++ != ' ') + ; + i = 0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(fold_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + + if (verbose > 1) + print_utf32nfkdicf(unichar); + count++; + } + fclose(file); + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(fold_name); +} + +static void +ignore_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int first; + unsigned int last; + unsigned int *um; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", prop_name); + file = fopen(prop_name, "r"); + if (!file) + open_fail(prop_name, errno); + assert(file); + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X..%X ; %s # ", &first, &last, buf0); + if (ret == 3) { + if (strcmp(buf0, "Default_Ignorable_Code_Point")) + continue; + if (!utf32valid(first) || !utf32valid(last)) + line_fail(prop_name, line); + for (unichar = first; unichar <= last; unichar++) { + free(unicode_data[unichar].utf32nfkdi); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdi = um; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdicf = um; + count++; + } + if (verbose > 1) + printf(" %X..%X Default_Ignorable_Code_Point\n", + first, last); + continue; + } + ret = sscanf(line, "%X ; %s # ", &unichar, buf0); + if (ret == 2) { + if (strcmp(buf0, "Default_Ignorable_Code_Point")) + continue; + if (!utf32valid(unichar)) + line_fail(prop_name, line); + free(unicode_data[unichar].utf32nfkdi); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdi = um; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdicf = um; + if (verbose > 1) + printf(" %X Default_Ignorable_Code_Point\n", + unichar); + count++; + continue; + } + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(prop_name); +} + +static void +corrections_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int major; + unsigned int minor; + unsigned int revision; + unsigned int age; + unsigned int *um; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char *s; + int i; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", norm_name); + file = fopen(norm_name, "r"); + if (!file) + open_fail(norm_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%[^;];%[^;];%d.%d.%d #", + &unichar, buf0, buf1, + &major, &minor, &revision); + if (ret != 6) + continue; + if (!utf32valid(unichar) || !age_valid(major, minor, revision)) + line_fail(norm_name, line); + count++; + } + corrections = calloc(count, sizeof(struct unicode_data)); + corrections_count = count; + rewind(file); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%[^;];%[^;];%d.%d.%d #", + &unichar, buf0, buf1, + &major, &minor, &revision); + if (ret != 6) + continue; + if (!utf32valid(unichar) || !age_valid(major, minor, revision)) + line_fail(norm_name, line); + corrections[count] = unicode_data[unichar]; + assert(corrections[count].code == unichar); + age = UNICODE_AGE(major, minor, revision); + corrections[count].correction = age; + + i = 0; + s = buf0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(norm_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + corrections[count].utf32nfkdi = um; + + if (verbose > 1) + printf(" %X -> %s -> %s V%d_%d_%d\n", + unichar, buf0, buf1, major, minor, revision); + count++; + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(norm_name); +} + +/* ------------------------------------------------------------------ */ + +/* + * Hangul decomposition (algorithm from Section 3.12 of Unicode 6.3.0) + * + * AC00;;Lo;0;L;;;;;N;;;;; + * D7A3;;Lo;0;L;;;;;N;;;;; + * + * SBase = 0xAC00 + * LBase = 0x1100 + * VBase = 0x1161 + * TBase = 0x11A7 + * LCount = 19 + * VCount = 21 + * TCount = 28 + * NCount = 588 (VCount * TCount) + * SCount = 11172 (LCount * NCount) + * + * Decomposition: + * SIndex = s - SBase + * + * LV (Canonical/Full) + * LIndex = SIndex / NCount + * VIndex = (Sindex % NCount) / TCount + * LPart = LBase + LIndex + * VPart = VBase + VIndex + * + * LVT (Canonical) + * LVIndex = (SIndex / TCount) * TCount + * TIndex = (Sindex % TCount + * LVPart = LBase + LVIndex + * TPart = TBase + TIndex + * + * LVT (Full) + * LIndex = SIndex / NCount + * VIndex = (Sindex % NCount) / TCount + * TIndex = (Sindex % TCount + * LPart = LBase + LIndex + * VPart = VBase + VIndex + * if (TIndex == 0) { + * d = + * } else { + * TPart = TBase + TIndex + * d = + * } + * + */ + +static void +hangul_decompose(void) +{ + unsigned int sb = 0xAC00; + unsigned int lb = 0x1100; + unsigned int vb = 0x1161; + unsigned int tb = 0x11a7; + /* unsigned int lc = 19; */ + unsigned int vc = 21; + unsigned int tc = 28; + unsigned int nc = (vc * tc); + /* unsigned int sc = (lc * nc); */ + unsigned int unichar; + unsigned int mapping[4]; + unsigned int *um; + int count; + int i; + + if (verbose > 0) + printf("Decomposing hangul\n"); + /* Hangul */ + count = 0; + for (unichar = 0xAC00; unichar <= 0xD7A3; unichar++) { + unsigned int si = unichar - sb; + unsigned int li = si / nc; + unsigned int vi = (si % nc) / tc; + unsigned int ti = si % tc; + + i = 0; + mapping[i++] = lb + li; + mapping[i++] = vb + vi; + if (ti) + mapping[i++] = tb + ti; + mapping[i++] = 0; + + assert(!unicode_data[unichar].utf32nfkdi); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + + assert(!unicode_data[unichar].utf32nfkdicf); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + + if (verbose > 1) + print_utf32nfkdi(unichar); + + count++; + } + if (verbose > 0) + printf("Created %d entries\n", count); +} + +static void +nfkdi_decompose(void) +{ + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + unsigned int *um; + unsigned int *dc; + int count; + int i; + int j; + int ret; + + if (verbose > 0) + printf("Decomposing nfkdi\n"); + + count = 0; + for (unichar = 0; unichar != 0x110000; unichar++) { + if (!unicode_data[unichar].utf32nfkdi) + continue; + for (;;) { + ret = 1; + i = 0; + um = unicode_data[unichar].utf32nfkdi; + while (*um) { + dc = unicode_data[*um].utf32nfkdi; + if (dc) { + for (j = 0; dc[j]; j++) + mapping[i++] = dc[j]; + ret = 0; + } else { + mapping[i++] = *um; + } + um++; + } + mapping[i++] = 0; + if (ret) + break; + free(unicode_data[unichar].utf32nfkdi); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + } + /* Add this decomposition to nfkdicf if there is no entry. */ + if (!unicode_data[unichar].utf32nfkdicf) { + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + } + if (verbose > 1) + print_utf32nfkdi(unichar); + count++; + } + if (verbose > 0) + printf("Processed %d entries\n", count); +} + +static void +nfkdicf_decompose(void) +{ + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + unsigned int *um; + unsigned int *dc; + int count; + int i; + int j; + int ret; + + if (verbose > 0) + printf("Decomposing nfkdicf\n"); + count = 0; + for (unichar = 0; unichar != 0x110000; unichar++) { + if (!unicode_data[unichar].utf32nfkdicf) + continue; + for (;;) { + ret = 1; + i = 0; + um = unicode_data[unichar].utf32nfkdicf; + while (*um) { + dc = unicode_data[*um].utf32nfkdicf; + if (dc) { + for (j = 0; dc[j]; j++) + mapping[i++] = dc[j]; + ret = 0; + } else { + mapping[i++] = *um; + } + um++; + } + mapping[i++] = 0; + if (ret) + break; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + } + if (verbose > 1) + print_utf32nfkdicf(unichar); + count++; + } + if (verbose > 0) + printf("Processed %d entries\n", count); +} + +/* ------------------------------------------------------------------ */ + +int utf8agemax(struct tree *, const char *); +int utf8nagemax(struct tree *, const char *, size_t); +int utf8agemin(struct tree *, const char *); +int utf8nagemin(struct tree *, const char *, size_t); +ssize_t utf8len(struct tree *, const char *); +ssize_t utf8nlen(struct tree *, const char *, size_t); +struct utf8cursor; +int utf8cursor(struct utf8cursor *, struct tree *, const char *); +int utf8ncursor(struct utf8cursor *, struct tree *, const char *, size_t); +int utf8byte(struct utf8cursor *); + +/* + * Use trie to scan s, touching at most len bytes. + * Returns the leaf if one exists, NULL otherwise. + * + * A non-NULL return guarantees that the UTF-8 sequence starting at s + * is well-formed and corresponds to a known unicode code point. The + * shorthand for this will be "is valid UTF-8 unicode". + */ +static utf8leaf_t * +utf8nlookup(struct tree *tree, const char *s, size_t len) +{ + utf8trie_t *trie = utf8data + tree->index; + int offlen; + int offset; + int mask; + int node; + + if (!tree) + return NULL; + if (len == 0) + return NULL; + node = 1; + while (node) { + offlen = (*trie & OFFLEN) >> OFFLEN_SHIFT; + if (*trie & NEXTBYTE) { + if (--len == 0) + return NULL; + s++; + } + mask = 1 << (*trie & BITNUM); + if (*s & mask) { + /* Right leg */ + if (offlen) { + /* Right node at offset of trie */ + node = (*trie & RIGHTNODE); + offset = trie[offlen]; + while (--offlen) { + offset <<= 8; + offset |= trie[offlen]; + } + trie += offset; + } else if (*trie & RIGHTPATH) { + /* Right node after this node */ + node = (*trie & TRIENODE); + trie++; + } else { + /* No right node. */ + node = 0; + trie = NULL; + } + } else { + /* Left leg */ + if (offlen) { + /* Left node after this node. */ + node = (*trie & LEFTNODE); + trie += offlen + 1; + } else if (*trie & RIGHTPATH) { + /* No left node. */ + node = 0; + trie = NULL; + } else { + /* Left node after this node */ + node = (*trie & TRIENODE); + trie++; + } + } + } + return trie; +} + +/* + * Use trie to scan s. + * Returns the leaf if one exists, NULL otherwise. + * + * Forwards to trie_nlookup(). + */ +static utf8leaf_t * +utf8lookup(struct tree *tree, const char *s) +{ + return utf8nlookup(tree, s, (size_t)-1); +} + +/* + * Return the number of bytes used by the current UTF-8 sequence. + * Assumes the input points to the first byte of a valid UTF-8 + * sequence. + */ +static inline int +utf8clen(const char *s) +{ + unsigned char c = *s; + return 1 + (c >= 0xC0) + (c >= 0xE0) + (c >= 0xF0); +} + +/* + * Maximum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if only non-assigned code points are used. + */ +int +utf8agemax(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age > age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Minimum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if non-assigned code points are used. + */ +int +utf8agemin(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + int age = tree->maxage; + int leaf_age; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age < age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemax(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age > age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemin(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int leaf_age; + int age = tree->maxage; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age < age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Length of the normalization of s. + * Return -1 if s is not valid UTF-8 unicode. + * + * A string of Default_Ignorable_Code_Point has length 0. + */ +ssize_t +utf8len(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + if (ages[LEAF_GEN(leaf)] > tree->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Length of the normalization of s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +ssize_t +utf8nlen(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + if (ages[LEAF_GEN(leaf)] > tree->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + len -= utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Cursor structure used by the normalizer. + */ +struct utf8cursor { + struct tree *tree; + const char *s; + const char *p; + const char *ss; + const char *sp; + unsigned int len; + unsigned int slen; + short int ccc; + short int nccc; + unsigned int unichar; +}; + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * s : string. + * len : length of s. + * u8c : pointer to cursor. + * trie : utf8trie_t to use for normalization. + * + * Returns -1 on error, 0 on success. + */ +int +utf8ncursor( + struct utf8cursor *u8c, + struct tree *tree, + const char *s, + size_t len) +{ + if (!tree) + return -1; + if (!s) + return -1; + u8c->tree = tree; + u8c->s = s; + u8c->p = NULL; + u8c->ss = NULL; + u8c->sp = NULL; + u8c->len = len; + u8c->slen = 0; + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->unichar = 0; + /* Check we didn't clobber the maximum length. */ + if (u8c->len != len) + return -1; + /* The first byte of s may not be an utf8 continuation. */ + if (len > 0 && (*s & 0xC0) == 0x80) + return -1; + return 0; +} + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * s : NUL-terminated string. + * u8c : pointer to cursor. + * trie : utf8trie_t to use for normalization. + * + * Returns -1 on error, 0 on success. + */ +int +utf8cursor( + struct utf8cursor *u8c, + struct tree *tree, + const char *s) +{ + return utf8ncursor(u8c, tree, s, (unsigned int)-1); +} + +/* + * Get one byte from the normalized form of the string described by u8c. + * + * Returns the byte cast to an unsigned char on succes, and -1 on failure. + * + * The cursor keeps track of the location in the string in u8c->s. + * When a character is decomposed, the current location is stored in + * u8c->p, and u8c->s is set to the start of the decomposition. Note + * that bytes from a decomposition do not count against u8c->len. + * + * Characters are emitted if they match the current CCC in u8c->ccc. + * Hitting end-of-string while u8c->ccc == STOPPER means we're done, + * and the function returns 0 in that case. + * + * Sorting by CCC is done by repeatedly scanning the string. The + * values of u8c->s and u8c->p are stored in u8c->ss and u8c->sp at + * the start of the scan. The first pass finds the lowest CCC to be + * emitted and stores it in u8c->nccc, the second pass emits the + * characters with this CCC and finds the next lowest CCC. This limits + * the number of passes to 1 + the number of different CCCs in the + * sequence being scanned. + * + * Therefore: + * u8c->p != NULL -> a decomposition is being scanned. + * u8c->ss != NULL -> this is a repeating scan. + * u8c->ccc == -1 -> this is the first scan of a repeating scan. + */ +int +utf8byte(struct utf8cursor *u8c) +{ + utf8leaf_t *leaf; + int ccc; + + for (;;) { + /* Check for the end of a decomposed character. */ + if (u8c->p && *u8c->s == '\0') { + u8c->s = u8c->p; + u8c->p = NULL; + } + + /* Check for end-of-string. */ + if (!u8c->p && (u8c->len == 0 || *u8c->s == '\0')) { + /* There is no next byte. */ + if (u8c->ccc == STOPPER) + return 0; + /* End-of-string during a scan counts as a stopper. */ + ccc = STOPPER; + goto ccc_mismatch; + } else if ((*u8c->s & 0xC0) == 0x80) { + /* This is a continuation of the current character. */ + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Look up the data for the current character. */ + if (u8c->p) + leaf = utf8lookup(u8c->tree, u8c->s); + else + leaf = utf8nlookup(u8c->tree, u8c->s, u8c->len); + + /* No leaf found implies that the input is a binary blob. */ + if (!leaf) + return -1; + + /* Characters that are too new have CCC 0. */ + if (ages[LEAF_GEN(leaf)] > u8c->tree->maxage) { + ccc = STOPPER; + } else if ((ccc = LEAF_CCC(leaf)) == DECOMPOSE) { + u8c->len -= utf8clen(u8c->s); + u8c->p = u8c->s + utf8clen(u8c->s); + u8c->s = LEAF_STR(leaf); + /* Empty decomposition implies CCC 0. */ + if (*u8c->s == '\0') { + if (u8c->ccc == STOPPER) + continue; + ccc = STOPPER; + goto ccc_mismatch; + } + leaf = utf8lookup(u8c->tree, u8c->s); + ccc = LEAF_CCC(leaf); + } + u8c->unichar = utf8code(u8c->s); + + /* + * If this is not a stopper, then see if it updates + * the next canonical class to be emitted. + */ + if (ccc != STOPPER && u8c->ccc < ccc && ccc < u8c->nccc) + u8c->nccc = ccc; + + /* + * Return the current byte if this is the current + * combining class. + */ + if (ccc == u8c->ccc) { + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Current combining class mismatch. */ + ccc_mismatch: + if (u8c->nccc == STOPPER) { + /* + * Scan forward for the first canonical class + * to be emitted. Save the position from + * which to restart. + */ + assert(u8c->ccc == STOPPER); + u8c->ccc = MINCCC - 1; + u8c->nccc = ccc; + u8c->sp = u8c->p; + u8c->ss = u8c->s; + u8c->slen = u8c->len; + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (ccc != STOPPER) { + /* Not a stopper, and not the ccc we're emitting. */ + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (u8c->nccc != MAXCCC + 1) { + /* At a stopper, restart for next ccc. */ + u8c->ccc = u8c->nccc; + u8c->nccc = MAXCCC + 1; + u8c->s = u8c->ss; + u8c->p = u8c->sp; + u8c->len = u8c->slen; + } else { + /* All done, proceed from here. */ + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->sp = NULL; + u8c->ss = NULL; + u8c->slen = 0; + } + } +} + +/* ------------------------------------------------------------------ */ + +static int +normalize_line(struct tree *tree) +{ + char *s; + char *t; + int c; + struct utf8cursor u8c; + + /* First test: null-terminated string. */ + s = buf2; + t = buf3; + if (utf8cursor(&u8c, tree, s)) + return -1; + while ((c = utf8byte(&u8c)) > 0) + if (c != (unsigned char)*t++) + return -1; + if (c < 0) + return -1; + if (*t != 0) + return -1; + + /* Second test: length-limited string. */ + s = buf2; + /* Replace NUL with a value that will cause an error if seen. */ + s[strlen(s) + 1] = -1; + t = buf3; + if (utf8cursor(&u8c, tree, s)) + return -1; + while ((c = utf8byte(&u8c)) > 0) + if (c != (unsigned char)*t++) + return -1; + if (c < 0) + return -1; + if (*t != 0) + return -1; + + return 0; +} + +static void +normalization_test(void) +{ + FILE *file; + unsigned int unichar; + struct unicode_data *data; + char *s; + char *t; + int ret; + int ignorables; + int tests = 0; + int failures = 0; + + if (verbose > 0) + printf("Parsing %s\n", test_name); + /* Step one, read data from file. */ + file = fopen(test_name, "r"); + if (!file) + open_fail(test_name, errno); + + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%[^;];%*[^;];%*[^;];%*[^;];%[^;];", + buf0, buf1); + if (ret != 2 || *line == '#') + continue; + s = buf0; + t = buf2; + while (*s) { + unichar = strtoul(s, &s, 16); + t += utf8key(unichar, t); + } + *t = '\0'; + + ignorables = 0; + s = buf1; + t = buf3; + while (*s) { + unichar = strtoul(s, &s, 16); + data = &unicode_data[unichar]; + if (data->utf8nfkdi && !*data->utf8nfkdi) + ignorables = 1; + else + t += utf8key(unichar, t); + } + *t = '\0'; + + tests++; + if (normalize_line(nfkdi_tree) < 0) { + printf("\nline %s -> %s", buf0, buf1); + if (ignorables) + printf(" (ignorables removed)"); + printf(" failure\n"); + failures++; + } + } + fclose(file); + if (verbose > 0) + printf("Ran %d tests with %d failures\n", tests, failures); + if (failures) + file_fail(test_name); +} + +/* ------------------------------------------------------------------ */ + +static void +write_file(void) +{ + FILE *file; + int i; + int j; + int t; + int gen; + + if (verbose > 0) + printf("Writing %s\n", utf8_name); + file = fopen(utf8_name, "w"); + if (!file) + open_fail(utf8_name, errno); + + fprintf(file, "/* This file is generated code, do not edit. */\n"); + fprintf(file, "#ifndef __INCLUDED_FROM_UTF8NORM_C__\n"); + fprintf(file, "#error Only xfs_utf8.c may include this file.\n"); + fprintf(file, "#endif\n"); + fprintf(file, "\n"); + fprintf(file, "const unsigned int utf8version = %#x;\n", + unicode_maxage); + fprintf(file, "\n"); + fprintf(file, "static const unsigned int utf8agetab[] = {\n"); + for (i = 0; i != ages_count; i++) + fprintf(file, "\t%#x%s\n", ages[i], + ages[i] == unicode_maxage ? "" : ","); + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const struct utf8data utf8nfkdicfdata[] = {\n"); + t = 0; + for (gen = 0; gen < ages_count; gen++) { + fprintf(file, "\t{ %#x, %d }%s\n", + ages[gen], trees[t].index, + ages[gen] == unicode_maxage ? "" : ","); + if (trees[t].maxage == ages[gen]) + t += 2; + } + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const struct utf8data utf8nfkdidata[] = {\n"); + t = 1; + for (gen = 0; gen < ages_count; gen++) { + fprintf(file, "\t{ %#x, %d }%s\n", + ages[gen], trees[t].index, + ages[gen] == unicode_maxage ? "" : ","); + if (trees[t].maxage == ages[gen]) + t += 2; + } + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const unsigned char utf8data[%zd] = {\n", + utf8data_size); + t = 0; + for (i = 0; i != utf8data_size; i += 16) { + if (i == trees[t].index) { + fprintf(file, "\t/* %s_%x */\n", + trees[t].type, trees[t].maxage); + if (t < trees_count-1) + t++; + } + fprintf(file, "\t"); + for (j = i; j != i + 16; j++) + fprintf(file, "0x%.2x%s", utf8data[j], + (j < utf8data_size -1 ? "," : "")); + fprintf(file, "\n"); + } + fprintf(file, "};\n"); + fclose(file); +} + +/* ------------------------------------------------------------------ */ + +int +main(int argc, char *argv[]) +{ + unsigned int unichar; + int opt; + + argv0 = argv[0]; + + while ((opt = getopt(argc, argv, "a:c:d:f:hn:o:p:t:v")) != -1) { + switch (opt) { + case 'a': + age_name = optarg; + break; + case 'c': + ccc_name = optarg; + break; + case 'd': + data_name = optarg; + break; + case 'f': + fold_name = optarg; + break; + case 'n': + norm_name = optarg; + break; + case 'o': + utf8_name = optarg; + break; + case 'p': + prop_name = optarg; + break; + case 't': + test_name = optarg; + break; + case 'v': + verbose++; + break; + case 'h': + help(); + exit(0); + default: + usage(); + } + } + + if (verbose > 1) + help(); + for (unichar = 0; unichar != 0x110000; unichar++) + unicode_data[unichar].code = unichar; + age_init(); + ccc_init(); + nfkdi_init(); + nfkdicf_init(); + ignore_init(); + corrections_init(); + hangul_decompose(); + nfkdi_decompose(); + nfkdicf_decompose(); + utf8_init(); + trees_init(); + trees_populate(); + trees_reduce(); + trees_verify(); + /* Prevent "unused function" warning. */ + (void)lookup(nfkdi_tree, " "); + if (verbose > 2) + tree_walk(nfkdi_tree); + if (verbose > 2) + tree_walk(nfkdicf_tree); + normalization_test(); + write_file(); + + return 0; +} -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 16:00:10 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 41F407F9C for ; Thu, 11 Sep 2014 16:00:10 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0AC6E8F8037; Thu, 11 Sep 2014 14:00:10 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id CD89C4266DC; Thu, 11 Sep 2014 16:00:09 -0500 (CDT) Date: Thu, 11 Sep 2014 16:00:09 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 08/13] libxfs: add xfs_nameops for utf8 and utf8+casefold. Message-ID: <20140911210009.GQ13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber The xfs_utf8_nameops use the nfkdi normalization when comparing filenames, and are installed if the utf8bit is set in the super block. The xfs_utf8_ci_nameops use the nfkdicf normalization when comparing filenames, and are installed if both the utf8bit and the borgbit are set in the superblock. Normalized filenames are not stored on disk. Normalization will fail if a filename is not valid UTF-8, in which case the filename is treated as an opaque blob. Changes: Type conversion to "(const char *)" added to utf8ncursor() and utf8nlen() calls. Signed-off-by: Olaf Weber --- Makefile | 2 +- include/libxfs.h | 1 + include/xfs_utf8.h | 25 ++++++ libxfs/Makefile | 4 +- libxfs/xfs_dir2.c | 15 +++- libxfs/xfs_utf8.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++++ support/Makefile | 24 ++++++ 7 files changed, 303 insertions(+), 6 deletions(-) create mode 100644 include/xfs_utf8.h create mode 100644 libxfs/xfs_utf8.c create mode 100644 support/Makefile diff --git a/Makefile b/Makefile index f56aebd..c442da6 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ LDIRDIRT = $(SRCDIR) LDIRT += $(SRCTAR) endif -LIB_SUBDIRS = libxfs libxlog libxcmd libhandle libdisk +LIB_SUBDIRS = support libxfs libxlog libxcmd libhandle libdisk TOOL_SUBDIRS = copy db estimate fsck fsr growfs io logprint mkfs quota \ mdrestore repair rtcp m4 man doc po debian diff --git a/include/libxfs.h b/include/libxfs.h index 45a924f..99cb3d9 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -59,6 +59,7 @@ #include #include #include +#include #ifndef ARRAY_SIZE diff --git a/include/xfs_utf8.h b/include/xfs_utf8.h new file mode 100644 index 0000000..97b6a91 --- /dev/null +++ b/include/xfs_utf8.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef XFS_UTF8_H +#define XFS_UTF8_H + +extern struct xfs_nameops xfs_utf8_nameops; +extern struct xfs_nameops xfs_utf8_ci_nameops; + +#endif /* XFS_UTF8_H */ diff --git a/libxfs/Makefile b/libxfs/Makefile index ae15a5d..d836027 100644 --- a/libxfs/Makefile +++ b/libxfs/Makefile @@ -14,6 +14,7 @@ HFILES = xfs.h init.h xfs_dir2_priv.h crc32defs.h crc32table.h CFILES = cache.c \ crc32.c \ init.c kmem.c logitem.c radix-tree.c rdwr.c trans.c util.c \ + utf8norm.c \ xfs_alloc.c \ xfs_alloc_btree.c \ xfs_attr.c \ @@ -38,7 +39,8 @@ CFILES = cache.c \ xfs_rtbitmap.c \ xfs_sb.c \ xfs_symlink_remote.c \ - xfs_trans_resv.c + xfs_trans_resv.c \ + xfs_utf8.c CFILES += $(PKG_PLATFORM).c PCFILES = darwin.c freebsd.c irix.c linux.c diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index 1893931..6872844 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -123,10 +123,17 @@ xfs_dir_mount( (uint)sizeof(xfs_da_node_entry_t); mp->m_dir_magicpct = (mp->m_dirblksize * 37) / 100; - if (xfs_sb_version_hasasciici(&mp->m_sb)) - mp->m_dirnameops = &xfs_ascii_ci_nameops; - else - mp->m_dirnameops = &xfs_default_nameops; + if (xfs_sb_version_hasutf8(&mp->m_sb)) { + if (xfs_sb_version_hasasciici(&mp->m_sb)) + mp->m_dirnameops = &xfs_utf8_ci_nameops; + else + mp->m_dirnameops = &xfs_utf8_nameops; + } else { + if (xfs_sb_version_hasasciici(&mp->m_sb)) + mp->m_dirnameops = &xfs_ascii_ci_nameops; + else + mp->m_dirnameops = &xfs_default_nameops; + } } /* diff --git a/libxfs/xfs_utf8.c b/libxfs/xfs_utf8.c new file mode 100644 index 0000000..f5cc231 --- /dev/null +++ b/libxfs/xfs_utf8.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "xfs.h" +#include "xfs_fs.h" +#include "xfs_types.h" +#include "xfs_bit.h" +#include "xfs_inum.h" +#include "xfs_sb.h" +#include "xfs_ag.h" +#include "xfs_dir2.h" +#include "xfs_da_btree.h" +#include "xfs_bmap_btree.h" +#include "xfs_alloc_btree.h" +#include "xfs_dinode.h" +#include "xfs_inode_fork.h" +#include "xfs_bmap.h" +#include "xfs_dir2.h" +#include "xfs_trace.h" +#include "xfs_utf8.h" +#include "utf8norm.h" + +/* + * xfs nameops using nfkdi + */ + +static xfs_dahash_t +xfs_utf8_hashname( + const unsigned char *name, + int len) +{ + utf8data_t nfkdi; + struct utf8cursor u8c; + xfs_dahash_t hash; + int val; + + nfkdi = utf8nfkdi(utf8version); + hash = 0; + if (utf8ncursor(&u8c, nfkdi, (const char *)name, len) < 0) + goto blob; + while ((val = utf8byte(&u8c)) > 0) + hash = val ^ rol32(hash, 7); + /* In case of error treat the name as a binary blob. */ + if (val == 0) + return hash; +blob: + return xfs_da_hashname(name, len); +} + +static int +xfs_utf8_normhash( + struct xfs_da_args *args) +{ + utf8data_t nfkdi; + struct utf8cursor u8c; + unsigned char *norm; + ssize_t normlen; + int c; + + nfkdi = utf8nfkdi(utf8version); + /* Failure to normalize is treated as a blob. */ + if ((normlen = utf8nlen(nfkdi, (const char *)args->name, + args->namelen)) < 0) + goto blob; + if (utf8ncursor(&u8c, nfkdi, (const char *)args->name, + args->namelen) < 0) + goto blob; + if (!(norm = kmem_alloc(normlen + 1, KM_NOFS|KM_MAYFAIL))) + return ENOMEM; + args->norm = norm; + args->normlen = normlen; + while ((c = utf8byte(&u8c)) > 0) + *norm++ = c; + if (c == 0) { + *norm = '\0'; + args->hashval = xfs_da_hashname(args->norm, args->normlen); + return 0; + } + kmem_free((void *)args->norm); +blob: + args->norm = NULL; + args->normlen = -1; + args->hashval = xfs_da_hashname(args->name, args->namelen); + return 0; +} + +static enum xfs_dacmp +xfs_utf8_compname( + struct xfs_da_args *args, + const unsigned char *name, + int len) +{ + utf8data_t nfkdi; + struct utf8cursor u8c; + const char *norm; + int c; + + ASSERT(args->norm || args->normlen == -1); + + /* Check for an exact match first. */ + if (args->namelen == len && memcmp(args->name, name, len) == 0) + return XFS_CMP_EXACT; + /* xfs_utf8_normhash() set args->normlen to -1 for a blob */ + if (args->normlen < 0) + return XFS_CMP_DIFFERENT; + nfkdi = utf8nfkdi(utf8version); + if (utf8ncursor(&u8c, nfkdi, (const char *)name, len) < 0) + return XFS_CMP_DIFFERENT; + norm = (const char *)args->norm; + while ((c = utf8byte(&u8c)) > 0) + if (c != *norm++) + return XFS_CMP_DIFFERENT; + if (c < 0 || *norm != '\0') + return XFS_CMP_DIFFERENT; + return XFS_CMP_MATCH; +} + +struct xfs_nameops xfs_utf8_nameops = { + .hashname = xfs_utf8_hashname, + .normhash = xfs_utf8_normhash, + .compname = xfs_utf8_compname, +}; + +/* + * xfs nameops using nfkdicf + */ + +static xfs_dahash_t +xfs_utf8_ci_hashname( + const unsigned char *name, + int len) +{ + utf8data_t nfkdicf; + struct utf8cursor u8c; + xfs_dahash_t hash; + int val; + + nfkdicf = utf8nfkdicf(utf8version); + hash = 0; + if (utf8ncursor(&u8c, nfkdicf, (const char *)name, len) < 0) + goto blob; + while ((val = utf8byte(&u8c)) > 0) + hash = val ^ rol32(hash, 7); + /* In case of error treat the name as a binary blob. */ + if (val == 0) + return hash; +blob: + return xfs_da_hashname(name, len); +} + +static int +xfs_utf8_ci_normhash( + struct xfs_da_args *args) +{ + utf8data_t nfkdicf; + struct utf8cursor u8c; + unsigned char *norm; + ssize_t normlen; + int c; + + nfkdicf = utf8nfkdicf(utf8version); + /* Failure to normalize is treated as a blob. */ + if ((normlen = utf8nlen(nfkdicf, (const char *)args->name, + args->namelen)) < 0) + goto blob; + if (utf8ncursor(&u8c, nfkdicf, (const char *)args->name, + args->namelen) < 0) + goto blob; + if (!(norm = kmem_alloc(normlen + 1, KM_NOFS|KM_MAYFAIL))) + return ENOMEM; + args->norm = norm; + args->normlen = normlen; + while ((c = utf8byte(&u8c)) > 0) + *norm++ = c; + if (c == 0) { + *norm = '\0'; + args->hashval = xfs_da_hashname(args->norm, args->normlen); + return 0; + } + kmem_free((void *)args->norm); +blob: + args->norm = NULL; + args->normlen = -1; + args->hashval = xfs_da_hashname(args->name, args->namelen); + return 0; +} + +static enum xfs_dacmp +xfs_utf8_ci_compname( + struct xfs_da_args *args, + const unsigned char *name, + int len) +{ + utf8data_t nfkdicf; + struct utf8cursor u8c; + const unsigned char *norm; + int c; + + ASSERT(args->norm || args->normlen == -1); + + /* Check for an exact match first. */ + if (args->namelen == len && memcmp(args->name, name, len) == 0) + return XFS_CMP_EXACT; + /* xfs_utf8_ci_normhash() set args->normlen to -1 for a blob */ + if (args->normlen < 0) + return XFS_CMP_DIFFERENT; + nfkdicf = utf8nfkdicf(utf8version); + if (utf8ncursor(&u8c, nfkdicf, (const char *)name, len) < 0) + return XFS_CMP_DIFFERENT; + norm = args->norm; + while ((c = utf8byte(&u8c)) > 0) + if (c != *norm++) + return XFS_CMP_DIFFERENT; + if (c < 0 || *norm != '\0') + return XFS_CMP_DIFFERENT; + return XFS_CMP_MATCH; +} + +struct xfs_nameops xfs_utf8_ci_nameops = { + .hashname = xfs_utf8_ci_hashname, + .normhash = xfs_utf8_ci_normhash, + .compname = xfs_utf8_ci_compname, +}; diff --git a/support/Makefile b/support/Makefile new file mode 100644 index 0000000..cade5fe --- /dev/null +++ b/support/Makefile @@ -0,0 +1,24 @@ +# +# Copyright (c) 2014 SGI. All Rights Reserved. +# + +TOPDIR = .. +include $(TOPDIR)/include/builddefs + +default = ../include/utf8data.h + +../include/utf8data.h: mkutf8data.c + cc -o mkutf8data mkutf8data.c + cd ucd-7.0.0 ; ../mkutf8data + mv ucd-7.0.0/utf8data.h ../include + +default clean: + rm -f mkutf8data ../include/utf8data.h + +default install: + +default install-dev: + +default install-qa: + +-include .ltdep -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 16:01:07 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C3D227F9C for ; Thu, 11 Sep 2014 16:01:07 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id A18A68F8037; Thu, 11 Sep 2014 14:01:04 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 66BAB4266DC; Thu, 11 Sep 2014 16:01:04 -0500 (CDT) Date: Thu, 11 Sep 2014 16:01:04 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 09/13] libxfs: apply utf-8 normalization rules to user extended attribute names Message-ID: <20140911210104.GR13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Apply the same rules for UTF-8 normalization to the names of user-defined extended attributes. System attributes are excluded because they are not user-visible in the first place, and the kernel is expected to know what it is doing when naming them. Signed-off-by: Olaf Weber --- libxfs/xfs_attr.c | 49 +++++++++++++++++++++++++++++++++++++++++-------- libxfs/xfs_attr_leaf.c | 11 +++++++++-- libxfs/xfs_utf8.c | 7 +++++++ 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c index 17519d3..c30703b 100644 --- a/libxfs/xfs_attr.c +++ b/libxfs/xfs_attr.c @@ -88,8 +88,9 @@ xfs_attr_get_int( int *valuelenp, int flags) { - xfs_da_args_t args; - int error; + xfs_da_args_t args; + struct xfs_mount *mp = ip->i_mount; + int error; if (!xfs_inode_hasattr(ip)) return ENOATTR; @@ -103,9 +104,12 @@ xfs_attr_get_int( args.value = value; args.valuelen = *valuelenp; args.flags = flags; - args.hashval = xfs_da_hashname(args.name, args.namelen); args.dp = ip; args.whichfork = XFS_ATTR_FORK; + if (! xfs_sb_version_hasutf8(&mp->m_sb)) + args.hashval = xfs_da_hashname(args.name, args.namelen); + else if ((error = mp->m_dirnameops->normhash(&args)) != 0) + return error; /* * Decide on what work routines to call based on the inode size. @@ -118,6 +122,9 @@ xfs_attr_get_int( error = xfs_attr_node_get(&args); } + if (args.norm) + kmem_free((void *)args.norm); + /* * Return the number of bytes in the value to the caller. */ @@ -239,12 +246,15 @@ xfs_attr_set_int( args.value = value; args.valuelen = valuelen; args.flags = flags; - args.hashval = xfs_da_hashname(args.name, args.namelen); args.dp = dp; args.firstblock = &firstblock; args.flist = &flist; args.whichfork = XFS_ATTR_FORK; args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; + if (! xfs_sb_version_hasutf8(&mp->m_sb)) + args.hashval = xfs_da_hashname(args.name, args.namelen); + else if ((error = mp->m_dirnameops->normhash(&args)) != 0) + return error; /* Size is now blocks for attribute data */ args.total = xfs_attr_calc_size(dp, name->len, valuelen, &local); @@ -276,6 +286,8 @@ xfs_attr_set_int( error = xfs_trans_reserve(args.trans, &tres, args.total, 0); if (error) { xfs_trans_cancel(args.trans, 0); + if (args.norm) + kmem_free((void *)args.norm); return(error); } xfs_ilock(dp, XFS_ILOCK_EXCL); @@ -286,6 +298,8 @@ xfs_attr_set_int( if (error) { xfs_iunlock(dp, XFS_ILOCK_EXCL); xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES); + if (args.norm) + kmem_free((void *)args.norm); return (error); } @@ -333,7 +347,8 @@ xfs_attr_set_int( err2 = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); - + if (args.norm) + kmem_free((void *)args.norm); return(error == 0 ? err2 : error); } @@ -398,6 +413,8 @@ xfs_attr_set_int( xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE); error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (args.norm) + kmem_free((void *)args.norm); return(error); @@ -406,6 +423,9 @@ out: xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (args.norm) + kmem_free((void *)args.norm); + return(error); } @@ -452,12 +472,15 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) args.name = name->name; args.namelen = name->len; args.flags = flags; - args.hashval = xfs_da_hashname(args.name, args.namelen); args.dp = dp; args.firstblock = &firstblock; args.flist = &flist; args.total = 0; args.whichfork = XFS_ATTR_FORK; + if (! xfs_sb_version_hasutf8(&mp->m_sb)) + args.hashval = xfs_da_hashname(args.name, args.namelen); + else if ((error = mp->m_dirnameops->normhash(&args)) != 0) + return error; /* * we have no control over the attribute names that userspace passes us @@ -470,8 +493,11 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) * Attach the dquots to the inode. */ error = xfs_qm_dqattach(dp, 0); - if (error) - return error; + if (error) { + if (args.norm) + kmem_free((void *)args.norm); + return error; + } /* * Start our first transaction of the day. @@ -497,6 +523,8 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) XFS_ATTRRM_SPACE_RES(mp), 0); if (error) { xfs_trans_cancel(args.trans, 0); + if (args.norm) + kmem_free((void *)args.norm); return(error); } @@ -546,6 +574,8 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE); error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (args.norm) + kmem_free((void *)args.norm); return(error); @@ -554,6 +584,9 @@ out: xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (args.norm) + kmem_free((void *)args.norm); + return(error); } diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c index f7f02ae..052a6a1 100644 --- a/libxfs/xfs_attr_leaf.c +++ b/libxfs/xfs_attr_leaf.c @@ -634,6 +634,7 @@ int xfs_attr_shortform_to_leaf(xfs_da_args_t *args) { xfs_inode_t *dp; + struct xfs_mount *mp; xfs_attr_shortform_t *sf; xfs_attr_sf_entry_t *sfe; xfs_da_args_t nargs; @@ -646,6 +647,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) trace_xfs_attr_sf_to_leaf(args); dp = args->dp; + mp = dp->i_mount; ifp = dp->i_afp; sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; size = be16_to_cpu(sf->hdr.totsize); @@ -698,13 +700,18 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) nargs.namelen = sfe->namelen; nargs.value = &sfe->nameval[nargs.namelen]; nargs.valuelen = sfe->valuelen; - nargs.hashval = xfs_da_hashname(sfe->nameval, - sfe->namelen); nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags); + if (! xfs_sb_version_hasutf8(&mp->m_sb)) + nargs.hashval = xfs_da_hashname(sfe->nameval, + sfe->namelen); + else if ((error = mp->m_dirnameops->normhash(&nargs)) != 0) + goto out; error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */ ASSERT(error == ENOATTR); error = xfs_attr3_leaf_add(bp, &nargs); ASSERT(error != ENOSPC); + if (nargs.norm) + kmem_free((void *)nargs.norm); if (error) goto out; sfe = XFS_ATTR_SF_NEXTENTRY(sfe); diff --git a/libxfs/xfs_utf8.c b/libxfs/xfs_utf8.c index f5cc231..5c69591 100644 --- a/libxfs/xfs_utf8.c +++ b/libxfs/xfs_utf8.c @@ -31,6 +31,7 @@ #include "xfs_inode_fork.h" #include "xfs_bmap.h" #include "xfs_dir2.h" +#include "xfs_attr_leaf.h" #include "xfs_trace.h" #include "xfs_utf8.h" #include "utf8norm.h" @@ -72,6 +73,9 @@ xfs_utf8_normhash( ssize_t normlen; int c; + /* Don't normalize system attribute names. */ + if (args->flags & (ATTR_ROOT|ATTR_SECURE)) + goto blob; nfkdi = utf8nfkdi(utf8version); /* Failure to normalize is treated as a blob. */ if ((normlen = utf8nlen(nfkdi, (const char *)args->name, @@ -173,6 +177,9 @@ xfs_utf8_ci_normhash( ssize_t normlen; int c; + /* Don't normalize system attribute names. */ + if (args->flags & (ATTR_ROOT|ATTR_SECURE)) + goto blob; nfkdicf = utf8nfkdicf(utf8version); /* Failure to normalize is treated as a blob. */ if ((normlen = utf8nlen(nfkdicf, (const char *)args->name, -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 16:02:54 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id CF3547F9C for ; Thu, 11 Sep 2014 16:02:54 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id B53AE8F8037; Thu, 11 Sep 2014 14:02:54 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 86E884266DC; Thu, 11 Sep 2014 16:02:54 -0500 (CDT) Date: Thu, 11 Sep 2014 16:02:54 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: tinguely@sgi.com, olaf@sgi.com Subject: [PATCH 10/13] xfsprogs: add utf8 support to growfs Message-ID: <20140911210254.GS13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Mark Tinguely Add utf-8 to xfs_growfs and xfs_info. Signed-off-by: Mark Tinguely --- growfs/xfs_growfs.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/growfs/xfs_growfs.c b/growfs/xfs_growfs.c index 8e611b6..6c41803 100644 --- a/growfs/xfs_growfs.c +++ b/growfs/xfs_growfs.c @@ -57,7 +57,8 @@ report_info( int crcs_enabled, int cimode, int ftype_enabled, - int finobt_enabled) + int finobt_enabled, + int utf8) { printf(_( "meta-data=%-22s isize=%-6u agcount=%u, agsize=%u blks\n" @@ -65,7 +66,7 @@ report_info( " =%-22s crc=%-8u finobt=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" - "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" + "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d utf8=%d\n" "log =%-22s bsize=%-6u blocks=%u, version=%u\n" " =%-22s sectsz=%-5u sunit=%u blks, lazy-count=%u\n" "realtime =%-22s extsz=%-6u blocks=%llu, rtextents=%llu\n"), @@ -76,7 +77,7 @@ report_info( "", geo.blocksize, (unsigned long long)geo.datablocks, geo.imaxpct, "", geo.sunit, geo.swidth, - dirversion, geo.dirblocksize, cimode, ftype_enabled, + dirversion, geo.dirblocksize, cimode, ftype_enabled, utf8, isint ? _("internal") : logname ? logname : _("external"), geo.blocksize, geo.logblocks, logversion, "", geo.logsectsize, geo.logsunit / geo.blocksize, lazycount, @@ -114,6 +115,7 @@ main(int argc, char **argv) long long rsize; /* new rt size in fs blocks */ int ci; /* ASCII case-insensitive fs */ int lazycount; /* lazy superblock counters */ + int utf8; /* Unicode chars supported */ int xflag; /* -x flag */ char *fname; /* mount point name */ char *datadev; /* data device name */ @@ -247,11 +249,12 @@ main(int argc, char **argv) crcs_enabled = geo.flags & XFS_FSOP_GEOM_FLAGS_V5SB ? 1 : 0; ftype_enabled = geo.flags & XFS_FSOP_GEOM_FLAGS_FTYPE ? 1 : 0; finobt_enabled = geo.flags & XFS_FSOP_GEOM_FLAGS_FINOBT ? 1 : 0; + utf8 = geo.flags & XFS_FSOP_GEOM_FLAGS_UTF8 ? 1 : 0; if (nflag) { report_info(geo, datadev, isint, logdev, rtdev, lazycount, dirversion, logversion, attrversion, projid32bit, crcs_enabled, ci, - ftype_enabled, finobt_enabled); + ftype_enabled, finobt_enabled, utf8); exit(0); } @@ -289,7 +292,7 @@ main(int argc, char **argv) report_info(geo, datadev, isint, logdev, rtdev, lazycount, dirversion, logversion, attrversion, projid32bit, crcs_enabled, ci, ftype_enabled, - finobt_enabled); + finobt_enabled, utf8); ddsize = xi.dsize; dlsize = ( xi.logBBsize? xi.logBBsize : -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 16:03:47 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E04307FAA for ; Thu, 11 Sep 2014 16:03:46 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id 63CE8AC001; Thu, 11 Sep 2014 14:03:43 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 148E54266DC; Thu, 11 Sep 2014 16:03:43 -0500 (CDT) Date: Thu, 11 Sep 2014 16:03:43 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: tinguely@sgi.com, olaf@sgi.com Subject: [PATCH 11/13] xfsprogs: add utf8 support to mkfs.xfs Message-ID: <20140911210343.GT13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Mark Tinguely Set the utf-8 feature bit. Signed-off-by: Mark Tinguely --- man/man8/mkfs.xfs.8 | 9 ++++++++- mkfs/xfs_mkfs.c | 27 ++++++++++++++++++++++----- mkfs/xfs_mkfs.h | 3 ++- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/man/man8/mkfs.xfs.8 b/man/man8/mkfs.xfs.8 index ad9ff3d..aa43cf5 100644 --- a/man/man8/mkfs.xfs.8 +++ b/man/man8/mkfs.xfs.8 @@ -558,7 +558,7 @@ any power of 2 size from the filesystem block size up to 65536. .IP The .B version=ci -option enables ASCII only case-insensitive filename lookup and version +option enables ASCII or UTF-8 case-insensitive filename lookup and version 2 directories. Filenames are case-preserving, that is, the names are stored in directories using the case they were created with. .IP @@ -582,6 +582,13 @@ When CRCs are enabled via the ftype functionality is always enabled. This feature can not be turned off for such filesystem configurations. .IP +.TP +.BI utf8[= value ] +This is used to enable the UTF-8 character set support. The +.I value +is either 0 or 1, with 1 signifying that UTF-8 character support is to be +enabled. If the value is omitted, 1 is assumed. +.IP .RE .TP .BI \-p " protofile" diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index c85258a..1829e51 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -149,6 +149,8 @@ char *nopts[] = { "version", #define N_FTYPE 3 "ftype", +#define N_UTF8 4 + "utf8", NULL, }; @@ -958,6 +960,7 @@ main( int nsflag; int nvflag; int nci; + int utf8; int Nflag; int discard = 1; char *p; @@ -1004,6 +1007,7 @@ main( logagno = logblocks = rtblocks = rtextblocks = 0; Nflag = nlflag = nsflag = nvflag = nci = 0; nftype = dirftype = 0; /* inode type information in the dir */ + utf8 = 0; /* utf-8 support */ dirblocklog = dirblocksize = 0; dirversion = XFS_DFL_DIR_VERSION; qflag = 0; @@ -1565,7 +1569,8 @@ _("cannot specify both crc and ftype\n")); if (nvflag) respec('n', nopts, N_VERSION); if (!strcasecmp(value, "ci")) { - nci = 1; /* ASCII CI mode */ + /* ASCII or UTF-8 CI mode */ + nci = 1; } else { dirversion = atoi(value); if (dirversion != 2) @@ -1587,6 +1592,14 @@ _("cannot specify both crc and ftype\n")); } nftype = 1; break; + case N_UTF8: + if (!value || *value == '\0') + value = "1"; + c = atoi(value); + if (c < 0 || c > 1) + illegal(value, "n utf8"); + utf8 = c; + break; default: unknown('n', value); } @@ -2460,7 +2473,8 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), */ sbp->sb_features2 = XFS_SB_VERSION2_MKFS(crcs_enabled, lazy_sb_counters, attrversion == 2, !projid16bit, 0, - (!crcs_enabled && dirftype)); + (!crcs_enabled && dirftype), + (!crcs_enabled && utf8)); sbp->sb_versionnum = XFS_SB_VERSION_MKFS(crcs_enabled, iaflag, dsunit != 0, logversion == 2, attrversion == 1, @@ -2534,6 +2548,9 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), if (crcs_enabled) { sbp->sb_features_incompat = XFS_SB_FEAT_INCOMPAT_FTYPE; dirftype = 1; + /* turn on the utf-8 support */ + if (utf8) + sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_UTF8; } if (!qflag || Nflag) { @@ -2543,7 +2560,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), " =%-22s crc=%-8u finobt=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" - "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" + "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d utf8=%d\n" "log =%-22s bsize=%-6d blocks=%lld, version=%d\n" " =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n" "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"), @@ -2552,7 +2569,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), "", crcs_enabled, finobt, "", blocksize, (long long)dblocks, imaxpct, "", dsunit, dswidth, - dirversion, dirblocksize, nci, dirftype, + dirversion, dirblocksize, nci, dirftype, utf8, logfile, 1 << blocklog, (long long)logblocks, logversion, "", lsectorsize, lsunit, lazy_sb_counters, rtfile, rtextblocks << blocklog, @@ -3171,7 +3188,7 @@ usage( void ) sunit=value|su=num,sectlog=n|sectsize=num,\n\ lazy-count=0|1]\n\ /* label */ [-L label (maximum 12 characters)]\n\ -/* naming */ [-n log=n|size=num,version=2|ci,ftype=0|1]\n\ +/* naming */ [-n log=n|size=num,version=2|ci,ftype=0|1,utf8=0|1]\n\ /* no-op info only */ [-N]\n\ /* prototype file */ [-p fname]\n\ /* quiet */ [-q]\n\ diff --git a/mkfs/xfs_mkfs.h b/mkfs/xfs_mkfs.h index 9df5f37..f40b284 100644 --- a/mkfs/xfs_mkfs.h +++ b/mkfs/xfs_mkfs.h @@ -37,13 +37,14 @@ 0 ) : XFS_SB_VERSION_1 ) #define XFS_SB_VERSION2_MKFS(crc, lazycount, attr2, projid32bit, parent, \ - ftype) (\ + ftype, utf8) (\ ((lazycount) ? XFS_SB_VERSION2_LAZYSBCOUNTBIT : 0) | \ ((attr2) ? XFS_SB_VERSION2_ATTR2BIT : 0) | \ ((projid32bit) ? XFS_SB_VERSION2_PROJID32BIT : 0) | \ ((parent) ? XFS_SB_VERSION2_PARENTBIT : 0) | \ ((crc) ? XFS_SB_VERSION2_CRCBIT : 0) | \ ((ftype) ? XFS_SB_VERSION2_FTYPE : 0) | \ + ((utf8) ? XFS_SB_VERSION2_UTF8BIT : 0) | \ 0 ) #define XFS_DFL_BLOCKSIZE_LOG 12 /* 4096 byte blocks */ -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 16:04:23 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD, T_FILL_THIS_FORM_SHORT autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 1650A7FA6 for ; Thu, 11 Sep 2014 16:04:23 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id E1D108F8037; Thu, 11 Sep 2014 14:04:22 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id A992C4266DC; Thu, 11 Sep 2014 16:04:22 -0500 (CDT) Date: Thu, 11 Sep 2014 16:04:22 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: tinguely@sgi.com, olaf@sgi.com Subject: [PATCH 12/13] xfsprogs: add utf8 support to xfs_repair Message-ID: <20140911210422.GU13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Mark Tinguely Fix the duplicate filename detection to use the utf-8 normalization routines. Signed-off-by: Mark Tinguely --- repair/phase6.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/repair/phase6.c b/repair/phase6.c index f374fd0..eb3ea35 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -176,13 +176,15 @@ dir_hash_add( unsigned char *name, __uint8_t ftype) { - xfs_dahash_t hash = 0; int byaddr; int byhash = 0; dir_hash_ent_t *p; int dup; short junk; struct xfs_name xname; + xfs_da_args_t args; + + memset(&args, 0, sizeof(xfs_da_args_t)); ASSERT(!hashtab->names_duped); @@ -195,19 +197,30 @@ dir_hash_add( dup = 0; if (!junk) { - hash = mp->m_dirnameops->hashname(name, namelen); - byhash = DIR_HASH_FUNC(hashtab, hash); + int error; + + args.name = name; + args.namelen = namelen; + args.inumber = inum; + args.whichfork = XFS_DATA_FORK; + + error = mp->m_dirnameops->normhash(&args); + if (error) + do_error(_("normalize has failed %d)\n"), error); + + byhash = DIR_HASH_FUNC(hashtab, args.hashval); /* * search hash bucket for existing name. */ for (p = hashtab->byhash[byhash]; p; p = p->nextbyhash) { - if (p->hashval == hash && p->name.len == namelen) { - if (memcmp(p->name.name, name, namelen) == 0) { - dup = 1; - junk = 1; - break; - } + if (p->hashval == args.hashval && + mp->m_dirnameops->compname(&args, p->name.name, + p->name.len) != + XFS_CMP_DIFFERENT) { + dup = 1; + junk = 1; + break; } } } @@ -226,7 +239,7 @@ dir_hash_add( hashtab->last = p; if (!(p->junkit = junk)) { - p->hashval = hash; + p->hashval = args.hashval; p->nextbyhash = hashtab->byhash[byhash]; hashtab->byhash[byhash] = p; } @@ -235,6 +248,8 @@ dir_hash_add( p->seen = 0; p->name = xname; + if (args.norm) + kmem_free((void *) args.norm); return !dup; } -- 1.7.12.4 From bpm@sgi.com Thu Sep 11 16:06:17 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id C0FA17FAC for ; Thu, 11 Sep 2014 16:06:17 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay2.corp.sgi.com (Postfix) with ESMTP id 90C94304043; Thu, 11 Sep 2014 14:06:17 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 40FF84266DC; Thu, 11 Sep 2014 16:06:17 -0500 (CDT) Date: Thu, 11 Sep 2014 16:06:17 -0500 From: Ben Myers To: xfs@oss.sgi.com Cc: tinguely@sgi.com, olaf@sgi.com Subject: [PATCH 13/13] xfsprogs: add a preliminary test for utf8 support Message-ID: <20140911210617.GV13262@sgi.com> References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Ben Myers Here's a preliminary test for utf8 support in xfs. It is based on Olaf's code that does some testing in the trie generator. Here too we are using the NormalizationTest.txt file from the unicode distribution. We check that the normalization in libxfs is working and then run checks on a filesystem. Note that there are some 'blacklisted' unichars which normalize to reserved characters. FIXME: For convenience of build this patch is against xfsprogs access to libxfs. Handling of ignorables and case fold is also not implemented here. --- Makefile | 2 +- chkutf8data/Makefile | 21 +++ chkutf8data/chkutf8data.c | 430 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 452 insertions(+), 1 deletion(-) create mode 100644 chkutf8data/Makefile create mode 100644 chkutf8data/chkutf8data.c diff --git a/Makefile b/Makefile index c442da6..d4c0a23 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ endif LIB_SUBDIRS = support libxfs libxlog libxcmd libhandle libdisk TOOL_SUBDIRS = copy db estimate fsck fsr growfs io logprint mkfs quota \ - mdrestore repair rtcp m4 man doc po debian + mdrestore repair rtcp m4 man doc po debian chkutf8data SUBDIRS = include $(LIB_SUBDIRS) $(TOOL_SUBDIRS) diff --git a/chkutf8data/Makefile b/chkutf8data/Makefile new file mode 100644 index 0000000..6ce5706 --- /dev/null +++ b/chkutf8data/Makefile @@ -0,0 +1,21 @@ +# +# Copyright (c) 2014 SGI. All Rights Reserved. +# + +TOPDIR = .. +include $(TOPDIR)/include/builddefs + +LTCOMMAND = chkutf8data +CFILES = chkutf8data.c + +LLDLIBS = $(LIBXFS) +LTDEPENDENCIES = $(LIBXFS) +LLDFLAGS = -static + +default: depend $(LTCOMMAND) + +include $(BUILDRULES) + +install: default + +-include .ltdep diff --git a/chkutf8data/chkutf8data.c b/chkutf8data/chkutf8data.c new file mode 100644 index 0000000..487cf1e --- /dev/null +++ b/chkutf8data/chkutf8data.c @@ -0,0 +1,430 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "utf8norm.h" + +#define FOLD_NAME "CaseFolding.txt" +#define TEST_NAME "NormalizationTest.txt" + +const char *fold_name = FOLD_NAME; +const char *test_name = TEST_NAME; + +/* An arbitrary line size limit on input lines. */ + +#define LINESIZE 1024 +char line[LINESIZE]; +char buf0[LINESIZE]; +char buf1[LINESIZE]; +char buf2[LINESIZE]; +char buf3[LINESIZE]; +char buf4[LINESIZE]; +char buf5[LINESIZE]; + +const char *mtpt; +int verbose = 0; + +/* ------------------------------------------------------------------ */ + +static void +help(void) +{ + printf("The input files:\n"); + printf("\t-f %s\n", FOLD_NAME); + printf("\t-t %s\n", TEST_NAME); + printf("\n\n"); + printf("\t-m mtpt\n"); + printf("\t-v (verbose)\n"); + printf("\t-h (help)\n"); + printf("\n"); +} + +static void +usage(void) +{ + help(); + exit(1); +} + +static void +open_fail(const char *name, int error) +{ + printf("Error %d opening %s: %s\n", error, name, strerror(error)); + exit(1); +} + +static void +file_fail(const char *filename) +{ + printf("Error parsing %s\n", filename); + exit(1); +} + +/* ------------------------------------------------------------------ */ + +/* + * UTF8 valid ranges. + * + * The UTF-8 encoding spreads the bits of a 32bit word over several + * bytes. This table gives the ranges that can be held and how they'd + * be represented. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000000 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000000 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * There is an additional requirement on UTF-8, in that only the + * shortest representation of a 32bit value is to be used. A decoder + * must not decode sequences that do not satisfy this requirement. + * Thus the allowed ranges have a lower bound. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000080 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000800 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00010000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00200000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x04000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Actual unicode characters are limited to the range 0x0 - 0x10FFFF, + * 17 planes of 65536 values. This limits the sequences actually seen + * even more, to just the following. + * + * 0 - 0x7f: 0 0x7f + * 0x80 - 0x7ff: 0xc2 0x80 0xdf 0xbf + * 0x800 - 0xffff: 0xe0 0xa0 0x80 0xef 0xbf 0xbf + * 0x10000 - 0x10ffff: 0xf0 0x90 0x80 0x80 0xf4 0x8f 0xbf 0xbf + * + * Even within those ranges not all values are allowed: the surrogates + * 0xd800 - 0xdfff should never be seen. + * + * Note that the longest sequence seen with valid usage is 4 bytes, + * the same a single UTF-32 character. This makes the UTF-8 + * representation of Unicode strictly smaller than UTF-32. + * + * The shortest sequence requirement was introduced by: + * Corrigendum #1: UTF-8 Shortest Form + * It can be found here: + * http://www.unicode.org/versions/corrigendum1.html + * + */ + +#define UTF8_2_BITS 0xC0 +#define UTF8_3_BITS 0xE0 +#define UTF8_4_BITS 0xF0 +#define UTF8_N_BITS 0x80 +#define UTF8_2_MASK 0xE0 +#define UTF8_3_MASK 0xF0 +#define UTF8_4_MASK 0xF8 +#define UTF8_N_MASK 0xC0 +#define UTF8_V_MASK 0x3F +#define UTF8_V_SHIFT 6 + +static int +utf8key(unsigned int key, char keyval[]) +{ + int keylen; + + if (key < 0x80) { + keyval[0] = key; + keylen = 1; + } else if (key < 0x800) { + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_2_BITS; + keylen = 2; + } else if (key < 0x10000) { + keyval[2] = key & UTF8_V_MASK; + keyval[2] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_3_BITS; + keylen = 3; + } else if (key < 0x110000) { + keyval[3] = key & UTF8_V_MASK; + keyval[3] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[2] = key & UTF8_V_MASK; + keyval[2] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_4_BITS; + keylen = 4; + } else { + printf("%#x: illegal key\n", key); + keylen = 0; + } + return keylen; +} + +static int +normalize_line(utf8data_t tree, char *s, char *t) +{ + struct utf8cursor u8c; + + if (utf8cursor(&u8c, tree, s)) { + printf("%s return utf8cursor failed\n", __func__); + return -1; + } + + while ((*t = utf8byte(&u8c)) > 0) + t++; + + if (*t < 0) { + printf("%s return error %d\r", __func__, *t); + return -1; + } + if (*t != 0) { + printf("%s return t not 0\n", __func__); + return -1; + } + + return 0; +} + +static void +test_key(char *source, + char *NFC, + char *NFD, + char *NFKC, + char *NFKD) +{ + int fd; + int error; + + if (verbose) + printf("Testing %s -> %s\n", source, NFKD); + + error = chdir(mtpt); /* XXX hardcoded mount point */ + if (error) { + perror(mtpt); + exit(-1); + } + + /* the initial create should succeed */ + if (verbose) + printf("Initial create %s... ", source); + fd = open(source, O_CREAT|O_EXCL, 0); + if (fd < 0) { + printf("Failed to create %s XXX\n", source); + perror(source); + close(fd); + exit(-1); + } + close(fd); + if (verbose) + printf("Success\n"); + + /* a second create should fail */ + if (verbose) + printf("Second create %s (should return EEXIST)... ", NFKD); + fd = open(NFKD, O_CREAT|O_EXCL, 0); + if (fd >= 1) { + printf("Test Failed. Was able to create %s XXX\n", NFKD); + perror(NFKD); + close(fd); + exit(-1); + } + close(fd); + if (verbose) + printf("EEXIST\n"); + + error = unlink(NFKD); + if (error) { + printf("Unlink failed\n"); + perror(NFKD); + exit(-1); + } +} + +int +blacklisted(unsigned int unichar) +{ + /* these unichars normalize to characters we don't allow */ + unsigned int list[] = { 0x2024 /* . */, + 0x2025 /* .. */, + 0x2100 /* a/c */, + 0x2101 /* a/s */, + 0x2105 /* c/o */, + 0x2106 /* c/u */, + 0xFE30 /* .. */, + 0xFE52 /* . */, + 0xFF0E /* . */, + 0xFF0F /* / */}; + int i; + + for (i=0; i < (sizeof(list) / sizeof(unichar)); i++) { + if (list[i] == unichar) + return 1; + } + return 0; +} + +static void +normalization_test(void) +{ + FILE *file; + unsigned int unichar; + char *s; + char *t; + int ret; + int tests = 0; + int failures = 0; + char source[LINESIZE]; + char NFKD[LINESIZE]; + int skip; + utf8data_t nfkdi = utf8nfkdi(utf8version); + + printf("Parsing %s\n", test_name); + /* Step one, read data from file. */ + file = fopen(test_name, "r"); + if (!file) + open_fail(test_name, errno); + + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%[^;];%*[^;];%*[^;];%*[^;];%[^;];", + source, NFKD); + //NFC, NFD, NFKC, NFKD); + if (ret != 2 || *line == '#') + continue; + + s = source; + t = buf2; + skip = 0; + while (*s) { + unichar = strtoul(s, &s, 16); + if (blacklisted(unichar)) + skip++; + t += utf8key(unichar, t); + } + *t = '\0'; + + if (skip) + continue; + + s = NFKD; + t = buf3; + while (*s) { + unichar = strtoul(s, &s, 16); + t += utf8key(unichar, t); + } + *t = '\0'; + + /* normalize source */ + if (normalize_line(nfkdi, buf2, buf4) < 0) { + printf("normalize_line for unichar %s Failed\n", buf0); + exit(1); + } + if (verbose) + printf("(%s) %s normalized to %s... ", + source, buf2, buf4); + + /* does it match NFKD? */ + tests++; + if (memcmp(buf4, buf3, strlen(buf3))) { + if (verbose) + printf("Fail!\n"); + failures++; + } else { + if (verbose) + printf("Correct!\n"); + } + + /* normalize NFKD */ + if (normalize_line(nfkdi, buf3, buf5) < 0) { + printf("normalize_line for unichar %s Failed\n", + buf3); + exit(1); + } + if (verbose) + printf("(%s) %s normalized to %s... ", + NFKD, buf3, buf5); + + /* does it normalize to itself? */ + tests++; + if (memcmp(buf5, buf3, strlen(buf3))) { + if (verbose) + printf("Fail!\n"); + failures++; + } else { + if (verbose) + printf("Correct!\n"); + } + + /* XXX ignorables need to be taken into account? */ + test_key(buf2, NULL, NULL, NULL, buf3); + } + fclose(file); + printf("Ran %d tests with %d failures\n", tests, failures); + if (failures) + file_fail(test_name); +} + +int +main(int argc, char *argv[]) +{ + int opt; + + while ((opt = getopt(argc, argv, "f:t:m:vh")) != -1) { + switch (opt) { + case 'f': + fold_name = optarg; + break; + case 't': + test_name = optarg; + break; + case 'm': + mtpt = optarg; + break; + case 'v': + verbose++; + break; + case 'h': + help(); + exit(0); + default: + usage(); + } + } + + if (!test_name || !mtpt) { + usage(); + exit(-1); + } + + normalization_test(); + + return 0; +} -- 1.7.12.4 From BATV+3a8580734ab415595e92+4036+infradead.org+hch@bombadil.srs.infradead.org Thu Sep 11 16:14:45 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 488B07FA8 for ; Thu, 11 Sep 2014 16:14:45 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 35368304032 for ; Thu, 11 Sep 2014 14:14:45 -0700 (PDT) X-ASG-Debug-ID: 1410470083-04cbb05485d1f4d0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id 3ufwUh6lXsmHKGGa (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 11 Sep 2014 14:14:43 -0700 (PDT) X-Barracuda-Envelope-From: BATV+3a8580734ab415595e92+4036+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XSBhT-000146-4D for xfs@oss.sgi.com; Thu, 11 Sep 2014 21:14:43 +0000 Date: Thu, 11 Sep 2014 14:14:43 -0700 From: Christoph Hellwig To: xfs@oss.sgi.com Subject: more pagecache invalidation issues? Message-ID: <20140911211443.GA2191@infradead.org> X-ASG-Orig-Subj: more pagecache invalidation issues? MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1410470083 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9380 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 I just hit this with Linus' tree from a day or two ago when running xfstests in my 64-bit x86 kvm VM: [ 1810.820601] ------------[ cut here ]------------ [ 1810.821730] kernel BUG at ../fs/xfs/xfs_aops.c:1373! [ 1810.822881] invalid opcode: 0000 [#1] SMP [ 1810.823177] Modules linked in: [ 1810.823177] CPU: 0 PID: 5324 Comm: 4980.fsstress.b Not tainted 3.17.0-rc4+ #266 [ 1810.823177] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007 [ 1810.823177] task: ffff88004fedc910 ti: ffff88000b340000 task.ti: ffff88000b340000 [ 1810.823177] RIP: 0010:[] [] __xfs_get_blocks+0x5cb/0x5d0 [ 1810.823177] RSP: 0018:ffff88000b343998 EFLAGS: 00010202 [ 1810.823177] RAX: ffff880079ddf580 RBX: 0000000000166000 RCX: ffff88004fedd0f8 [ 1810.823177] RDX: 0000000000000001 RSI: 0000000000000000 RDI: 0000000000000246 [ 1810.823177] RBP: ffff88000b343a38 R08: 0000000000000001 R09: 0000000000000000 [ 1810.823177] R10: 0000000000000000 R11: 00000000000785b0 R12: ffff88004863d9a0 [ 1810.823177] R13: ffff88004863d700 R14: ffff88000b343b50 R15: 0000000000000000 [ 1810.823177] FS: 00007ff4401c6700(0000) GS:ffff88007fc00000(0000) knlGS:0000000000000000 [ 1810.823177] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1810.823177] CR2: 00007ff4400c2008 CR3: 000000004fed3000 CR4: 00000000000006f0 [ 1810.823177] Stack: [ 1810.823177] ffff88000b343a18 0000000000005000 ffff88000b3439c8 ffff880000000000 [ 1810.823177] ffff880000000008 0000000000000166 000188004ff2e940 0000000000005000 [ 1810.823177] ffff88000b343a18 0000000100000202 000000000000015e ffffffffffffffff [ 1810.823177] Call Trace: [ 1810.823177] [] xfs_get_blocks_direct+0xf/0x20 [ 1810.823177] [] __blockdev_direct_IO+0x9ee/0x3340 [ 1810.823177] [] ? __xfs_get_blocks+0x5d0/0x5d0 [ 1810.823177] [] xfs_vm_direct_IO+0x130/0x150 [ 1810.823177] [] ? __xfs_get_blocks+0x5d0/0x5d0 [ 1810.823177] [] generic_file_read_iter+0x54a/0x610 [ 1810.823177] [] ? mark_held_locks+0x6a/0x90 [ 1810.823177] [] xfs_file_read_iter+0xf9/0x2b0 [ 1810.823177] [] ? might_fault+0x3e/0x90 [ 1810.823177] [] new_sync_read+0x79/0xb0 [ 1810.823177] [] vfs_read+0x9b/0x190 [ 1810.823177] [] SyS_read+0x51/0xc0 [ 1810.823177] [] system_call_fastpath+0x16/0x1b The BUG_ON is this one: if (imap.br_startblock == DELAYSTARTBLOCK) { BUG_ON(direct); if (create) { .. From david@fromorbit.com Thu Sep 11 16:19:21 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 1756B7FAF for ; Thu, 11 Sep 2014 16:19:21 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id F10A1304032 for ; Thu, 11 Sep 2014 14:19:20 -0700 (PDT) X-ASG-Debug-ID: 1410470357-04cbb05487d1f910001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id 0ni3leRYNiJt6X18 for ; Thu, 11 Sep 2014 14:19:18 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ArMqAFkRElR5LCtmPGdsb2JhbABfgw2BKoIshQepdQEBAQEBAQaYeIVqBAIBgRAXBQEBAQE4N4QDAQEBAwE6HCMFCwgDDgoJJQ8FJQMHGhOIOge+IQEXGIVkiVEHgy+BHQWdAJkvKy+CTwEBAQ Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail06.adl6.internode.on.net with ESMTP; 12 Sep 2014 06:49:17 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XSBlr-0003Yu-BP; Fri, 12 Sep 2014 07:19:15 +1000 Date: Fri, 12 Sep 2014 07:19:15 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc Message-ID: <20140911211915.GA4322@dastard> X-ASG-Orig-Subj: Re: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc References: <1410355231-50495-1-git-send-email-bfoster@redhat.com> <20140911044243.GA10111@dastard> <20140911152012.GB54638@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911152012.GB54638@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1410470358 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9380 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 11, 2014 at 11:20:13AM -0400, Brian Foster wrote: > On Thu, Sep 11, 2014 at 02:42:43PM +1000, Dave Chinner wrote: > > On Wed, Sep 10, 2014 at 09:20:26AM -0400, Brian Foster wrote: > > > Hi all, > > > > > > Here's v2 of the collapse clean up. We refactor a bit more via the > > > insertion of patch 3, otherwise it's similar to v1. This will see some > > > continued testing, but it survived ~500m fsx operations overnight. > > > > > > Brian > > > > I'm not sure about the invalidation patch now. On a 1k block size > > filesystem, generic/127 fails with: > > > > +ltp/fsx -q -l 262144 -o 65536 -S 191110531 -N 100000 -R -W fsx_std_nommap > > +collapse range: 1000 to 3000 > > +do_collapse_range: fallocate: Device or resource busy > > > > which indicates we had an invalidation failure. This is probably > > exposing some other bug, but I haven't had time to look into it yet > > so I don't know. > > > > Yeah, I can reproduce this as well, thanks. I think you're referring to > the xfs_free_file_space() patch (5/5)..? *nod* > FWIW, I don't see the problem > without that patch, so it appears that the full pagecache truncate is > still covering up a problem somewhere. I'll try to dig into it... It's likely that it is leaving a dirty buffer on the page beyond EOF as a result of the truncate zeroing the remainder of the page in memory. If I get a chance I'll look at it this afternoon, as this patchset also seems to be causing a marked increase in the number of fsstress failures due to stray delalloc blocks in files even on 4k block size filesystems (e.g. at unmount). Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Thu Sep 11 17:03:32 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E5F0C7FB1 for ; Thu, 11 Sep 2014 17:03:32 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id D47C88F8037 for ; Thu, 11 Sep 2014 15:03:29 -0700 (PDT) X-ASG-Debug-ID: 1410473003-04cb6c54fea4e920001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id rzL0hRORzdaGsOp0 for ; Thu, 11 Sep 2014 15:03:24 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Am9GAOAbElR5LCtmPGdsb2JhbABfgw2BKoIshQepdQEBAQEBAQaYeIVqAgIBAQGBEBcFAQEBATg3hAQBAQQ6HCMQCAMOCgklDwUlAwcaE4hBvg4BFxiFZIlRB4MvgR0Fhh6WYpkvKy+CTwEBAQ Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail06.adl6.internode.on.net with ESMTP; 12 Sep 2014 07:33:19 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XSCST-0003jE-7n; Fri, 12 Sep 2014 08:03:17 +1000 Date: Fri, 12 Sep 2014 08:03:17 +1000 From: Dave Chinner To: Christoph Hellwig Cc: xfs@oss.sgi.com Subject: Re: more pagecache invalidation issues? Message-ID: <20140911220317.GB4322@dastard> X-ASG-Orig-Subj: Re: more pagecache invalidation issues? References: <20140911211443.GA2191@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911211443.GA2191@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1410473003 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9381 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 11, 2014 at 02:14:43PM -0700, Christoph Hellwig wrote: > I just hit this with Linus' tree from a day or two ago when running > xfstests in my 64-bit x86 kvm VM: > > [ 1810.820601] ------------[ cut here ]------------ > [ 1810.821730] kernel BUG at ../fs/xfs/xfs_aops.c:1373! > [ 1810.822881] invalid opcode: 0000 [#1] SMP > [ 1810.823177] Modules linked in: > [ 1810.823177] CPU: 0 PID: 5324 Comm: 4980.fsstress.b Not tainted 3.17.0-rc4+ #266 > [ 1810.823177] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007 > [ 1810.823177] task: ffff88004fedc910 ti: ffff88000b340000 task.ti: ffff88000b340000 > [ 1810.823177] RIP: 0010:[] [] __xfs_get_blocks+0x5cb/0x5d0 > [ 1810.823177] RSP: 0018:ffff88000b343998 EFLAGS: 00010202 > [ 1810.823177] RAX: ffff880079ddf580 RBX: 0000000000166000 RCX: ffff88004fedd0f8 > [ 1810.823177] RDX: 0000000000000001 RSI: 0000000000000000 RDI: 0000000000000246 > [ 1810.823177] RBP: ffff88000b343a38 R08: 0000000000000001 R09: 0000000000000000 > [ 1810.823177] R10: 0000000000000000 R11: 00000000000785b0 R12: ffff88004863d9a0 > [ 1810.823177] R13: ffff88004863d700 R14: ffff88000b343b50 R15: 0000000000000000 > [ 1810.823177] FS: 00007ff4401c6700(0000) GS:ffff88007fc00000(0000) knlGS:0000000000000000 > [ 1810.823177] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > [ 1810.823177] CR2: 00007ff4400c2008 CR3: 000000004fed3000 CR4: 00000000000006f0 > [ 1810.823177] Stack: > [ 1810.823177] ffff88000b343a18 0000000000005000 ffff88000b3439c8 ffff880000000000 > [ 1810.823177] ffff880000000008 0000000000000166 000188004ff2e940 0000000000005000 > [ 1810.823177] ffff88000b343a18 0000000100000202 000000000000015e ffffffffffffffff > [ 1810.823177] Call Trace: > [ 1810.823177] [] xfs_get_blocks_direct+0xf/0x20 > [ 1810.823177] [] __blockdev_direct_IO+0x9ee/0x3340 > [ 1810.823177] [] ? __xfs_get_blocks+0x5d0/0x5d0 > [ 1810.823177] [] xfs_vm_direct_IO+0x130/0x150 > [ 1810.823177] [] ? __xfs_get_blocks+0x5d0/0x5d0 > [ 1810.823177] [] generic_file_read_iter+0x54a/0x610 > [ 1810.823177] [] ? mark_held_locks+0x6a/0x90 > [ 1810.823177] [] xfs_file_read_iter+0xf9/0x2b0 > [ 1810.823177] [] ? might_fault+0x3e/0x90 > [ 1810.823177] [] new_sync_read+0x79/0xb0 > [ 1810.823177] [] vfs_read+0x9b/0x190 > [ 1810.823177] [] SyS_read+0x51/0xc0 > [ 1810.823177] [] system_call_fastpath+0x16/0x1b > > The BUG_ON is this one: > > if (imap.br_startblock == DELAYSTARTBLOCK) { > BUG_ON(direct); > if (create) { > .. That's a symptom of the problem I've been chasing for the past *18 months*. Every time we fix another bunch of bufferhead coherency bugs, I hope that it goes away. It hasn't, and Brian's latest set of collapse_range fixes have made it substantially worse on my test machines. However, Brian has a simply test case we are discussing on #xfs right now that reproduces on of the issues, and again it looks like stray delalloc blocks and/or dirty buffers beyond EOF being the source of the problems. We're slowly fixing the problems we find, but the frequency of that bug being hit is increasing and decreasing as time goes on. But in reality we still haven't found the root cause because it's been so hard to reliably reproduce.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From eflorac@intellique.com Fri Sep 12 02:06:24 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 359E67FB3 for ; Fri, 12 Sep 2014 02:06:24 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 157AC8F8035 for ; Fri, 12 Sep 2014 00:06:21 -0700 (PDT) X-ASG-Debug-ID: 1410505574-04bdf010a09df950001-NocioJ Received: from smtp5-g21.free.fr (smtp5-g21.free.fr [212.27.42.5]) by cuda.sgi.com with ESMTP id 8RS39GFdggPdkA36 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 12 Sep 2014 00:06:16 -0700 (PDT) X-Barracuda-Envelope-From: eflorac@intellique.com X-Barracuda-Apparent-Source-IP: 212.27.42.5 Received: from galadriel.home (unknown [82.235.234.79]) by smtp5-g21.free.fr (Postfix) with ESMTP id 7E5AFD4802D; Fri, 12 Sep 2014 09:06:13 +0200 (CEST) Date: Fri, 12 Sep 2014 09:06:42 +0200 From: Emmanuel Florac To: Greg Freemyer Cc: Leslie Rhorer , Sean Caron , "xfs@oss.sgi.com" Subject: Re: Corrupted files Message-ID: <20140912090642.7f9b11a7@galadriel.home> X-ASG-Orig-Subj: Re: Corrupted files In-Reply-To: References: <540F1B01.3020700@mygrande.net> <20140909220645.GH20518@dastard> <540FA586.9090308@mygrande.net> <540FACAC.3010504@mygrande.net> <20140910163124.3d879432@harpe.intellique.com> Organization: Intellique X-Mailer: Claws Mail 3.10.0 (GTK+ 2.24.20; i486-slackware-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: smtp5-g21.free.fr[212.27.42.5] X-Barracuda-Start-Time: 1410505575 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9394 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Le Thu, 11 Sep 2014 09:24:04 -0400 vous =E9criviez: > Regardless, ignoring the summer of discontent, I find Seagate to be my > preferred drives. Nowadays I only buy HGST drives. The 3 TB aren't as reliable as the 1, 2, 4 and 6 TB, but generally speaking the failure rate is extremely low (an order of a few failures a year among several thousands units). --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From david@fromorbit.com Fri Sep 12 05:02:41 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 341C57FB5 for ; Fri, 12 Sep 2014 05:02:41 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id C4364AC001 for ; Fri, 12 Sep 2014 03:02:37 -0700 (PDT) X-ASG-Debug-ID: 1410516154-04bdf010979e6060001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id Zl90dMyRW0HhIE0U for ; Fri, 12 Sep 2014 03:02:35 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Anc/ADrDElR5LCtmPGdsb2JhbABfgw1TV4IsryEGUQEBHJYlgWWFawQCAYEPFwUBAQEBODeEAwEBAQMBOhwVDgULCAMOBAYJJQ8FJQMHBhQTiDoHvggBFxiFZIQEhHVYB4MvgR0Fhh6PYoI9hEWBYIpKinkCHIFuKy+BBgIeBoEjAQEB Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail05.adl6.internode.on.net with ESMTP; 12 Sep 2014 19:32:32 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XSNgU-0005Iu-E6; Fri, 12 Sep 2014 20:02:30 +1000 Date: Fri, 12 Sep 2014 20:02:30 +1000 From: Dave Chinner To: Ben Myers Cc: xfs@oss.sgi.com, tinguely@sgi.com, olaf@sgi.com Subject: Re: [RFC] Unicode/UTF-8 support for XFS Message-ID: <20140912100230.GB4267@dastard> X-ASG-Orig-Subj: Re: [RFC] Unicode/UTF-8 support for XFS References: <20140911203735.GA19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911203735.GA19952@sgi.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1410516154 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9398 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 11, 2014 at 03:37:35PM -0500, Ben Myers wrote: > Hi, > > I'm posting this RFC on Olaf's behalf, as he is busy with other projects. Ok, but I'd prefer to have Olaf discuss the finer points rather than have to play chinese whispers through you. :/ > First is a series of kernel patches, then a series of patches for > xfsprogs, and then a test. Seeing as this is something out of the blue (i.e. nobody has made a mention of this functionality in the past couple of years), I think we need to look at design and architecture first before spending any time commenting on the code. > Note that I have removed the unicode database files prior to posting due > to their large size. There are instructions on how to download them in > the relevant commit headers. Which leads to an interesting issue: these files do not have cryptographically verifiable signatures. How can I trust them? I can't even access unicode.org via https, so I can't even be certain that I'm downloading from the site I think I'm downloading from.... > Here are some notes of introduction from Olaf: > > ----------------------------------------------------------------------------- > Unicode/UTF-8 support for XFS > > So we had a customer request proper unicode support... > > Design notes. > > XFS uses byte strings for filenames, so UTF-8 is the expected format for > unicode filenames. This does raise the question what criteria a byte string > must meet to be UTF-8. We settled on the following: > - Valid unicode code points are 0..0x10FFFF, except that > - The surrogates 0xD800..0xDFFF are not valid code points, and > - Valid UTF-8 must be a shortest encoding of a valid unicode code point. > > In addition, U+0 (ASCII NUL, '\0') is used to terminate byte strings (and > is itself not part of the string). Moreover strings may be length-limited > in addition to being NUL-terminated (there is no such thing as an embedded > NUL in a length-limited string). > > Based on feedback on the earlier patches for unicode/UTF-8 support, we References, please. I don't recall any series discussion on this topic since Barry posted the unicode-CI patches back in 2008, and I doubt anyone remembers the details of those discussions.... > decided that a filename that does not match the above criteria should be > treated as a binary blob, as opposed to being rejected. To stress: if any > part of the string isn't valid UTF-8, then the entire string is treated > as a binary blob. This matters once normalization is considered. So we accept invalid unicode in filenames, but only after failing to parse them? Isn't this a potential vector for exploiting weaknesses in application filename handling? i.e. unprivileged user writes specially crafted invalid unicode filename to disk, setuid program tries to parse it, invalid sequence triggers a buffer overflow bug in setuid parser? > When comparing unicode strings for equality, normalization comes into play: > we must compare the normalized forms of strings, not just the raw sequences > of bytes. There are a number of defined normalization forms for unicode. > We decided on a variant of NFKD we call NFKDI. NFD was chosed over NFC, > because calculating NFC requires calculating NFD first, followed by an > additional step. NFKD was chosen over NFD because this makes filenames > that ought to be equal compare as equal. But are they really equal? Choosing *compatibility* decomposition over *canonical* decomposition means that compound characters and formatting distinctions don't affect the hash. i.e. "of'fi'ce", "o'ffi'ce" and "office" all hash and compare as the same name, but then they get stored on disk unnormalised. So they are the "same" in memory, but very different on disk. I note that the unicode spec says this for normalised forms (11.1): "A normalized string is guaranteed to be stable; that is, once normalized, a string is normalized according to all future versions of Unicode." So if we store normalised strings on disk, they are guaranteed to be compatible with all future versions of unicode and anything that goes to use them. So why wouldn't we store normalised forms on disk? As another point to note and discuss, from the unicode standard: "Normalization Forms KC and KD must not be blindly applied to arbitrary text. [...] It is best to think of these Normalization Forms as being like uppercase or lowercase mappings: useful in certain contexts for identifying core meanings, but also performing modifications to the text that may not always be appropriate." I'd consider file names to be mostly "arbitrary text" - we currently treat them as opaque blobs and don't try to interpret them (apart from '/' delimiters) and so they can contain arbitrary text.... > My favorite example is the ways > "office" can be spelled, when "fi" or "ffi" ligatures are used. NFKDI adds > one more step of NFKD, in that it eliminates the code points that have the > Default_Ignorable_Code_Point property from the comparison. These code > points are as a rule invisible, but might (or might not) be pulled in when > you copy/paste a string to be used as a filename. An example of these is > U+00AD SOFT HYPHEN, a code point that only shows up if a word is split > across lines. This extension does not appear to be specified by the unicode standard - this seems like a dangerous thing to do when considering compatibility with future unicode standards - we are not in the business of extend-and-embrace here. Anyway, what happens if a user actually wants a filename with a Default_Ignorable_Code_Point character in it? IMO, if cut-n-paste modifies the string being cut-n-pasted, then that's a bug in the cut-n-paste application. I'd much prefer we use a normalisation type that is defined by the standard than to invent a new one to work around problems that may not even exist. > If a filename is considered to be binary blob, comparison is based on a > simple binary match. Normalization does not apply to any part of a blob. See above: if we have unicode enabled, I think that we should reject invalid unicode in filenames at normalisation time. > The code uses ("leverages", in corp-speak) the existing infrastructure for > case-insensitive filenames. Like the CI code, the name used to create a > file is stored on disk, and returned in a lookup. When comparing filenames > the normalized forms of the names being compared are generated on the fly > from the non-normalized forms stored on disk. Again, why not store normalised forms on disk and avoid the need to generate normalised forms for dirents being read from disk every time they must be compared? > If the borgbit (the bit enabling legacy ASCII-based CI) is set in the > superblock, then case folding is added into the mix. This normalization > form we call NFKDICF. It allows for the creation of case-insensitive > filesystems with UTF-8 support. Different languages have different case folding rules e.g. the upper case character might be the same, but the lower case character is different (or vice versa). Where are the language specific case folding tables being stored? And speaking of language support, how does this interact with the kernel NLS subsystem? > ----------------------------------------------------------------------------- > Implementation notes. > > Strings are normalized using a trie that stores the relevant information. > The trie itself is part of the XFS module, and about 250kB in size. The > trie is not checked in: instead we add the source files from the Unicode > Character Database and a program that creates the header containing the > trie. This is rather unappealing. Distros would have to take this code size penalty if they decide one user needs that support. The other millions of users pay that cost even if they don't want it. And then there's validation - how are we supposed to validate that a 250k binary blob is correct and free of issues on every compiler and architecture that the kernel is built on? > The key for a lookup in the trie is a UTF-8 sequence. Each valid UTF-8 > sequence leads to a leaf. No invalid sequence does. This means that trie > lookups can be used to validate UTF-8 sequences, which why there is no > specialized code for the same purpose. > > The trie contains information for the version of unicode in which each > code point was defined. This matters because non-normalized strings are > stored on disk, and newer versions of unicode may introduce new normalized > forms. Ideally, the version of unicode used by the filesystem is stored in > the filesystem. > > The trie also accounts for corrections made in the past to normalizations. > This has little value today, because any newly created filesystem would be > using unicode version 7.0.0. It is included in order to show, not tell, > that such corrections can be handled if they are added in future revisions. And so back to the stability of normalised forms: if the normalised forms are stable and the trie encodes the version of codepoints, then the data in the leaves of the trie itself must be stable. i.e. even for future versions of the standards, all the leaves that are there now will be there in the future. What is valid unicode now will remain valid unicode. And given that, why do we need to carry the trie around in the compiled kernel? We have a perfectly good mechanism for storing large chunks of long-term stable metadata that we can access easily: in files. IOWs, the trie is really a property of the filesystem, not the kernel or userspace tools. If we ever want to update to a new version of unicode, we can compile a new trie and have mkfs write that into new filesystems, and maybe add an xfs-reapir function that allows migration to a new trie on an existing filesystem. But if we carry it in the kernel then there will be interesting issues with iupgrade/downgrade compatibility with new tries. Better to prevent those simply by havingthe trie be owned by the filesystem, not the kernel. Hence I think the trie should probably be stored on disk in the filesystem. It gets calculated and written by mkfs into file attached to the superblock, and the only code that needs to go into the kernel is the code needed to read it into memory and walk it. That means we don't need 3,000 lines of nasty trie generation code in the kernel, we don't bloat the kernel unnecessarily with abinary blob, we don't need to build code with data from unverifiable sources directly into the kernel, we can support different versions of unicode easily, and so on. > The algorithm used to calculate the sequences of bytes for the normalized > form of a UTF-8 string is tricky. The core is found in utf8byte(), with an > explanation in the preceeding comment. Precisely my point - it's nasty, tricky code, and getting it wrong is a potential security vulnerability. Exactly how are we expected to review >3,000 lines of unicode/utf-8 minutae without having to become unicode encoding experts? Cheers, Dave. -- Dave Chinner david@fromorbit.com From olaf@sgi.com Fri Sep 12 06:55:42 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 56A127FB7 for ; Fri, 12 Sep 2014 06:55:42 -0500 (CDT) Received: from xmail.sgi.com (pv-excas1-dc21.corp.sgi.com [137.38.106.7]) by relay2.corp.sgi.com (Postfix) with ESMTP id 3463930404E; Fri, 12 Sep 2014 04:55:39 -0700 (PDT) Received: from [144.253.208.66] (144.253.208.66) by xmail.sgi.com (137.38.106.6) with Microsoft SMTP Server (TLS) id 14.3.195.1; Fri, 12 Sep 2014 06:55:38 -0500 Message-ID: <5412DF37.9030005@sgi.com> Date: Fri, 12 Sep 2014 13:55:35 +0200 From: Olaf Weber Organization: SGI User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.0 MIME-Version: 1.0 To: Dave Chinner , Ben Myers CC: , Subject: Re: [RFC] Unicode/UTF-8 support for XFS References: <20140911203735.GA19952@sgi.com> <20140912100230.GB4267@dastard> In-Reply-To: <20140912100230.GB4267@dastard> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [144.253.208.66] On 12-09-14 12:02, Dave Chinner wrote: > On Thu, Sep 11, 2014 at 03:37:35PM -0500, Ben Myers wrote: >> Hi, >> >> I'm posting this RFC on Olaf's behalf, as he is busy with other projects. > > Ok, but I'd prefer to have Olaf discuss the finer points rather than > have to play chinese whispers through you. :/ > I am on this mailing list, and I am trying to follow along, but I do have other calls on my time. >> First is a series of kernel patches, then a series of patches for >> xfsprogs, and then a test. > > Seeing as this is something out of the blue (i.e. nobody has made a > mention of this functionality in the past couple of years), I think > we need to look at design and architecture first before spending any > time commenting on the code. > >> Note that I have removed the unicode database files prior to posting due >> to their large size. There are instructions on how to download them in >> the relevant commit headers. > > Which leads to an interesting issue: these files do not have > cryptographically verifiable signatures. How can I trust them? I > can't even access unicode.org via https, so I can't even be certain > that I'm downloading from the site I think I'm downloading from.... As Ben noted, the reason to not include them in these emails is their size: $ wc fs/xfs/support/ucd/* 1273 12288 68009 fs/xfs/support/ucd/CaseFolding-7.0.0.txt 1470 14166 98263 fs/xfs/support/ucd/DerivedAge-7.0.0.txt 2368 22320 145072 fs/xfs/support/ucd/DerivedCombiningClass-7.0.0.txt 10794 123871 899859 fs/xfs/support/ucd/DerivedCoreProperties-7.0.0.txt 50 318 2040 fs/xfs/support/ucd/NormalizationCorrections-7.0.0.txt 18635 332441 2457187 fs/xfs/support/ucd/NormalizationTest-7.0.0.txt 33 86 1364 fs/xfs/support/ucd/README 27268 120686 1509570 fs/xfs/support/ucd/UnicodeData-7.0.0.txt 61891 626176 5181364 total As for your remarks about cryptographic signatures, I'm not sure I see your point there. Just to be clear: the idea is to check the files in, as opposed to having to download them from unicode.org prior to compiling XFS. >> Here are some notes of introduction from Olaf: >> >> ----------------------------------------------------------------------------- >> Unicode/UTF-8 support for XFS >> >> So we had a customer request proper unicode support... >> >> Design notes. >> >> XFS uses byte strings for filenames, so UTF-8 is the expected format for >> unicode filenames. This does raise the question what criteria a byte string >> must meet to be UTF-8. We settled on the following: >> - Valid unicode code points are 0..0x10FFFF, except that >> - The surrogates 0xD800..0xDFFF are not valid code points, and >> - Valid UTF-8 must be a shortest encoding of a valid unicode code point. >> >> In addition, U+0 (ASCII NUL, '\0') is used to terminate byte strings (and >> is itself not part of the string). Moreover strings may be length-limited >> in addition to being NUL-terminated (there is no such thing as an embedded >> NUL in a length-limited string). >> >> Based on feedback on the earlier patches for unicode/UTF-8 support, we > > References, please. I don't recall any series discussion on this > topic since Barry posted the unicode-CI patches back in 2008, and I > doubt anyone remembers the details of those discussions.... I looked up those discussions in the archives. For example, here's Christoph about rejecting filenames if they're not well-formed unicode. http://marc.info/?l=linux-fsdevel&m=120876935526856&w=2 And Jamie Lokier making a similar point: http://oss.sgi.com/archives/xfs/2008-04/msg01263.html >> decided that a filename that does not match the above criteria should be >> treated as a binary blob, as opposed to being rejected. To stress: if any >> part of the string isn't valid UTF-8, then the entire string is treated >> as a binary blob. This matters once normalization is considered. > > So we accept invalid unicode in filenames, but only after failing to > parse them? Isn't this a potential vector for exploiting weaknesses > in application filename handling? i.e. unprivileged user writes > specially crafted invalid unicode filename to disk, setuid program > tries to parse it, invalid sequence triggers a buffer overflow bug > in setuid parser? > Yes, this means that userspace must be capable of handling filenames that are not well-formed UTF-8 and a whole slew of other edge cases. Same as today really. >> When comparing unicode strings for equality, normalization comes into play: >> we must compare the normalized forms of strings, not just the raw sequences >> of bytes. There are a number of defined normalization forms for unicode. >> We decided on a variant of NFKD we call NFKDI. NFD was chosed over NFC, >> because calculating NFC requires calculating NFD first, followed by an >> additional step. NFKD was chosen over NFD because this makes filenames >> that ought to be equal compare as equal. > > But are they really equal? > > Choosing *compatibility* decomposition over *canonical* > decomposition means that compound characters and formatting > distinctions don't affect the hash. i.e. "of'fi'ce", "o'ffi'ce" and > "office" all hash and compare as the same name, but then they get > stored on disk unnormalised. So they are the "same" in memory, but > very different on disk. > > I note that the unicode spec says this for normalised forms > (11.1): > > "A normalized string is guaranteed to be stable; that is, once > normalized, a string is normalized according to all future versions > of Unicode." Provided no unassigned codepoints are present in that string. > So if we store normalised strings on disk, they are guaranteed to > be compatible with all future versions of unicode and anything that > goes to use them. So why wouldn't we store normalised forms on disk? > Because, based what I read around the web, I expect a good deal of resistance to the idea that a filesystem will on a lookup of a file you just created return a name that is different-but-equivalent. Think of it as the equivalent of being case-preserving for a case-insensitive filesystem. An alternative would be to store each filename twice: both raw and normalized forms. > As another point to note and discuss, from the unicode standard: > > "Normalization Forms KC and KD must not be blindly applied to > arbitrary text. [...] It is best to think of these Normalization > Forms as being like uppercase or lowercase mappings: useful in > certain contexts for identifying core meanings, but also performing > modifications to the text that may not always be appropriate." > > I'd consider file names to be mostly "arbitrary text" - we currently > treat them as opaque blobs and don't try to interpret them (apart > from '/' delimiters) and so they can contain arbitrary text.... > My reading of this part of the unicode standard is that applying a compatibility normalization results in strings that materially differ from the originals, and no full equivalent of the original can be reconstructed from the normalized form. This makes it improper for a word processor to normalize to NFKC or NFKD before saving a file. For the same reason, it would not be proper to store the NFKD version of a filename on disk without some method to retrieve (an equivalent of) the original. >> My favorite example is the ways >> "office" can be spelled, when "fi" or "ffi" ligatures are used. NFKDI adds >> one more step of NFKD, in that it eliminates the code points that have the >> Default_Ignorable_Code_Point property from the comparison. These code >> points are as a rule invisible, but might (or might not) be pulled in when >> you copy/paste a string to be used as a filename. An example of these is >> U+00AD SOFT HYPHEN, a code point that only shows up if a word is split >> across lines. > > This extension does not appear to be specified by the unicode > standard - this seems like a dangerous thing to do when considering > compatibility with future unicode standards - we are not in the > business of extend-and-embrace here. Anyway, what happens if a > user actually wants a filename with a Default_Ignorable_Code_Point > character in it? Such a filename can be created, and since the raw form of the name is stored on disk, when the filename is read back the Default_Ignorable_Code_Point will still be there. It just doesn't count when comparing names for equality. > IMO, if cut-n-paste modifies the string being cut-n-pasted, then > that's a bug in the cut-n-paste application. I'd much prefer we use > a normalisation type that is defined by the standard than to invent > a new one to work around problems that may not even exist. > >> If a filename is considered to be binary blob, comparison is based on a >> simple binary match. Normalization does not apply to any part of a blob. > > See above: if we have unicode enabled, I think that we should reject > invalid unicode in filenames at normalisation time. > That was my original intent, which I abandoned based on the emails linked to above. >> The code uses ("leverages", in corp-speak) the existing infrastructure for >> case-insensitive filenames. Like the CI code, the name used to create a >> file is stored on disk, and returned in a lookup. When comparing filenames >> the normalized forms of the names being compared are generated on the fly >> from the non-normalized forms stored on disk. > > Again, why not store normalised forms on disk and avoid the need to > generate normalised forms for dirents being read from disk every > time they must be compared? > >> If the borgbit (the bit enabling legacy ASCII-based CI) is set in the >> superblock, then case folding is added into the mix. This normalization >> form we call NFKDICF. It allows for the creation of case-insensitive >> filesystems with UTF-8 support. > > Different languages have different case folding rules e.g. the upper > case character might be the same, but the lower case character is > different (or vice versa). Where are the language specific case > folding tables being stored? And speaking of language support, how > does this interact with the kernel NLS subsystem? I use a full case fold as per CaseFolding.txt to obtain a result that is consistent and (in my opinion) good enough. Since XFS has no nls mount options, there is no interaction with the NLS subsystem. >> ----------------------------------------------------------------------------- >> Implementation notes. >> >> Strings are normalized using a trie that stores the relevant information. >> The trie itself is part of the XFS module, and about 250kB in size. The >> trie is not checked in: instead we add the source files from the Unicode >> Character Database and a program that creates the header containing the >> trie. > > This is rather unappealing. Distros would have to take this code > size penalty if they decide one user needs that support. The other > millions of users pay that cost even if they don't want it. And > then there's validation - how are we supposed to validate that a > 250k binary blob is correct and free of issues on every compiler and > architecture that the kernel is built on? If your concern is that the generator might create bad blobs on some architectures, then there are ways around that: checksums, checking in a reference blob, or maybe something else. As for size in general, looking at the NLS support I do not consider it to be excessively big (as in, it is a bit less than 2 times the size of the largest NLS module). Obviously opinions can differ on this. >> The key for a lookup in the trie is a UTF-8 sequence. Each valid UTF-8 >> sequence leads to a leaf. No invalid sequence does. This means that trie >> lookups can be used to validate UTF-8 sequences, which why there is no >> specialized code for the same purpose. >> >> The trie contains information for the version of unicode in which each >> code point was defined. This matters because non-normalized strings are >> stored on disk, and newer versions of unicode may introduce new normalized >> forms. Ideally, the version of unicode used by the filesystem is stored in >> the filesystem. >> >> The trie also accounts for corrections made in the past to normalizations. >> This has little value today, because any newly created filesystem would be >> using unicode version 7.0.0. It is included in order to show, not tell, >> that such corrections can be handled if they are added in future revisions. > > And so back to the stability of normalised forms: if the normalised > forms are stable and the trie encodes the version of codepoints, > then the data in the leaves of the trie itself must be stable. i.e. > even for future versions of the standards, all the leaves that are > there now will be there in the future. What is valid unicode now > will remain valid unicode. The set of valid unicode code points is known and stable: 0..0x10FFFF minus 0xD800..0xDFFF. However, the set of assigned code points grows with each revision of the unicode standard. Note that there is an explicit limitation on the stability of normalized strings: they are stable if, and only if, no unassigned codepoints are present in the string. > And given that, why do we need to carry the trie around in the > compiled kernel? We have a perfectly good mechanism for storing > large chunks of long-term stable metadata that we can access easily: > in files. > > IOWs, the trie is really a property of the filesystem, not the > kernel or userspace tools. If we ever want to update to a new > version of unicode, we can compile a new trie and have mkfs write > that into new filesystems, and maybe add an xfs-reapir function that > allows migration to a new trie on an existing filesystem. But if we > carry it in the kernel then there will be interesting issues with > iupgrade/downgrade compatibility with new tries. Better to prevent > those simply by havingthe trie be owned by the filesystem, not the > kernel. > > Hence I think the trie should probably be stored on disk in the > filesystem. It gets calculated and written by mkfs into file > attached to the superblock, and the only code that needs to go into > the kernel is the code needed to read it into memory and walk it. > > That means we don't need 3,000 lines of nasty trie generation code > in the kernel, we don't bloat the kernel unnecessarily with abinary > blob, we don't need to build code with data from unverifiable > sources directly into the kernel, we can support different versions > of unicode easily, and so on. Storing the trie in the filesystem is certainly an option, as is making XFS UTF-8 support a config option. >> The algorithm used to calculate the sequences of bytes for the normalized >> form of a UTF-8 string is tricky. The core is found in utf8byte(), with an >> explanation in the preceeding comment. > > Precisely my point - it's nasty, tricky code, and getting it wrong > is a potential security vulnerability. Exactly how are we expected > to review >3,000 lines of unicode/utf-8 minutae without having to > become unicode encoding experts? The bits and pieces that are specific to unicode are smaller than that, much of the complication of the generator is due to the work required to reduce the size of the trie. The generator is included because we felt that offering a large binary blob for checkin would also run into resistance. Olaf -- Olaf Weber SGI Phone: +31(0)30-6696796 Veldzigt 2b Fax: +31(0)30-6696799 Technical Lead 3454 PW de Meern Vnet: 955-6796 Storage Software The Netherlands Email: olaf@sgi.com From zimer@zimer.nazwa.pl Fri Sep 12 09:42:39 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: * X-Spam-Status: No, score=2.0 required=5.0 tests=HK_SCAM_N4,SUBJ_ALL_CAPS, T_FILL_THIS_FORM_SHORT autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 313F17FB9 for ; Fri, 12 Sep 2014 09:42:39 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id C40F9AC002 for ; Fri, 12 Sep 2014 07:42:35 -0700 (PDT) X-ASG-Debug-ID: 1410532953-04bdf010979f2c40001-NocioJ Received: from abq116.rev.netart.pl (abq116.rev.netart.pl [77.55.42.116]) by cuda.sgi.com with ESMTP id VB7GiR1AtpPUIv28 for ; Fri, 12 Sep 2014 07:42:34 -0700 (PDT) X-Barracuda-Envelope-From: zimer@zimer.nazwa.pl X-Barracuda-Apparent-Source-IP: 77.55.42.116 Received: from zimer.nazwa.pl (unknown [85.128.142.49]) by zimer.nazwa.pl (Postfix) with ESMTP id 6C27B115ABEF for ; Fri, 12 Sep 2014 16:42:31 +0200 (CEST) Date: Fri, 12 Sep 2014 16:42:31 +0200 To: xfs@oss.sgi.com From: =?UTF-8?Q?Gerald_Dean?= Subject: =?UTF-8?Q?PART_TIME_OFFER_=21?= Message-ID: X-ASG-Orig-Subj: =?UTF-8?Q?PART_TIME_OFFER_=21?= X-Priority: 1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="us-ascii" X-HTTP-Posting-URI: http://photodiploma.com:80/mel.php X-HTTP-Client: 24.117.20.138 X-Barracuda-Connect: abq116.rev.netart.pl[77.55.42.116] X-Barracuda-Start-Time: 1410532953 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.64 X-Barracuda-Spam-Status: No, SCORE=1.64 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=SUBJ_ALL_CAPS, SUBJ_ALL_CAPS_2 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9404 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 SUBJ_ALL_CAPS Subject is all capitals 1.62 SUBJ_ALL_CAPS_2 SUBJ_ALL_CAPS_2 Hello,=20 Our Company is looking for an Organized, Motivated, and Proactive individua= l to fill the Personal Assistant position. The individual in this role will= be responsible for providing seamless personal support for a busy, high-pr= ofile executive. Conserves executive's time by maintaining calendars; arran= ging for activities and services; keeping information confidential. The ass= ignment will pay you S2500/_assignment of 2 assignment a week. Please reply= this email with the following information below to sign up : 1. Name :=20 2. Genders :=20 3 Physical Address :=20 4. City / State :=20 5. Zip~code :=20 6. Phone No. :=20 7. Email :=20 Upon your response we shall revert to you with more details. Thank you,=20 Nice regards, Gerald Dean From sandeen@sandeen.net Fri Sep 12 11:22:14 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 998887F3F for ; Fri, 12 Sep 2014 11:22:14 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7912530406A for ; Fri, 12 Sep 2014 09:22:10 -0700 (PDT) X-ASG-Debug-ID: 1410538929-04cb6c5500a7c000001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id XjBhZXmsZBDPYAEX for ; Fri, 12 Sep 2014 09:22:09 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 20B276372C76; Fri, 12 Sep 2014 11:22:09 -0500 (CDT) Message-ID: <54131DB9.9010307@sandeen.net> Date: Fri, 12 Sep 2014 11:22:17 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Eric Sandeen , xfs-oss Subject: Re: [PATCH V2] xfs_io: add mremap command References: <54111610.4080604@redhat.com> <5411171F.6010704@sandeen.net> X-ASG-Orig-Subj: Re: [PATCH V2] xfs_io: add mremap command In-Reply-To: <5411171F.6010704@sandeen.net> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410538929 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9407 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/10/14 10:29 PM, Eric Sandeen wrote: > This adds a simple mremap command to xfs_io. > > It does not take a start address; it uses the existing > start address, so the sized passed will be the new total > size of the mapping. > > Signed-off-by: Eric Sandeen > --- > +int > +mremap_f( > + int argc, > + char **argv) > +{ > + ssize_t new_length; > + void *new_addr; > + int flags = 0; > + int c; > + size_t blocksize, sectsize; > + Crap, and I just realized my mailer has started swapping tabs for spaces; my last several patches are probably corrupted this way. Grumble. -Eric From sandeen@sandeen.net Fri Sep 12 11:54:39 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 66B227FA5 for ; Fri, 12 Sep 2014 11:54:39 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 556978F8037 for ; Fri, 12 Sep 2014 09:54:35 -0700 (PDT) X-ASG-Debug-ID: 1410540874-04cb6c54fda7dcf0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id MNvuR7lnZVOAsteI for ; Fri, 12 Sep 2014 09:54:34 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 24EF06372C76; Fri, 12 Sep 2014 11:54:34 -0500 (CDT) Message-ID: <54132553.9090202@sandeen.net> Date: Fri, 12 Sep 2014 11:54:43 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Eric Sandeen , xfs-oss Subject: [PATCH V3] xfs_io: add mremap command References: <54111610.4080604@redhat.com> X-ASG-Orig-Subj: [PATCH V3] xfs_io: add mremap command In-Reply-To: <54111610.4080604@redhat.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410540874 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9408 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This adds a simple mremap command to xfs_io. It does not take a start address; it uses the existing start address, so the sized passed will be the new total size of the mapping. Signed-off-by: Eric Sandeen --- V2: fix stray line in help. - Why was it only visible after I sent V1... :/ V3: Unmangle whitespace, yay me! diff --git a/io/mmap.c b/io/mmap.c index ea7498f..565a541 100644 --- a/io/mmap.c +++ b/io/mmap.c @@ -29,6 +29,7 @@ static cmdinfo_t mread_cmd; static cmdinfo_t msync_cmd; static cmdinfo_t munmap_cmd; static cmdinfo_t mwrite_cmd; +static cmdinfo_t mremap_cmd; mmap_region_t *maptable; int mapcount; @@ -574,6 +575,66 @@ mwrite_f( return 0; } +static void +mremap_help(void) +{ + printf(_( +"\n" +" resizes the current memory mapping\n" +"\n" +" Examples:\n" +" 'mremap 8192' - resizes the current mapping to 8192 bytes.\n" +"\n" +" Resizes the mappping, growing or shrinking from the current size.\n" +" The default stored value is 'X', repeated to fill the range specified.\n" +" -f -- use the MREMAP_FIXED flag\n" +" -m -- use the MREMAP_MAYMOVE flag\n" +"\n")); +} + +int +mremap_f( + int argc, + char **argv) +{ + ssize_t new_length; + void *new_addr; + int flags = 0; + int c; + size_t blocksize, sectsize; + + while ((c = getopt(argc, argv, "fm")) != EOF) { + switch (c) { + case 'f': + flags = MREMAP_FIXED|MREMAP_MAYMOVE; + break; + case 'm': + flags = MREMAP_MAYMOVE; + break; + default: + return command_usage(&mremap_cmd); + } + } + + init_cvtnum(&blocksize, §size); + new_length = cvtnum(blocksize, sectsize, argv[optind]); + if (new_length < 0) { + printf(_("non-numeric offset argument -- %s\n"), + argv[optind]); + return 0; + } + + new_addr = mremap(mapping->addr, mapping->length, new_length, flags); + if (new_addr == MAP_FAILED) + perror("mremap"); + else { + mapping->addr = new_addr; + mapping->length = new_length; + } + + return 0; +} + void mmap_init(void) { @@ -628,9 +689,21 @@ mmap_init(void) _("writes data into a region in the current memory mapping"); mwrite_cmd.help = mwrite_help; + mremap_cmd.name = "mremap"; + mremap_cmd.altname = "mrm"; + mremap_cmd.cfunc = mremap_f; + mremap_cmd.argmin = 1; + mremap_cmd.argmax = 2; + mremap_cmd.flags = CMD_NOFILE_OK | CMD_FOREIGN_OK; + mremap_cmd.args = _("[-m|-f] newsize"); + mremap_cmd.oneline = + _("alters the size of the current memory mapping"); + mremap_cmd.help = mremap_help; + add_command(&mmap_cmd); add_command(&mread_cmd); add_command(&msync_cmd); add_command(&munmap_cmd); add_command(&mwrite_cmd); + add_command(&mremap_cmd); } diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index e1a3e1a..e40fbf9 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -501,6 +501,20 @@ See the .B mmap command. .TP +.BI "mremap [ \-f ] [ \-m ] " new_length +Changes the current mapping size to +.IR new_length . +Whether the mapping may be moved is controlled by the flags passed; +MREMAP_FIXED +.RB ( \-f ), +or MREMAP_MAYMOVE +.RB ( \-m ). +.TP +.B mrm +See the +.B mremap +command. +.TP .B munmap Unmaps the current memory mapping. .TP From jeffpc@josefsipek.net Fri Sep 12 12:45:38 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 3B0D57FA7 for ; Fri, 12 Sep 2014 12:45:38 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 296C0304051 for ; Fri, 12 Sep 2014 10:45:35 -0700 (PDT) X-ASG-Debug-ID: 1410543931-04cb6c54fda80c30001-NocioJ Received: from josefsipek.net (josefsipek.net [71.174.113.7]) by cuda.sgi.com with ESMTP id vG1GEfsYKKB8hEyD for ; Fri, 12 Sep 2014 10:45:31 -0700 (PDT) X-Barracuda-Envelope-From: jeffpc@josefsipek.net X-Barracuda-Apparent-Source-IP: 71.174.113.7 Received: from meili (ma.nexenta.com [50.201.33.114]) by josefsipek.net (Postfix) with ESMTPSA id 77E3455654; Fri, 12 Sep 2014 13:45:30 -0400 (EDT) Date: Fri, 12 Sep 2014 13:45:39 -0400 From: Josef 'Jeff' Sipek To: Dave Chinner Cc: Ben Myers , tinguely@sgi.com, olaf@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC] Unicode/UTF-8 support for XFS Message-ID: <20140912174538.GD978@meili> X-ASG-Orig-Subj: Re: [RFC] Unicode/UTF-8 support for XFS References: <20140911203735.GA19952@sgi.com> <20140912100230.GB4267@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140912100230.GB4267@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: josefsipek.net[71.174.113.7] X-Barracuda-Start-Time: 1410543931 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9409 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 12, 2014 at 08:02:30PM +1000, Dave Chinner wrote: > On Thu, Sep 11, 2014 at 03:37:35PM -0500, Ben Myers wrote: ... > > When comparing unicode strings for equality, normalization comes into play: > > we must compare the normalized forms of strings, not just the raw sequences > > of bytes. There are a number of defined normalization forms for unicode. > > We decided on a variant of NFKD we call NFKDI. NFD was chosed over NFC, > > because calculating NFC requires calculating NFD first, followed by an > > additional step. NFKD was chosen over NFD because this makes filenames > > that ought to be equal compare as equal. > > But are they really equal? > > Choosing *compatibility* decomposition over *canonical* > decomposition means that compound characters and formatting > distinctions don't affect the hash. i.e. "of'fi'ce", "o'ffi'ce" and > "office" all hash and compare as the same name, but then they get > stored on disk unnormalised. So they are the "same" in memory, but > very different on disk. > > I note that the unicode spec says this for normalised forms > (11.1): > > "A normalized string is guaranteed to be stable; that is, once > normalized, a string is normalized according to all future versions > of Unicode." > > So if we store normalised strings on disk, they are guaranteed to > be compatible with all future versions of unicode and anything that > goes to use them. So why wouldn't we store normalised forms on disk? I've had a very similar discussion about normalization in ZFS. Sadly, I can't find where it happened so I can't point you to it. One interesting point that I remember is that storing the original form may be less surprising to an application. Specifically, the name it reads back is the same it supplied during the creation. (Granted, if the file already exists, the application will read back the new form.) Just FWIW. Jeff. -- Only two things are infinite, the universe and human stupidity, and I'm not sure about the former. - Albert Einstein From sandeen@sandeen.net Fri Sep 12 14:29:49 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A25747FA9 for ; Fri, 12 Sep 2014 14:29:49 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 81D32304062 for ; Fri, 12 Sep 2014 12:29:46 -0700 (PDT) X-ASG-Debug-ID: 1410550185-04cbb05487d58650001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id vYUU3YmlWHjmn1uy for ; Fri, 12 Sep 2014 12:29:45 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id D73D96079775; Fri, 12 Sep 2014 14:29:44 -0500 (CDT) Message-ID: <541349B1.1070007@sandeen.net> Date: Fri, 12 Sep 2014 14:29:53 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Eric Sandeen , xfs-oss CC: Boris Ranto Subject: Re: [PATCH] xfs: test for shut down fs in xfs_dir_fsync() References: <535E8344.2070209@redhat.com> X-ASG-Orig-Subj: Re: [PATCH] xfs: test for shut down fs in xfs_dir_fsync() In-Reply-To: <535E8344.2070209@redhat.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410550185 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9411 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 4/28/14 11:35 AM, Eric Sandeen wrote: > Similar to xfs_file_fsync(), I think xfs_dir_fsync() needs > to test for a shut down fs, lest we go down paths we'll > never be able to complete; Boris reported that during some > stress tests he had threads stuck in xlog_cil_force_lsn > via xfs_dir_fsync(). (re-ping) So Dave, you fixed this with: So, you did solve the problem properly I guess, in commit ac983517ec5941da0c58cacdbad10a231dc4e001 Author: Dave Chinner Date: Wed May 7 08:05:50 2014 +1000 xfs: don't sleep in xlog_cil_force_lsn on shutdown But should my patch still go in, if only to be consistent with file_fsync() paths? -Eric From bfoster@redhat.com Fri Sep 12 14:51:35 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 38DCF7FAF for ; Fri, 12 Sep 2014 14:51:35 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id AF53CAC006 for ; Fri, 12 Sep 2014 12:51:34 -0700 (PDT) X-ASG-Debug-ID: 1410551492-04cbb05487d595b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id iimjezdL82A1xq6L (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 12 Sep 2014 12:51:33 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8CJpVrs030047 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 12 Sep 2014 15:51:31 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8CJpU5b021053; Fri, 12 Sep 2014 15:51:31 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 470051256F8; Fri, 12 Sep 2014 15:51:29 -0400 (EDT) Date: Fri, 12 Sep 2014 15:51:29 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc Message-ID: <20140912195128.GA42029@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc References: <1410355231-50495-1-git-send-email-bfoster@redhat.com> <20140911044243.GA10111@dastard> <20140911152012.GB54638@bfoster.bfoster> <20140911211915.GA4322@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140911211915.GA4322@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410551493 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Sep 12, 2014 at 07:19:15AM +1000, Dave Chinner wrote: > On Thu, Sep 11, 2014 at 11:20:13AM -0400, Brian Foster wrote: > > On Thu, Sep 11, 2014 at 02:42:43PM +1000, Dave Chinner wrote: > > > On Wed, Sep 10, 2014 at 09:20:26AM -0400, Brian Foster wrote: > > > > Hi all, > > > > > > > > Here's v2 of the collapse clean up. We refactor a bit more via the > > > > insertion of patch 3, otherwise it's similar to v1. This will see some > > > > continued testing, but it survived ~500m fsx operations overnight. > > > > > > > > Brian > > > > > > I'm not sure about the invalidation patch now. On a 1k block size > > > filesystem, generic/127 fails with: > > > > > > +ltp/fsx -q -l 262144 -o 65536 -S 191110531 -N 100000 -R -W fsx_std_nommap > > > +collapse range: 1000 to 3000 > > > +do_collapse_range: fallocate: Device or resource busy > > > > > > which indicates we had an invalidation failure. This is probably > > > exposing some other bug, but I haven't had time to look into it yet > > > so I don't know. > > > > > > > Yeah, I can reproduce this as well, thanks. I think you're referring to > > the xfs_free_file_space() patch (5/5)..? > > *nod* > > > FWIW, I don't see the problem > > without that patch, so it appears that the full pagecache truncate is > > still covering up a problem somewhere. I'll try to dig into it... > > It's likely that it is leaving a dirty buffer on the page beyond EOF > as a result of the truncate zeroing the remainder of the page in > memory. > > If I get a chance I'll look at it this afternoon, as this patchset > also seems to be causing a marked increase in the number of fsstress > failures due to stray delalloc blocks in files even on 4k block size > filesystems (e.g. at unmount). > I think I have a bit of an idea of what's going on here. I'm not sure that this one is post-eof delalloc related. For reference, here's the command that reproduces for me 100% of the time on a 1k block fs (derived from the fsx trace): xfs_io -fc "pwrite 185332 55756" \ -c "fcollapse 28672 40960" \ -c "pwrite 133228 63394" \ -c "fcollapse 0 4096" /mnt/file The first write extends the file to 241088 bytes and the first collapse targets a hole, but shrinks the file down to 200128 bytes. The last page offset of the file is now 196608 and with 1k blocks, eof falls within the last block of this page (e.g., within bh offsets 199680-200704). The second write falls just into the first block of this page. What I see occur on the final collapse is that the invalidate_inode_pages2_range() call in the collapse op fails due to finding a dirty page at offset 196608. We don't have a launder_page() callback, so this results in -EBUSY. Given the above, it seems like the filemap_write_and_wait_range() call should handle this. Digging further, what I see is one or two writepage()->xfs_cluster_write() sequences along the range of the previous write. xfs_convert_page() eventually attempts to handle page offset 196608 and breaks out at offset 197632 (the second bh in the page) near the top of the bh loop: ... if (!(PageUptodate(page) || buffer_uptodate(bh))) { done = 1; break; } ... I suspect the reason the page/buffer is in this particular state is due to the previous invalidation (collapse 1), which would have removed the page from the mapping. This seems reasonable to me since we only wrote into the first bytes of the page since the prior invalidation. The problem is that the page somehow has the following buffer_head state at the point of the EBUSY inval failure: invalidate_inode_pages2_range(648): state 0x29 block 84 size 1024 invalidate_inode_pages2_range(648): state 0x0 block 18446744073709551615 size 1024 invalidate_inode_pages2_range(648): state 0x0 block 18446744073709551615 size 1024 invalidate_inode_pages2_range(648): state 0x2b block 87 size 1024 The first block is BH_Uptodate|BH_Req|BH_Mapped. I read the next two as simply not up to date..? The last block is the same as the first plus BH_Dirty. This last block is offset 199680 and the previous write goes to 196622, so I'm not sure how this ends up dirty. I think the write path to this range of the file might be the spot to dig next... Brian P.S., As a datapoint from experimentation, this problem doesn't occur if I ensure that writepage() handles this particular page rather than xfs_convert_page(). I can do that by either jumping out of xfs_convert_page() sooner, before the page is set for writeback, or hacking xfs_start_page_writeback() to use __test_set_page_writeback() and keep the write tag such that write_cache_pages() can still find the page. This calls out an interesting bit of behavior in xfs_convert_page() since commit a49935f2: if we handle a part of a page, break and mark the page for writeback without handling the rest, we'll still clear the PAGECACHE_TAG_TOWRITE tag and writeback won't finish off the page during the current iteration (for WB_SYNC_ALL). It's not clear to me if this is contributing to the problem in this particular case, but it seems like an independent bug at the very least. Thoughts? > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Fri Sep 12 15:05:48 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id F1E2E7FB3 for ; Fri, 12 Sep 2014 15:05:47 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id C22BA304043 for ; Fri, 12 Sep 2014 13:05:44 -0700 (PDT) X-ASG-Debug-ID: 1410552340-04cb6c54fda87a00001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id SIB2W0wl3vZVxraO (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 12 Sep 2014 13:05:40 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8CK5cpA014079 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 12 Sep 2014 16:05:38 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8CK5bf8000971; Fri, 12 Sep 2014 16:05:38 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 7B61A1256F8; Fri, 12 Sep 2014 16:05:36 -0400 (EDT) Date: Fri, 12 Sep 2014 16:05:36 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc Message-ID: <20140912200536.GB42029@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc References: <1410355231-50495-1-git-send-email-bfoster@redhat.com> <20140911044243.GA10111@dastard> <20140911152012.GB54638@bfoster.bfoster> <20140911211915.GA4322@dastard> <20140912195128.GA42029@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140912195128.GA42029@bfoster.bfoster> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410552340 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Sep 12, 2014 at 03:51:29PM -0400, Brian Foster wrote: > On Fri, Sep 12, 2014 at 07:19:15AM +1000, Dave Chinner wrote: > > On Thu, Sep 11, 2014 at 11:20:13AM -0400, Brian Foster wrote: > > > On Thu, Sep 11, 2014 at 02:42:43PM +1000, Dave Chinner wrote: > > > > On Wed, Sep 10, 2014 at 09:20:26AM -0400, Brian Foster wrote: > > > > > Hi all, > > > > > > > > > > Here's v2 of the collapse clean up. We refactor a bit more via the > > > > > insertion of patch 3, otherwise it's similar to v1. This will see some > > > > > continued testing, but it survived ~500m fsx operations overnight. > > > > > > > > > > Brian > > > > > > > > I'm not sure about the invalidation patch now. On a 1k block size > > > > filesystem, generic/127 fails with: > > > > > > > > +ltp/fsx -q -l 262144 -o 65536 -S 191110531 -N 100000 -R -W fsx_std_nommap > > > > +collapse range: 1000 to 3000 > > > > +do_collapse_range: fallocate: Device or resource busy > > > > > > > > which indicates we had an invalidation failure. This is probably > > > > exposing some other bug, but I haven't had time to look into it yet > > > > so I don't know. > > > > > > > > > > Yeah, I can reproduce this as well, thanks. I think you're referring to > > > the xfs_free_file_space() patch (5/5)..? > > > > *nod* > > > > > FWIW, I don't see the problem > > > without that patch, so it appears that the full pagecache truncate is > > > still covering up a problem somewhere. I'll try to dig into it... > > > > It's likely that it is leaving a dirty buffer on the page beyond EOF > > as a result of the truncate zeroing the remainder of the page in > > memory. > > > > If I get a chance I'll look at it this afternoon, as this patchset > > also seems to be causing a marked increase in the number of fsstress > > failures due to stray delalloc blocks in files even on 4k block size > > filesystems (e.g. at unmount). > > > > I think I have a bit of an idea of what's going on here. I'm not sure > that this one is post-eof delalloc related. For reference, here's the > command that reproduces for me 100% of the time on a 1k block fs > (derived from the fsx trace): > > xfs_io -fc "pwrite 185332 55756" \ > -c "fcollapse 28672 40960" \ > -c "pwrite 133228 63394" \ > -c "fcollapse 0 4096" /mnt/file > > The first write extends the file to 241088 bytes and the first collapse > targets a hole, but shrinks the file down to 200128 bytes. The last page > offset of the file is now 196608 and with 1k blocks, eof falls within > the last block of this page (e.g., within bh offsets 199680-200704). The > second write falls just into the first block of this page. > > What I see occur on the final collapse is that the > invalidate_inode_pages2_range() call in the collapse op fails due to > finding a dirty page at offset 196608. We don't have a launder_page() > callback, so this results in -EBUSY. > > Given the above, it seems like the filemap_write_and_wait_range() call > should handle this. Digging further, what I see is one or two > writepage()->xfs_cluster_write() sequences along the range of the > previous write. xfs_convert_page() eventually attempts to handle page > offset 196608 and breaks out at offset 197632 (the second bh in the > page) near the top of the bh loop: > > ... > if (!(PageUptodate(page) || buffer_uptodate(bh))) { > done = 1; > break; > } > ... > > I suspect the reason the page/buffer is in this particular state is due > to the previous invalidation (collapse 1), which would have removed the > page from the mapping. This seems reasonable to me since we only wrote > into the first bytes of the page since the prior invalidation. The problem is > that the page somehow has the following buffer_head state at the point of the > EBUSY inval failure: > > invalidate_inode_pages2_range(648): state 0x29 block 84 size 1024 > invalidate_inode_pages2_range(648): state 0x0 block 18446744073709551615 size 1024 > invalidate_inode_pages2_range(648): state 0x0 block 18446744073709551615 size 1024 > invalidate_inode_pages2_range(648): state 0x2b block 87 size 1024 > > The first block is BH_Uptodate|BH_Req|BH_Mapped. I read the next two as > simply not up to date..? The last block is the same as the first plus > BH_Dirty. This last block is offset 199680 and the previous write goes > to 196622, so I'm not sure how this ends up dirty. I think the write > path to this range of the file might be the spot to dig next... > ... and it just hit me that truncate dirties the buffer. ;) So I'm wondering if we have something like the following sequence of events for this particular page: - first pwrite writes to complete page - first collapse: - flush - invalidate - truncate -> dirty last buffer of page - second pwrite writes to first buffer in page (dirty first buffer) - flush - xfs_convert_page() hits the first buffer, breaks out and causes the last buffer to be passed over due to the issue below - invalidate - finds dirty buffer, error! Brian > Brian > > P.S., As a datapoint from experimentation, this problem doesn't occur if > I ensure that writepage() handles this particular page rather than > xfs_convert_page(). I can do that by either jumping out of > xfs_convert_page() sooner, before the page is set for writeback, or > hacking xfs_start_page_writeback() to use __test_set_page_writeback() > and keep the write tag such that write_cache_pages() can still find the > page. This calls out an interesting bit of behavior in > xfs_convert_page() since commit a49935f2: if we handle a part of a > page, break and mark the page for writeback without handling the rest, > we'll still clear the PAGECACHE_TAG_TOWRITE tag and writeback won't > finish off the page during the current iteration (for WB_SYNC_ALL). > > It's not clear to me if this is contributing to the problem in this > particular case, but it seems like an independent bug at the very > least. Thoughts? > > > Cheers, > > > > Dave. > > -- > > Dave Chinner > > david@fromorbit.com > > > > _______________________________________________ > > xfs mailing list > > xfs@oss.sgi.com > > http://oss.sgi.com/mailman/listinfo/xfs > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From BATV+e480f420f953aa9743f7+4037+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 12 15:53:16 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id AD85C7FA7 for ; Fri, 12 Sep 2014 15:53:16 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8D5A78F8037 for ; Fri, 12 Sep 2014 13:53:13 -0700 (PDT) X-ASG-Debug-ID: 1410555192-04bdf010a0a07200001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id tHUzlx90MvPbClh9 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO); Fri, 12 Sep 2014 13:53:12 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e480f420f953aa9743f7+4037+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XSXqB-0004Tg-P7; Fri, 12 Sep 2014 20:53:11 +0000 Date: Fri, 12 Sep 2014 13:53:11 -0700 From: Christoph Hellwig To: Dave Chinner Cc: Ben Myers , tinguely@sgi.com, olaf@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC] Unicode/UTF-8 support for XFS Message-ID: <20140912205311.GA11717@infradead.org> X-ASG-Orig-Subj: Re: [RFC] Unicode/UTF-8 support for XFS References: <20140911203735.GA19952@sgi.com> <20140912100230.GB4267@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140912100230.GB4267@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1410555192 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9414 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Fri, Sep 12, 2014 at 08:02:30PM +1000, Dave Chinner wrote: > > Implementation notes. > > > > Strings are normalized using a trie that stores the relevant information. > > The trie itself is part of the XFS module, and about 250kB in size. The > > trie is not checked in: instead we add the source files from the Unicode > > Character Database and a program that creates the header containing the > > trie. > > This is rather unappealing. Distros would have to take this code > size penalty if they decide one user needs that support. The other > millions of users pay that cost even if they don't want it. And > then there's validation - how are we supposed to validate that a > 250k binary blob is correct and free of issues on every compiler and > architecture that the kernel is built on? The way this needs to be done is to have a separate module for the tables, which XFS or other users then can symbol_get if and only if a mount requires it. The unicode tables should defintively be outside of fs/xfs. And please run this past lkml or -fsdevel, as people who actually understand unicode and related issues are much more likely to be found there than on the XFS list. From BATV+e480f420f953aa9743f7+4037+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 12 15:55:30 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 970D77FA7 for ; Fri, 12 Sep 2014 15:55:30 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7AFBB30405F for ; Fri, 12 Sep 2014 13:55:30 -0700 (PDT) X-ASG-Debug-ID: 1410555328-04cbb05485d5c2a0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id FT3pbPO5zu5EsgYz (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO); Fri, 12 Sep 2014 13:55:29 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e480f420f953aa9743f7+4037+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XSXsO-00061W-Mt; Fri, 12 Sep 2014 20:55:28 +0000 Date: Fri, 12 Sep 2014 13:55:28 -0700 From: Christoph Hellwig To: Olaf Weber Cc: Dave Chinner , Ben Myers , tinguely@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC] Unicode/UTF-8 support for XFS Message-ID: <20140912205528.GB11717@infradead.org> X-ASG-Orig-Subj: Re: [RFC] Unicode/UTF-8 support for XFS References: <20140911203735.GA19952@sgi.com> <20140912100230.GB4267@dastard> <5412DF37.9030005@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5412DF37.9030005@sgi.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1410555329 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-ASG-Whitelist: Body =?UTF-8?B?aHR0cDovL21hcmNcLmluZm8vXD8=?= X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Sep 12, 2014 at 01:55:35PM +0200, Olaf Weber wrote: > I looked up those discussions in the archives. For example, here's > Christoph about rejecting filenames if they're not well-formed unicode. > http://marc.info/?l=linux-fsdevel&m=120876935526856&w=2 > And Jamie Lokier making a similar point: > http://oss.sgi.com/archives/xfs/2008-04/msg01263.html And I might now disagree with my past self. While non-ut8 characters are perfectly valid unix filenames, and I think everyones life is easier if we generally stay out of the utf8 business it seems that for this particular use case (shared filesystem with Windows, right) just accepting utf8 should be fine. ZFS is doing, MacOS X apparently is, and NFSv4 requires it, although as far as I know most implementations ignore that requirement. From greg@kroah.com Fri Sep 12 20:44:51 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A61B67F37 for ; Fri, 12 Sep 2014 20:44:51 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 33140AC002 for ; Fri, 12 Sep 2014 18:44:48 -0700 (PDT) X-ASG-Debug-ID: 1410572683-04bdf0109aa11ad0001-NocioJ Received: from out4-smtp.messagingengine.com (out4-smtp.messagingengine.com [66.111.4.28]) by cuda.sgi.com with ESMTP id Fs4aE02VlYSFYALH (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 12 Sep 2014 18:44:43 -0700 (PDT) X-Barracuda-Envelope-From: greg@kroah.com X-Barracuda-Apparent-Source-IP: 66.111.4.28 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by gateway2.nyi.internal (Postfix) with ESMTP id E074C20A8A for ; Fri, 12 Sep 2014 21:44:42 -0400 (EDT) Received: from frontend1 ([10.202.2.160]) by compute3.internal (MEProxy); Fri, 12 Sep 2014 21:44:42 -0400 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=date:from:to:cc:subject:message-id :references:mime-version:content-type:in-reply-to; s=smtpout; bh=DkuaGgUuA5EsDkRjITD2WQTB+Dk=; b=HfcjEWZaqVJYmh6Vqn8EZRADGqk0 Yd9wBA3eGNNT6DLjS60Y13c5ejpdpEJlNMiWAUzHPY4yfV9vpiLOL/LEAjf02Kx7 Tl5joLtb7I6+693O4mYupvqX5stWn/M7myfQFcc3vPv+cdsnKhZiSmnwnrPDBZYo 5LQck2yAwAnj8dQ= X-Sasl-enc: 771IucYz/3jkY8q034mQzQUML2Vn6mnUFm+4oBrWPSDc 1410572682 Received: from localhost (unknown [24.22.230.10]) by mail.messagingengine.com (Postfix) with ESMTPA id 8F019C00915; Fri, 12 Sep 2014 21:44:42 -0400 (EDT) Date: Fri, 12 Sep 2014 18:44:41 -0700 From: Greg KH To: Dave Chinner Cc: stable@vger.kernel.org, xfs@oss.sgi.com, Fanael Linithien Subject: Re: XFS fixes needed in stable kernels Message-ID: <20140913014441.GA21972@kroah.com> X-ASG-Orig-Subj: Re: XFS fixes needed in stable kernels References: <20140820001623.GT20518@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140820001623.GT20518@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: out4-smtp.messagingengine.com[66.111.4.28] X-Barracuda-Start-Time: 1410572683 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9421 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Wed, Aug 20, 2014 at 10:16:23AM +1000, Dave Chinner wrote: > Hi Stable Kernel Gurus! > > The following XFs fixes need to be pushed back to stable kernels. > The commits weren't all tagged in the recent 3.17-rc1 merge, so > you're getting an email from me instead. The commits required > from 3.17-rc1 are: > > 67dc288 xfs: ensure verifiers are attached to recovered buffers You already marked this one, but it didn't apply to 3.10-stable > 5fd364f xfs: quotacheck leaves dquot buffers without verifiers Now queued up. > ad3714b xfs: dquot recovery needs verifiers Didn't apply at all to 3.16-stable :( thanks, greg k-h From weber@zbfmail.de Sat Sep 13 09:33:33 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E2EE27F3F for ; Sat, 13 Sep 2014 09:33:33 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id AA4258F804B for ; Sat, 13 Sep 2014 07:33:30 -0700 (PDT) X-ASG-Debug-ID: 1410618807-04bdf01097a2a910001-NocioJ Received: from mail.zbfmail.de (mail.zbfmail.de [176.9.84.12]) by cuda.sgi.com with ESMTP id qB8RahUQDzgBHCZg (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sat, 13 Sep 2014 07:33:28 -0700 (PDT) X-Barracuda-Envelope-From: weber@zbfmail.de X-Barracuda-Apparent-Source-IP: 176.9.84.12 Received: from mail.zbfmail.de (localhost [127.0.0.1]) by mail.zbfmail.de (Postfix) with ESMTP id EAD271BE46E for ; Sat, 13 Sep 2014 16:33:21 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.9.2 mail.zbfmail.de EAD271BE46E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zbfmail.de; s=dkim; t=1410618806; bh=Wa9qPo6JizxmGxJHuk0ij4slPveBzHfh1ZXutfyvZoA=; h=Date:From:To:Subject:Reply-To; b=s46sS878n0KsGmTyhr4epol0YKpGgf9MVTYdDTJbg7QfwVwZnFKDqhhi9+s1aNJ9O Yz4pPg8gwEKrpyVjlOqNqi+2qT2YXgW1lyJJnULjAFGdvr9eZgCap3tpj/6jt/FPCi HkEpM+9SbEj123DkmPA7JrEnMpj3oUTlvo0jZ9B8= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable Date: Sat, 13 Sep 2014 16:33:21 +0200 From: Marko Weber|8000 To: Xfs Subject: unclean shutdown of usb hdd destroyed xfs partially Organization: zbf mail X-ASG-Orig-Subj: unclean shutdown of usb hdd destroyed xfs partially Reply-To: weber@zbfmail.de Mail-Reply-To: weber@zbfmail.de Message-ID: <3999c95c0dc7ebfdfbb2853a6d13f7dc@zbfmail.de> X-Sender: weber@zbfmail.de User-Agent: Roundcube zbfmail Webmail X-DCC--Metrics: mailserver 1282; Body=1 Fuz1=1 Fuz2=1 X-Barracuda-Connect: mail.zbfmail.de[176.9.84.12] X-Barracuda-Start-Time: 1410618808 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9439 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature hello dave hello list, an unclean shutdown on of my boxes made the xfs partially corrupt. i tried an xfs_repair with xfsprogs 3.1.10 then i read the corrupt data thread and tried it with 3.2.1 version of=20 xfsprogs. when i mount the partition and do an ls -l i get: # ls -l /mnt/temp ls: Zugriff auf /mnt/temp/serien nicht m=C3=B6glich: Die Struktur muss=20 bereinigt werden ls: Zugriff auf /mnt/temp/dokutv nicht m=C3=B6glich: Die Struktur muss=20 bereinigt werden insgesamt 0 ?????????? ? ? ? ? ? dokutv drwxrwxr-x 33 weber mediatomb 1283 25. Aug 2013 movies drwxrwxr-x 12 weber mediatomb 151 6. Aug 18:57 mp3 ?????????? ? ? ? ? ? serien the above lines with ls says "access not possible on serien and dokutv,=20 structure needs cleaning. This is also after an xfs_repair -L /dev/sde1 is there any trick to get the data accessable again? thanks for any hints or help marko From weber@zbfmail.de Sat Sep 13 09:37:06 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 70B417F3F for ; Sat, 13 Sep 2014 09:37:06 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id EA33CAC002 for ; Sat, 13 Sep 2014 07:37:02 -0700 (PDT) X-ASG-Debug-ID: 1410619020-04cb6c54feaad000001-NocioJ Received: from mail.zbfmail.de (mail.zbfmail.de [176.9.84.12]) by cuda.sgi.com with ESMTP id KclCpcX27m9bIH9J (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sat, 13 Sep 2014 07:37:01 -0700 (PDT) X-Barracuda-Envelope-From: weber@zbfmail.de X-Barracuda-Apparent-Source-IP: 176.9.84.12 Received: from mail.zbfmail.de (localhost [127.0.0.1]) by mail.zbfmail.de (Postfix) with ESMTP id BAC611BE51A for ; Sat, 13 Sep 2014 16:36:59 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.9.2 mail.zbfmail.de BAC611BE51A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zbfmail.de; s=dkim; t=1410619019; bh=AmCs2VT6vQgLuMuVR9dwWvPWERl9IKhb7YTgBziFdLI=; h=Date:From:To:Subject:Reply-To:In-Reply-To:References; b=3GykL6settEDc+tanPBBXNqHl5fRNoQ8kJB+1fHu6yNHgsYXaW0kcG5gPCXPB3Bi1 eG1DzTEit8Z2d4gXLOiiDRlohRpQ2vR0T3gC8UEGdzv/7w7/b0Gp81cN0skq/pLJFh qRTPM3aZ80fFeZcGuQmMu2xS+Aijj+CnvUpsJ4cI= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable Date: Sat, 13 Sep 2014 16:36:59 +0200 From: Marko Weber|8000 To: Xfs Subject: Re: unclean shutdown of usb hdd destroyed xfs partially Organization: zbf mail X-ASG-Orig-Subj: Re: unclean shutdown of usb hdd destroyed xfs partially Reply-To: weber@zbfmail.de Mail-Reply-To: weber@zbfmail.de In-Reply-To: <3999c95c0dc7ebfdfbb2853a6d13f7dc@zbfmail.de> References: <3999c95c0dc7ebfdfbb2853a6d13f7dc@zbfmail.de> Message-ID: <082ebd288523ee6155b66debade2a775@zbfmail.de> X-Sender: weber@zbfmail.de User-Agent: Roundcube zbfmail Webmail X-DCC--Metrics: mailserver 1282; Body=2 Fuz1=2 Fuz2=2 X-Barracuda-Connect: mail.zbfmail.de[176.9.84.12] X-Barracuda-Start-Time: 1410619020 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9439 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature an output of xfs_repair -v -L /dev/sde1 Am 2014-09-13 16:33, schrieb Marko Weber|8000: > hello dave hello list, >=20 > an unclean shutdown on of my boxes made the xfs partially corrupt. >=20 > i tried an xfs_repair with xfsprogs 3.1.10 > then i read the corrupt data thread and tried it with 3.2.1 version of=20 > xfsprogs. >=20 > when i mount the partition and do an ls -l i get: >=20 > # ls -l /mnt/temp > ls: Zugriff auf /mnt/temp/serien nicht m=C3=B6glich: Die Struktur muss > bereinigt werden > ls: Zugriff auf /mnt/temp/dokutv nicht m=C3=B6glich: Die Struktur muss > bereinigt werden > insgesamt 0 > ?????????? ? ? ? ? ? dokutv > drwxrwxr-x 33 weber mediatomb 1283 25. Aug 2013 movies > drwxrwxr-x 12 weber mediatomb 151 6. Aug 18:57 mp3 > ?????????? ? ? ? ? ? serien >=20 > the above lines with ls says "access not possible on serien and > dokutv, structure needs cleaning. >=20 > This is also after an xfs_repair -L /dev/sde1 >=20 > is there any trick to get the data accessable again? >=20 > thanks for any hints or help >=20 > marko >=20 > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs # xfs_repair -v -L /dev/sde1 Phase 1 - Superblock finden und =C3=BCberpr=C3=BCfen... - Berichts-Prozess in Abst=C3=A4nden von 15 Minutes - Block-Zwischenspeichergr=C3=B6=C3=9Fe ist auf 1487792 Eintr=C3= =A4ge gesetzt Phase 2 - ein internes Protokoll benutzen - Null-Protokoll... zero_log: head block 40 tail block 40 - freier Speicher und Inode-Karten des Dateisystems werden gescannt... bad magic numberbad magic numberbad magic number bad magic number bad magic number bad magic number bad magic number bad magic number bad magic number Metadata corruption detected at block 0x8/0x1000bad magic number bad magic number bad magic number bad magic number bad magic number bad magic number Metadata corruption detected at block 0x369497c8/0x1000 Metadata corruption detected at block 0x82fe3908/0x1000 Metadata corruption detected at block 0x20bf8e48/0x1000 Metadata corruption detected at block 0x417f1c88/0x1000 Metadata corruption detected at block 0x7813b448/0x1000 Metadata corruption detected at block 0x57542608/0x1000 Metadata corruption detected at block 0x4c69a148/0x1000 Metadata corruption detected at block 0x2baa1308/0x1000 Metadata corruption detected at block 0x6d292f88/0x1000 flasche magische # 0xfc4e2ba9 f=C3=BCr agf 0 Metadata corruption detected at block 0x15d50988/0x1000 falsche Version # 16777216 f=C3=BCr agf 0 falsche L=C3=A4nge 0 f=C3=BCr agf 0, k=C3=B6nnte 22892696 sein flfirst 1631203328 in agf 0 too large (max =3D 1024) falscher agf f=C3=BCr ag 0 wird zur=C3=BCckgesetzt falscher agbno 1681871612 f=C3=BCr btbno-Wurzel, agno 0 falscher agbno 1222767762 f=C3=BCr btbcnt-Wurzel, agno 0 Metadata corruption detected at block 0xaea84c8/0x1000 Metadata corruption detected at block 0x623eaac8/0x1000 Metadata corruption detected at block 0x8de8bdc8/0x1000 Metadata corruption detected at block 0xa3bdc748/0x1000 Metadata corruption detected at block 0x98d34288/0x1000 Metadata corruption detected at block 0x369497d0/0x1000 Metadata corruption detected at block 0x82fe3910/0x1000 falscher on-disk-Superblock 5 - falsche Magische Nummer falscher on-disk-Superblock 12 - falsche Magische Nummer Metadata corruption detected at block=20 0x20bf8e50/0x1000prim=C3=A4re/sekund=C3=A4rer Superblock-12-Konflikt -=20 AG-Superblock-Geometrie-Info hat einen Konflikt mit der Dateisystem-Geometrie flasche magische # 0x0 f=C3=BCr agf 12 falsche Version # 0 f=C3=BCr agf 12 Metadata corruption detected at block 0x417f1c90/0x1000 falscher on-disk-Superblock 6 - falsche Magische Nummer prim=C3=A4re/sekund=C3=A4rer Superblock-6-Konflikt - AG-Superblock-Geometri= e-Info=20 hat einen Konflikt mit der Dateisystem-Geometrie falscher on-disk-Superblock 3 - falsche Magische Nummer ungenutzten Anteil des =C2=BBsekund=C3=A4r=C2=AB-Superblocks nullen (AG #6) Metadata corruption detected at block 0x57542610/0x1000 falsche Sequenz # 0 f=C3=BCr agf 12 Metadata corruption detected at block=20 0x7813b450/0x1000Speicherzugriffsfehler From robin.listas@gmail.com Sat Sep 13 09:43:42 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 866267F50 for ; Sat, 13 Sep 2014 09:43:42 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id EF4FFAC001 for ; Sat, 13 Sep 2014 07:43:41 -0700 (PDT) X-ASG-Debug-ID: 1410619419-04cb6c54fdaad4a0001-NocioJ Received: from mail-we0-f172.google.com (mail-we0-f172.google.com [74.125.82.172]) by cuda.sgi.com with ESMTP id DiHxH1Kcpd2DMX3x (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Sat, 13 Sep 2014 07:43:40 -0700 (PDT) X-Barracuda-Envelope-From: robin.listas@gmail.com X-Barracuda-Apparent-Source-IP: 74.125.82.172 Received: by mail-we0-f172.google.com with SMTP id k48so1997469wev.17 for ; Sat, 13 Sep 2014 07:43:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:message-id:date:from:user-agent:mime-version:to:subject :references:in-reply-to:content-type:content-transfer-encoding; bh=phxc88IhmGQxYWTIfHpjGOx/rei3XbjwDKzJRpdm6jw=; b=EHWSTzaXr0sB2wTFmFoXBgRD1YhX04VmZMPpkYqBg9RdcsXHnyT2cHbJte9FjgUcDl +2WWjP3DriunXywtLNFK3/LfOaOksndrybBzp+A3ntF24/s4DibIRYijYNh6KdXMNHBe V/AyZkczh93Nvg6VPhfEvdXEy8Mas/q+aD69lWrLPGLZB3z25oArShpTfPvo0+KlkNl6 mpGBE1lVk368da7iSz8yIfAe8LEeM5jsaAckV7g1xua82HCyiaUZqQCowuBVpEQzoGBd Y++qalBwDTcPQKid5JPW4yVO1cBvxsLM1yAmMxzJhR4j41OTVE0ogGx/uWGMn3PaH89w PjZg== X-Received: by 10.194.78.4 with SMTP id x4mr20259290wjw.44.1410619419446; Sat, 13 Sep 2014 07:43:39 -0700 (PDT) Received: from Telcontar.valinor (177.Red-79-159-63.staticIP.rima-tde.net. [79.159.63.177]) by mx.google.com with ESMTPSA id dc9sm5110730wib.5.2014.09.13.07.43.38 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 13 Sep 2014 07:43:38 -0700 (PDT) Sender: Carlos Robinson Received: from localhost (localhost [127.0.0.1]) by Telcontar.valinor (Postfix) with ESMTP id EB99A6128B for ; Sat, 13 Sep 2014 16:43:33 +0200 (CEST) X-Virus-Scanned: amavisd-new at valinor Received: from Telcontar.valinor ([127.0.0.1]) by localhost (Telcontar.valinor [127.0.0.1]) (amavisd-new, port 10024) with LMTP id exiH_aFm4EtH for ; Sat, 13 Sep 2014 16:43:32 +0200 (CEST) Received: from [127.0.0.1] (localhost [127.0.0.1]) by Telcontar.valinor (Postfix) with ESMTP id 7B6326066F for ; Sat, 13 Sep 2014 16:43:31 +0200 (CEST) Message-ID: <54145812.7070100@opensuse.org> Date: Sat, 13 Sep 2014 16:43:30 +0200 From: "Carlos E. R." User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.0 MIME-Version: 1.0 To: xfs@oss.sgi.com Subject: Re: unclean shutdown of usb hdd destroyed xfs partially References: <3999c95c0dc7ebfdfbb2853a6d13f7dc@zbfmail.de> X-ASG-Orig-Subj: Re: unclean shutdown of usb hdd destroyed xfs partially In-Reply-To: <3999c95c0dc7ebfdfbb2853a6d13f7dc@zbfmail.de> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: mail-we0-f172.google.com[74.125.82.172] X-Barracuda-Start-Time: 1410619420 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9439 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 2014-09-13 16:33, Marko Weber|8000 wrote: > # ls -l /mnt/temp ls: Zugriff auf /mnt/temp/serien nicht möglich: > Die Struktur muss bereinigt werden ... > the above lines with ls says "access not possible on serien and > dokutv, structure needs cleaning. Just a comment. You can issue commands like this: LANG=C ls -l /mnt/temp and the output will be, for that time only, in English, so that we can all read it ;-) - -- Cheers / Saludos, Carlos E. R. (from 13.1 x86_64 "Bottle" at Telcontar) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iEYEARECAAYFAlQUWBAACgkQtTMYHG2NR9WslgCeNCsAiQA21UaQWl28qipLwOTK nnsAn09/oQlsrkDwlF2TYznumgK5sXnI =ipKe -----END PGP SIGNATURE----- From somdeepdey10@gmail.com Sat Sep 13 12:07:59 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.3 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,HTML_MESSAGE,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 640057F47 for ; Sat, 13 Sep 2014 12:07:59 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 3AAFB8F804B for ; Sat, 13 Sep 2014 10:07:56 -0700 (PDT) X-ASG-Debug-ID: 1410628073-04cbb05488d841d0001-NocioJ Received: from mail-ie0-f170.google.com (mail-ie0-f170.google.com [209.85.223.170]) by cuda.sgi.com with ESMTP id uGCxBpAQc81BRUst (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Sat, 13 Sep 2014 10:07:54 -0700 (PDT) X-Barracuda-Envelope-From: somdeepdey10@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.223.170 X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.170] Received: by mail-ie0-f170.google.com with SMTP id tp5so2628331ieb.29 for ; Sat, 13 Sep 2014 10:07:53 -0700 (PDT) X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.170] X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.170] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=qJObt37yk5W5+h1QCojTwF51G5viJt86RFbrMefQw0A=; b=0xnVRoChnrOEIGWYQJkIRrEJtNnMizdiTdYJ4gZnhP3W4t76DzNMtbTjqctv7TWQMh BdZBbec+1js+IkfsT/u4Fqy4uLnTIzn6Df8umWajd2CIc/qTf9Zx+h94+ssrcaRyVPPn WI9njwPqonN+KdcJpHUCL7AtBdPQ7HRaiWpfa5SQ3+N0oGmzKgLxryiTjremLvV6q7he 3XjoUXWl8wBRW2zY4DeD/qKrDrjtFFmjzGMK3migxhjnNhHBmXVMNJdV4iSUGsbncHFm iUmmiBV8m/Aq9knPwGGAY6zV2TyWs+PIFoBeueHyEg5mQ2UXDjrHiR9/K7Tujtyo7xy7 hRsg== MIME-Version: 1.0 X-Received: by 10.42.161.198 with SMTP id u6mr17508105icx.31.1410628073692; Sat, 13 Sep 2014 10:07:53 -0700 (PDT) Received: by 10.107.4.78 with HTTP; Sat, 13 Sep 2014 10:07:53 -0700 (PDT) Date: Sat, 13 Sep 2014 22:37:53 +0530 Message-ID: Subject: [RFD] xfs_fsr: Doubts related to xfs_fsr code From: Somdeep Dey X-ASG-Orig-Subj: [RFD] xfs_fsr: Doubts related to xfs_fsr code To: xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=90e6ba6e8fb83e236d0502f57163 X-Barracuda-Connect: mail-ie0-f170.google.com[209.85.223.170] X-Barracuda-Start-Time: 1410628074 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9442 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message --90e6ba6e8fb83e236d0502f57163 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hi, While studying the code and attempting to understand it, we have come up against certain doubts that have us in a slight fix. We've included the concerned sections of the code below, along with our specific problem in each of these sections. A little pointer in the right direction would be of great help. (Source file : fsr_xfs_fsr.c) ****** Doubt number 1 ****** (line 331 onwards) int main() if (optind < argc) // If the command line input contains the XFS //filesystem name / file on which xfs_fsr needs to be run on { for (; optind < argc; optind++) { argname =3D argv[optind]; // save target which can be file or filesystem if (lstat64(argname, &sb) < 0) { /* This system call returns a stat64 structure, and thus sets * all fields in it. * On success, zero is returned. On error, -1 is returned, * and errno is set appropriately. */ fprintf(stderr, _("%s: could not stat: %s: %s\n"), progname, argname, strerror(errno)); continue; } // POSIX macros are defined to check the file type using the st_mode field if (S_ISLNK(sb.st_mode)) // Check if path(argname) is a //symbolic link, if so link will be stat-ed and not file {// Hence we run stat64() and save the obtained stat structure struct stat64 sb2; if (stat64(argname, &sb2) =3D=3D 0 && (S_ISBLK(sb2.st_mode) || S_ISCHR(sb2.st_mode))) sb =3D sb2; // check if stat is a success and //if argname(path) is block device ? OR is character device? } ___________________________________________________________________________= _____ We understand that lstat64() and stat64() are used to see if target (file/filesystem) can be stated and if yes then the structure is saved. But we couldn=E2=80=99t exactly understand its use and why both functions a= re used separately. Usually the error could not stat: filename : is followed by Permission denied. Is this related to the root permissions i.e. accessibility ? ****** Doubt number 2 ****** (line 184 onwards) static char * find_mountpoint(char *mtab, char *argname, struct stat64 *sb) while ((t =3D getmntent(mtabp))) { if (S_ISDIR(sb->st_mode)) { /* mount point */ if (stat64(t->mnt_dir, &ms) < 0) continue; if (sb->st_ino !=3D ms.st_ino) continue; if (sb->st_dev !=3D ms.st_dev) continue; if (strcmp(t->mnt_type, MNTTYPE_XFS) !=3D 0) continue; } else { /* device */ struct stat64 sb2; if (stat64(t->mnt_fsname, &ms) < 0) continue; if (sb->st_rdev !=3D ms.st_rdev) continue; if (strcmp(t->mnt_type, MNTTYPE_XFS) !=3D 0) continue; /* * Make sure the mount point given by mtab is accessible * before using it. */ if (stat64(t->mnt_dir, &sb2) < 0) continue; } ___________________________________________________________________________= _____ We just wanted to confirm if the basic working of the function is 1) To obtain a mount table pointer to the mount table (/etc/mtab/ or /proc/mounts). 2) For each entry in the mount table check if it is a directory or device and after performing various comparisons (checks) =E2=80=93 (could you please elabor= ate on the checks performed), this function returns a pointer to the entry. ****** Doubt number 3 ****** (line 677 onwards) static int fsrfs(char *mntdir, xfs_ino_t startino, int targetrange) For the following __s32 buflenout; fshandlep =3D jdm_getfshandle( mntdir ); if ( ! fshandlep ) { fsrprintf(_("unable to get handle: %s: %s\n"), mntdir, strerror( errno )); return -1; } ___________________________________________________________________________= _____ We are a bit confused about what is exactly the file handle being returned by jdm_getfshandle(). Also what exactly is buflenout. Is it a structure field ? ___________________________________________________________________________= _____ while ((ret =3D xfs_bulkstat(fsfd,&lastino, GRABSZ, &buf[0], &buflenout) = =3D=3D 0)) { xfs_bstat_t *p; xfs_bstat_t *endp; if (buflenout =3D=3D 0) goto out0; /* Each loop through, defrag targetrange percent of the files */ count =3D (buflenout * targetrange) / 100; qsort((char *)buf, buflenout, sizeof(struct xfs_bstat), cmp); ___________________________________________________________________________= _____ In the above code snippet we understand that the while loop will run for N(10) passes and defragment top 10% of the defragmented files. However we would appreciate if you could further explain the functions: (ret =3D xfs_bulkstat(fsfd,&lastino, GRABSZ, &buf[0], &buflenout) =3D=3D 0) qsort((char *)buf, buflenout, sizeof(struct xfs_bstat), cmp); We know that the sort function will be used to sort extents based on size and then offset, but a bit more information on how it is exactly working will be really appreciated, as we believe that this sort() has some other purpose. ___________________________________________________________________________= _____ For this mail we have listed only a limited number of doubts that we think are pressing. Based on further explanations that we might receive from you, we will send out another mail for the doubts that still linger. Regards, A-DRS. --90e6ba6e8fb83e236d0502f57163 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi,<= /div>

While = studying the code and attempting to understand it, we have come up against = certain doubts that have us in a slight fix. We've included the concern= ed
=C2=A0sections of the code below, along = with our specific problem in each of these=C2=A0
=C2=A0sections. A little pointer in the right direction would be of g= reat help.

(Source file : fsr_xfs_fsr.c)

****** Doubt number 1 ******
(line 331 onwards)
int mai= n()=C2=A0

if (optind < argc) // If the command line input contains the XFS=C2=A0
//filesystem name / file on which xfs_fsr needs to be run on
{
for (; optind < argc; optind++)=C2=A0
{
a= rgname =3D argv[optind]; = // save target which can be file or filesystem
if (lstat64(argname, &sb) < 0)
{ /* This system call returns a stat64 struc= ture, and thus sets =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * all f= ields in it.
* On success, zero is returned. =C2=A0On error, -1 = is returned,=C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * and =C2=A0errno =C2=A0is set appropriatel= y.
*/
fprintf(stderr,
<= span class=3D"" style=3D"white-space:pre"> _("%s: could not s= tat: %s: %s\n"),
progname, argname, strerror(errno));
<= div class=3D"gmail_extra"> continue;
}=
// POSIX macros are defined to check the file type using the st_m= ode field
if (S_ISLNK(sb.st_mode)) // Check if path(argname) is a=C2=A0
//symboli= c link, if so link will be stat-ed and not file
{// Hence =C2=A0we= run stat64() and save the obtained stat structure
struct stat64 = sb2;
if (stat64(argname, &sb2) =3D=3D 0 && (S_ISBLK(s= b2.st_mode) || = =C2=A0=C2=A0
=C2=A0 =C2=A0 S_ISCHR(sb2.st_mode)))
sb= =3D sb2; // check if sta= t is a success and=C2=A0
//if argname(path) is block device ? O= R is character device? <= /div>
= }
________________________________= ________________________________________________

We understand that lstat64() and= stat64() are used to see if target
=C2=A0(= file/filesystem) can be stated and if yes then the structure is saved.=C2= =A0
But we couldn=E2=80=99t exactly underst= and its use and why both functions are used separately.
Usually the error could not stat: filename : is followed by Pe= rmission denied.
=C2=A0Is this related to t= he root permissions i.e. accessibility ?
****** Doubt number 2 ******

(line 184 onwards= )
static char *
find_mountpoint(char *mtab, char *argname, struct stat64 *sb)

while ((t =3D = getmntent(mtabp))) {
if (S_ISDIR(sb->st_mode)) { /* mount point */
if (stat64= (t->mnt_dir, &ms) < 0)
continue;
if (sb->= st_ino !=3D ms.st_ino)
continue;
if (sb->st_dev != =3D ms.st_dev)
continue;
if (strcmp(t->mnt_type, MN= TTYPE_XFS) !=3D 0)
continue;
<= span class=3D"" style=3D"white-space:pre"> } else { /* device */
struct stat64 = sb2;

<= span class=3D"" style=3D"white-space:pre"> if (stat64(t->mnt_fs= name, &ms) < 0)
continue;
if (sb->st_rdev != =3D ms.st_rdev)
continue;
if (strcmp(t->mnt_type, M= NTTYPE_XFS) !=3D 0)
continue;
<= br>
/*
* Make sure the mount point given by mtab is ac= cessible
* before using it.
*/
if (stat64(t= ->mnt_dir, &sb2) < 0)
continue;
}
______________________________________________________= __________________________
We just wanted t= o confirm if the basic working of the function is
1) To obtain a mount table pointer to the mount table (/etc/mtab/ or= /proc/mounts).
2) =C2=A0For each entry in = the mount table check if it is a directory or device and after
=C2=A0performing various comparisons (checks) =E2=80=93= (could you please elaborate on the checks
= =C2=A0 performed), this function returns a pointer to the entry.=C2=A0

****** Dou= bt number 3 ******

(line 677 onwards)
static int<= /div>
fsrfs(char *mntdir, xfs_ino_t startino, int= targetrange)

For the following=C2=A0

<= div class=3D"gmail_extra">__s32 = buflenout;

fshandlep = =3D jdm_getfshandle( mntdir );
if ( ! fshandlep ) {
fsrpr= intf(_("unable to get handle: %s: %s\n"),
=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0mntdir, strerror( errno ));
return -1;
<= div class=3D"gmail_extra"> }
_______________________________________= _________________________________________
<= br>
We are a bit confused about what is exa= ctly the file handle being returned
=C2=A0b= y jdm_getfshandle().
Also what exactly is b= uflenout. Is it a structure field ?
_______= _________________________________________________________________________

while (= (ret =3D xfs_bulkstat(fsfd,&lastino, GRABSZ, &buf[0], &buflenou= t) =3D=3D 0))
{
xfs_bstat_t *p;
xfs_bstat_t *end= p;

if (buflenout =3D=3D 0)
= goto out0;

/* Each lo= op through, defrag targetrange percent of the files */
count =3D (= buflenout * targetrange) / 100;

<= div class=3D"gmail_extra">
qsort((char *)buf, buflenout, sizeof(struct xfs_bstat), cmp);
_____________________________________________________= ___________________________

In the above code snippet we understand that the whil= e loop will run for N(10)=C2=A0
passes and = defragment top 10% of the defragmented files.
However we would appreciate if you could further explain the functions:<= /div>

(ret = =3D xfs_bulkstat(fsfd,&lastino, GRABSZ, &buf[0], &buflenout) = =3D=3D 0)

qsort((char *)buf, buflenout, sizeof(struct xfs_bstat), cmp);

We know that th= e sort function will be used to sort extents based on size and then=C2=A0
offset, but a bit more information on how it= is exactly working will be really=C2=A0
ap= preciated, as we believe that this sort() has some other purpose.
____________________________________________________= ____________________________



For this mail we have listed only a limited number of= doubts that we think are pressing. Based on further explanations that we m= ight receive from you, we will send out another =C2=A0mail for the doubts t= hat still linger.

Regards,
A-DRS.
--90e6ba6e8fb83e236d0502f57163-- From BATV+0d006f7484da0da72a41+4038+infradead.org+hch@bombadil.srs.infradead.org Sat Sep 13 14:46:06 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BAF0E7F3F for ; Sat, 13 Sep 2014 14:46:06 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4D861AC001 for ; Sat, 13 Sep 2014 12:46:03 -0700 (PDT) X-ASG-Debug-ID: 1410637560-04cbb05486d87af0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id ymBNWeD7bLmzsrpQ (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sat, 13 Sep 2014 12:46:01 -0700 (PDT) X-Barracuda-Envelope-From: BATV+0d006f7484da0da72a41+4038+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XStGh-0000ME-HH; Sat, 13 Sep 2014 19:45:59 +0000 Date: Sat, 13 Sep 2014 12:45:59 -0700 From: Christoph Hellwig To: Eric Sandeen Cc: Eric Sandeen , xfs-oss Subject: Re: [PATCH V3] xfs_io: add mremap command Message-ID: <20140913194559.GA28479@infradead.org> X-ASG-Orig-Subj: Re: [PATCH V3] xfs_io: add mremap command References: <54111610.4080604@redhat.com> <54132553.9090202@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <54132553.9090202@sandeen.net> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1410637561 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9445 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Fri, Sep 12, 2014 at 11:54:43AM -0500, Eric Sandeen wrote: > This adds a simple mremap command to xfs_io. > > It does not take a start address; it uses the existing > start address, so the sized passed will be the new total > size of the mapping. > > Signed-off-by: Eric Sandeen Looks good to me, but I'd feel much more comfortable about merging it if we had an xfstests test case that actually exercises it. From BATV+0d006f7484da0da72a41+4038+infradead.org+hch@bombadil.srs.infradead.org Sat Sep 13 14:47:22 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 816617F3F for ; Sat, 13 Sep 2014 14:47:22 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 62DA38F8033 for ; Sat, 13 Sep 2014 12:47:22 -0700 (PDT) X-ASG-Debug-ID: 1410637633-04cb6c5500ab7040001-NocioJ Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) by cuda.sgi.com with ESMTP id eiHzpFqpFGsZEHcL (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sat, 13 Sep 2014 12:47:13 -0700 (PDT) X-Barracuda-Envelope-From: BATV+0d006f7484da0da72a41+4038+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XStHt-0000Q9-77; Sat, 13 Sep 2014 19:47:13 +0000 Date: Sat, 13 Sep 2014 12:47:13 -0700 From: Christoph Hellwig To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH v2] xfsrestore: use utimensat() to provide atime/mtime with ns resolution Message-ID: <20140913194713.GB28479@infradead.org> X-ASG-Orig-Subj: Re: [PATCH v2] xfsrestore: use utimensat() to provide atime/mtime with ns resolution References: <1409866939-1480-1-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1409866939-1480-1-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: bombadil.infradead.org[198.137.202.9] X-Barracuda-Start-Time: 1410637633 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9446 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 04, 2014 at 05:42:19PM -0400, Brian Foster wrote: > xfsdump encodes and stores the full atime and mtime for each file with > nanosecond resolution. xfsrestore uses utime() to set the times of each > file that is restored. The latter supports resolution of 1 second, thus > sub-second timestamp data is lost on restore. > > Add the associated configure checks for and use utimensat() when > available to restore timestamps with nanosecond resolution. Create a new > helper to facilitate conditional support for utimensat(). > > Signed-off-by: Brian Foster Looks good to me, Reviewed-by: Christoph Hellwig From BATV+0d006f7484da0da72a41+4038+infradead.org+hch@bombadil.srs.infradead.org Sat Sep 13 14:47:56 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id BED967F3F for ; Sat, 13 Sep 2014 14:47:56 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 85F8E8F8033 for ; Sat, 13 Sep 2014 12:47:56 -0700 (PDT) X-ASG-Debug-ID: 1410637675-04bdf0109aa34c80001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id BOzr1BXYzjxOPSsJ (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sat, 13 Sep 2014 12:47:55 -0700 (PDT) X-Barracuda-Envelope-From: BATV+0d006f7484da0da72a41+4038+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XStIV-0000Un-Kl; Sat, 13 Sep 2014 19:47:51 +0000 Date: Sat, 13 Sep 2014 12:47:51 -0700 From: Christoph Hellwig To: Jan ??ul??k , Dave Chinner Cc: Brian Foster , Eric Sandeen , XFS mail list Subject: Re: symlink loop for /lib64/libhandle.so Message-ID: <20140913194751.GA1675@infradead.org> X-ASG-Orig-Subj: Re: symlink loop for /lib64/libhandle.so References: <20140709132836.GA65226@bfoster.bfoster> <20140710134851.GA26652@infradead.org> <1405009872.31068.22.camel@jtulak> <53BEC1E7.1070904@sandeen.net> <1405075678.28203.56.camel@jtulak> <1405325087.3196.6.camel@jtulak> <20140714082607.GA19882@infradead.org> <20140715154857.GA14716@infradead.org> <20140811180227.GA30281@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140811180227.GA30281@infradead.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1410637675 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9445 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS ping? On Mon, Aug 11, 2014 at 11:02:27AM -0700, Christoph Hellwig wrote: > Dave, can you pick up this patch for xfsprogs? > > On Tue, Jul 15, 2014 at 08:48:57AM -0700, Christoph Hellwig wrote: > > Hi Jan, > > > > there were still some small isues with the patch format, I've attached > > a version of your patch that has the expected format. > > > > Note that I also changed it to only check the canonical names instead of > > testing the passed in one and the one readlink was called on. This > > should be enough I think, but please test that it still works for you. > > > > Thanks for tracking this down! > > > From: Jan Tulak > > Subject: [PATCH] libhandle: fix instalation for symlinked /usr > > > > Canonicalize the pathnames for PKG_LIB_DIR and PKG_ROOT_LIB_DIR before > > checking if they are the same. This is required for Fedora which doesn't > > have a separate /usr/lib directory anymore. > > > > Reported-by: Jan Tulak > > Signed-off-by: Jan Tulak > > > > diff --git a/include/buildmacros b/include/buildmacros > > index 7a01880..4e4e8fa 100644 > > --- a/include/buildmacros > > +++ b/include/buildmacros > > @@ -76,10 +76,11 @@ INSTALL_LTLIB_DEV = \ > > ../$(INSTALL) -m 644 $(LIBNAME).lai $(PKG_LIB_DIR)/$(LIBNAME).la ; \ > > ../$(INSTALL) -m 755 -d $(PKG_ROOT_LIB_DIR); \ > > ../$(INSTALL) -T so_base $(LIBNAME).lai $(PKG_ROOT_LIB_DIR); \ > > - if test "x$(PKG_LIB_DIR)" != "x$(PKG_ROOT_LIB_DIR)" ; then \ > > - ../$(INSTALL) -S $(PKG_LIB_DIR)/$(LIBNAME).a $(PKG_ROOT_LIB_DIR)/$(LIBNAME).a; \ > > - ../$(INSTALL) -S $(PKG_LIB_DIR)/$(LIBNAME).la $(PKG_ROOT_LIB_DIR)/$(LIBNAME).la; \ > > - ../$(INSTALL) -S $(PKG_ROOT_LIB_DIR)/$(LIBNAME).so $(PKG_LIB_DIR)/$(LIBNAME).so; \ > > + if [ "x$(shell readlink -f $(PKG_LIB_DIR))" != \ > > + "x$(shell readlink -f $(PKG_ROOT_LIB_DIR))"; ]; then \ > > + ../$(INSTALL) -S $(PKG_LIB_DIR)/$(LIBNAME).a $(PKG_ROOT_LIB_DIR)/$(LIBNAME).a; \ > > + ../$(INSTALL) -S $(PKG_LIB_DIR)/$(LIBNAME).la $(PKG_ROOT_LIB_DIR)/$(LIBNAME).la; \ > > + ../$(INSTALL) -S $(PKG_ROOT_LIB_DIR)/$(LIBNAME).so $(PKG_LIB_DIR)/$(LIBNAME).so; \ > > fi > > else > > INSTALL_LTLIB_DEV = $(INSTALL_LTLIB_STATIC) > > > _______________________________________________ > > xfs mailing list > > xfs@oss.sgi.com > > http://oss.sgi.com/mailman/listinfo/xfs > > ---end quoted text--- ---end quoted text--- From sandeen@sandeen.net Sat Sep 13 15:12:13 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 75F517F3F for ; Sat, 13 Sep 2014 15:12:13 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5C5F9304048 for ; Sat, 13 Sep 2014 13:12:10 -0700 (PDT) X-ASG-Debug-ID: 1410639128-04cb6c5500ab7740001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id HQYAWNwwS7QINpAm for ; Sat, 13 Sep 2014 13:12:08 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 264ED60EB594; Sat, 13 Sep 2014 15:12:08 -0500 (CDT) Message-ID: <5414A517.1080102@sandeen.net> Date: Sat, 13 Sep 2014 15:12:07 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Christoph Hellwig CC: Eric Sandeen , xfs-oss Subject: Re: [PATCH V3] xfs_io: add mremap command References: <54111610.4080604@redhat.com> <54132553.9090202@sandeen.net> <20140913194559.GA28479@infradead.org> X-ASG-Orig-Subj: Re: [PATCH V3] xfs_io: add mremap command In-Reply-To: <20140913194559.GA28479@infradead.org> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410639128 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9446 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/13/14 2:45 PM, Christoph Hellwig wrote: > On Fri, Sep 12, 2014 at 11:54:43AM -0500, Eric Sandeen wrote: >> This adds a simple mremap command to xfs_io. >> >> It does not take a start address; it uses the existing >> start address, so the sized passed will be the new total >> size of the mapping. >> >> Signed-off-by: Eric Sandeen > > Looks good to me, but I'd feel much more comfortable about merging it > if we had an xfstests test case that actually exercises it. > I did it for a crazy mremap failure we saw, I'll probably end up writing a testcase for that which uses it. I could easily enough write a test to exercise this directly too, I'll look into it. Thanks, -Eric From sandeen@sandeen.net Sat Sep 13 16:46:48 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C7FFD7F3F for ; Sat, 13 Sep 2014 16:46:47 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3B810AC001 for ; Sat, 13 Sep 2014 14:46:46 -0700 (PDT) X-ASG-Debug-ID: 1410644804-04cbb05486d8a800001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id zUqQzaiFa6z1QHO6 for ; Sat, 13 Sep 2014 14:46:45 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id A694060EB594; Sat, 13 Sep 2014 16:46:44 -0500 (CDT) Message-ID: <5414BB44.6060306@sandeen.net> Date: Sat, 13 Sep 2014 16:46:44 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Somdeep Dey , xfs@oss.sgi.com Subject: Re: [RFD] xfs_fsr: Doubts related to xfs_fsr code References: X-ASG-Orig-Subj: Re: [RFD] xfs_fsr: Doubts related to xfs_fsr code In-Reply-To: Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410644804 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9448 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/13/14 12:07 PM, Somdeep Dey wrote: > Hi, > > While studying the code and attempting to understand it, we have come up against certain doubts that have us in a slight fix. We've included the concerned > sections of the code below, along with our specific problem in each of these > sections. A little pointer in the right direction would be of great help. > > (Source file : fsr_xfs_fsr.c) If possible, please send mails - especially those containing code - in plaintext, not HTML, so it doeesn't get mangled. > ****** Doubt number 1 ****** > (line 331 onwards) (re-pasted to avoid html mangling) for (; optind < argc; optind++) { argname = argv[optind]; if (lstat64(argname, &sb) < 0) { fprintf(stderr, _("%s: could not stat: %s: %s\n"), progname, argname, strerror(errno)); continue; } if (S_ISLNK(sb.st_mode)) { struct stat64 sb2; if (stat64(argname, &sb2) == 0 && (S_ISBLK(sb2.st_mode) || S_ISCHR(sb2.st_mode))) sb = sb2; } mntp = find_mountpoint(mtab, argname, &sb); > ________________________________________________________________________________ > > We understand that lstat64() and stat64() are used to see if target > (file/filesystem) can be stated and if yes then the structure is saved. > But we couldn’t exactly understand its use and why both functions are used separately. > Usually the error could not stat: filename : is followed by Permission denied. > Is this related to the root permissions i.e. accessibility ? The code has the net effect of only using the stat information of a link target if that target is a block or character device. I don't know for sure why that is, but I presume that it has to do with the find_mountpoint() code, and symlinks in /dev vs. what is found in /proc/mounts. The manpage mentions this behavior as well: A command line name referring to a symbolic link (except to a file system device), FIFO, or UNIX domain socket generates a warning message, but is otherwise ignored. While traversing the filesystem these types of files are silently skipped. > ****** Doubt number 2 ****** > > (line 184 onwards) while ((t = getmntent(mtabp))) { if (S_ISDIR(sb->st_mode)) { /* mount point */ if (stat64(t->mnt_dir, &ms) < 0) continue; if (sb->st_ino != ms.st_ino) continue; if (sb->st_dev != ms.st_dev) continue; if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) continue; } else { /* device */ struct stat64 sb2; if (stat64(t->mnt_fsname, &ms) < 0) continue; if (sb->st_rdev != ms.st_rdev) continue; if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) continue; /* * Make sure the mountpoint given by mtab is accessible * before using it. */ if (stat64(t->mnt_dir, &sb2) < 0) continue; > ________________________________________________________________________________ > We just wanted to confirm if the basic working of the function is > 1) To obtain a mount table pointer to the mount table (/etc/mtab/ or /proc/mounts). > 2) For each entry in the mount table check if it is a directory or device and after > performing various comparisons (checks) – (could you please elaborate on the checks > performed), this function returns a pointer to the entry. We are looking to see if we have been given either a mounted xfs device, or an xfs mount point. We iterate over devices from getmntent to find out if there is a match for a mounted filesystem. If the cmdline argument was a directory, it might be a mountpoint, so we check the getmntent entry's mnt_dir (mountpoint) to see if it: 1) has the same inode number as our argument 2) is the same device number as our argument (same st_dev) 3) is of type XFS If it isn't a directory, it might be a device, so we check the getmntent entry's device by looking at it's mnt_fsname (device) to see if: 1) is the same device number (same st_rdev) 2) is of type XFS > ****** Doubt number 3 ****** > > (line 677 onwards) > static int > fsrfs(char *mntdir, xfs_ino_t startino, int targetrange) > > For the following __s32 buflenout; ... fshandlep = jdm_getfshandle( mntdir ); if ( ! fshandlep ) { fsrprintf(_("unable to get handle: %s: %s\n"), mntdir, strerror( errno )); return -1; } > ________________________________________________________________________________ > > We are a bit confused about what is exactly the file handle being returned > by jdm_getfshandle(). > Also what exactly is buflenout. Is it a structure field ? > ________________________________________________________________________________ Let's be inquisitive people, and find out the answers to these questions by reading the code and the existing documentation: The fshandlep returned by jdm_getfshandle is passed through jdm_open() to open_by_fshandle(), which calls the XFS_IOC_OPEN_BY_HANDLE interface, which is well described in the open_by_handle(3) manpage. buflenout is passed to xfs_bulkstat() as the *ocount argument, which assigns it to an xfs_fsop_bulkreq_t structure's ocount member. That structure is then passed to the XFS_IOC_FSBULKSTAT which is documented in the xfsctl manpage: ocount is a pointer to a count of returned values, filled in by the call. An output ocount value of zero means that the inode table has been exhausted. That manpage also explains what the XFS bulkstat interface does. > ________________________________________________________________________________ while ((ret = xfs_bulkstat(fsfd, &lastino, GRABSZ, &buf[0], &buflenout) == 0)) { xfs_bstat_t *p; xfs_bstat_t *endp; if (buflenout == 0) goto out0; /* Each loop through, defrag targetrange percent of the files */ count = (buflenout * targetrange) / 100; qsort((char *)buf, buflenout, sizeof(struct xfs_bstat), cmp); > In the above code snippet we understand that the while loop will run for N(10) > passes and defragment top 10% of the defragmented files. > However we would appreciate if you could further explain the functions: > > (ret = xfs_bulkstat(fsfd,&lastino, GRABSZ, &buf[0], &buflenout) == 0) see the manpage mentioned above; it gets a batch (GRABSZ, or 64) of inodes to look at. > qsort((char *)buf, buflenout, sizeof(struct xfs_bstat), cmp); > > We know that the sort function will be used to sort extents based on size and then > offset, but a bit more information on how it is exactly working will be really > appreciated, as we believe that this sort() has some other purpose. > ________________________________________________________________________________ It has nothing to do with the extent *size* qsort is passed cmp() which compares the number of extents, based on: __s32 bs_extents; /* number of extents */ and sorts based on that. So it compares all of the entries returned by xfs_bulkstat and sorts the buffer by the number of extents in the entries, that's all. > For this mail we have listed only a limited number of doubts that we > think are pressing. Based on further explanations that we might > receive from you, we will send out another mail for the doubts that > still linger. Please also do as much reading of code and the existing documentation as you can, first. ;) -Eric > Regards, > A-DRS. From david@fromorbit.com Sat Sep 13 17:09:38 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1BCFA7F3F for ; Sat, 13 Sep 2014 17:09:38 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 96B8EAC001 for ; Sat, 13 Sep 2014 15:09:34 -0700 (PDT) X-ASG-Debug-ID: 1410646170-04cb6c54fdaba350001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id IXyGC7PyF5EqUXXa for ; Sat, 13 Sep 2014 15:09:31 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtAgAHe/FFR5LCtm/2dsb2JhbABfgw2BKoIsr2gGmHuFawQCAYEHF3iEAwEBAQMBDCYBIyMFCwgDGAkQAhMPBSUDNIg2B7wqGBiFZIlRBxYRAoMFgR0FnQeVQINwKy9nIYFCAQEB Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail07.adl2.internode.on.net with ESMTP; 14 Sep 2014 07:39:30 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XSvVM-0001Uy-QN; Sun, 14 Sep 2014 08:09:16 +1000 Date: Sun, 14 Sep 2014 08:09:16 +1000 From: Dave Chinner To: weber@zbfmail.de Cc: Xfs Subject: Re: unclean shutdown of usb hdd destroyed xfs partially Message-ID: <20140913220916.GC4267@dastard> X-ASG-Orig-Subj: Re: unclean shutdown of usb hdd destroyed xfs partially References: <3999c95c0dc7ebfdfbb2853a6d13f7dc@zbfmail.de> <082ebd288523ee6155b66debade2a775@zbfmail.de> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <082ebd288523ee6155b66debade2a775@zbfmail.de> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1410646171 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9449 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header On Sat, Sep 13, 2014 at 04:36:59PM +0200, Marko Weber|8000 wrote: > > an output of xfs_repair -v -L /dev/sde1 ... > > # xfs_repair -v -L /dev/sde1 What version? > Phase 1 - Superblock finden und überprüfen... > - Berichts-Prozess in Abständen von 15 Minutes > - Block-Zwischenspeichergröße ist auf 1487792 Einträge gesetzt > Phase 2 - ein internes Protokoll benutzen > - Null-Protokoll... > zero_log: head block 40 tail block 40 > - freier Speicher und Inode-Karten des Dateisystems werden > gescannt... > bad magic numberbad magic numberbad magic number .... > falscher on-disk-Superblock 12 - falsche Magische Nummer > Metadata corruption detected at block > 0x20bf8e50/0x1000primäre/sekundärer Superblock-12-Konflikt - > AG-Superblock-Geometrie-Info hat einen Konflikt mit der > Dateisystem-Geometrie > flasche magische # 0x0 für agf 12 > falsche Version # 0 für agf 12 > > Metadata corruption detected at block 0x417f1c90/0x1000 > falscher on-disk-Superblock 6 - falsche Magische Nummer > primäre/sekundärer Superblock-6-Konflikt - > AG-Superblock-Geometrie-Info hat einen Konflikt mit der > Dateisystem-Geometrie > falscher on-disk-Superblock 3 - falsche Magische Nummer > ungenutzten Anteil des »sekundär«-Superblocks nullen (AG #6) > Metadata corruption detected at block 0x57542610/0x1000 > falsche Sequenz # 0 für agf 12 > Metadata corruption detected at block > 0x7813b450/0x1000Speicherzugriffsfehler I don't read german(?) but that looks like many AG header block have been overwritten with zeros (0 magic number, 0 sequence #, 0 length, etc) and so even if we can repair the filesystem, I'd suggest that you need to verify that the data in every file in the filesystem is correct. Is that as far as xfs_repair got? If so, it would have appeared to crash. Can you run the lastest version inside gdb to get a stack trace when it dies? Or, alternatively, provide a metadump for one of us to look at more closely? Cheers, Dave. -- Dave Chinner david@fromorbit.com From root@krios.tbi.univie.ac.at Sat Sep 13 23:25:12 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 8E7257F3F for ; Sat, 13 Sep 2014 23:25:12 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 784F38F8033 for ; Sat, 13 Sep 2014 21:25:09 -0700 (PDT) X-ASG-Debug-ID: 1410668705-04cb6c54fdac1090001-NocioJ Received: from krios.tbi.univie.ac.at (krios.tbi.univie.ac.at [131.130.44.60]) by cuda.sgi.com with ESMTP id EzbkVO9GtoAGsm3U for ; Sat, 13 Sep 2014 21:25:06 -0700 (PDT) X-Barracuda-Envelope-From: root@krios.tbi.univie.ac.at X-Barracuda-Apparent-Source-IP: 131.130.44.60 Received: by krios.tbi.univie.ac.at (Postfix) id 5EDDE5ECF1; Sun, 14 Sep 2014 06:25:03 +0200 (CEST) Delivered-To: root@krios.tbi.univie.ac.at Received: by krios.tbi.univie.ac.at (Postfix, from userid 0) id 499F15F1A2; Sun, 14 Sep 2014 06:25:03 +0200 (CEST) From: root@krios.tbi.univie.ac.at (Cron Daemon) To: root@krios.tbi.univie.ac.at Subject: Cron test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) Content-Type: text/plain; charset=UTF-8 X-ASG-Orig-Subj: Cron test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) X-Cron-Env: X-Cron-Env: X-Cron-Env: X-Cron-Env: Message-Id: <20140914042503.499F15F1A2@krios.tbi.univie.ac.at> Date: Sun, 14 Sep 2014 06:25:03 +0200 (CEST) X-Barracuda-Connect: krios.tbi.univie.ac.at[131.130.44.60] X-Barracuda-Start-Time: 1410668705 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.70 X-Barracuda-Spam-Status: No, SCORE=0.70 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, BSF_SC0_SA_TO_FROM_ADDR_MATCH, PR0N_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9457 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.20 PR0N_SUBJECT Subject has letters around special characters (pr0n) 0.50 BSF_SC0_SA_TO_FROM_ADDR_MATCH Sender Address Matches Recipient Address /etc/cron.daily/logrotate: error: error opening /home/git/gitlab/log/application.log: Permission denied error: error opening /home/git/gitlab/log/githost.log: Permission denied error: error opening /home/git/gitlab/log/production.log: Permission denied error: error opening /home/git/gitlab/log/satellites.log: Permission denied error: error opening /home/git/gitlab/log/sidekiq.log: Permission denied error: error opening /home/git/gitlab/log/unicorn.stderr.log: Permission denied error: error opening /home/git/gitlab/log/unicorn.stdout.log: Permission denied error: error opening /home/git/gitlab-shell/gitlab-shell.log: Permission denied run-parts: /etc/cron.daily/logrotate exited with return code 1 From shamss@chges.ru Sun Sep 14 10:04:17 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 7A8AF7F4E for ; Sun, 14 Sep 2014 10:04:17 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 64BA58F8035 for ; Sun, 14 Sep 2014 08:04:14 -0700 (PDT) X-ASG-Debug-ID: 1410707047-04cbb05488da0650001-NocioJ Received: from ns3.bevolex.com (ns.km35921.keymachine.de [87.118.86.217]) by cuda.sgi.com with ESMTP id SwPYp5juERG25Y80 for ; Sun, 14 Sep 2014 08:04:07 -0700 (PDT) X-Barracuda-Envelope-From: shamss@chges.ru X-Barracuda-Apparent-Source-IP: 87.118.86.217 Received: from [37.9.53.12] (account shamss@chges.ru HELO bzzjczqy) by ns3.bevolex.com (CommuniGate Pro SMTP 5.2.3) with ESMTPA id 52285; Sun, 14 Sep 2014 19:04:06 +0400 Message-ID: From: =?windows-1251?B?weXn7u/g8e3u8fL8INDu5OA=?= To: , , , , Subject: =?windows-1251?B?wu7p7eAg7/Du8ujiIPDz8fHq6PUh?= Date: Sun, 14 Sep 2014 19:04:01 +0400 X-ASG-Orig-Subj: =?windows-1251?B?wu7p7eAg7/Du8ujiIPDz8fHq6PUh?= MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_0F04_01CFD04E.A579E790" X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Windows Live Mail 16.4.3528.331 X-MimeOLE: Produced By Microsoft MimeOLE V16.4.3528.331 X-Barracuda-Connect: ns.km35921.keymachine.de[87.118.86.217] X-Barracuda-Start-Time: 1410707047 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_TG035a, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9471 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 BSF_SC0_TG035a Message contains invalid style definition This is a multi-part message in MIME format. ------=_NextPart_000_0F04_01CFD04E.A579E790 Content-Type: text/plain; charset="windows-1251" Content-Transfer-Encoding: quoted-printable =C7=E4=F0=E0=E2=F1=F2=E2=F3=E9=F2=E5!=20 =CF=E5=F0=E5=E4=E0=E9=F2=E5 =FD=F2=EE =EE=E1=F0=E0=F9=E5=ED=E8=E5 =F0=EE=E4= =ED=FB=EC, =E1=EB=E8=E7=EA=E8=EC, =F1=EE=F1=E5=E4=FF=EC. =CC=FB =EE=E1=F0=E0=F9=E0=E5=EC=F1=FF =EA =F0=F3=F1=F1=EA=E8=EC =EB=FE=E4= =FF=EC (=F0=EE=F1=F1=E8=E9=F1=EA=E8=EC, =F3=EA=F0=E0=E8=ED=F1=EA=E8=EC, =E1= =E5=EB=EE=F0=F3=F1=F1=EA=E8=EC =E8 =EF=F0.)! =C2=D0=C0=C3 =E2 =ED=E0=F8=E5=EC =E4=EE=EC=E5! =CF=F0=E8=F7=E5=EC, =E2=F0= =E0=E3 =E3=EB=EE=E1=E0=EB=FC=ED=EE=E3=EE =EC=E0=F1=F8=F2=E0=E1=E0! =CF=EE= =E4 =E5=E3=EE =EA=EE=ED=F2=F0=EE=EB=E5=EC =EC=ED=EE=E6=E5=F1=F2=E2=EE =EC= =E0=F0=E8=EE=ED=E5=F2=EE=EA-=EF=F0=E5=E7=E8=E4=E5=ED=F2=EE=E2 =F1=EE=E2=E5= =F0=F8=E0=FE=F2 =F1=E0=EC=FB=E5 =F0=E0=E7=ED=FB=E5 =EE=EF=E0=F1=ED=FB=E5 = =E4=E5=FF=ED=E8=FF =E8 "=E1=E5=E7=E4=E5=E9=F1=F2=E2=E8=FF" =E2=EF=EB=EE=F2= =FC =E4=EE =E3=E5=ED=EE=F6=E8=E4=E0 =F1=E2=EE=E5=E3=EE =E8 =F7=F3=E6=E8=F5= =ED=E0=F0=EE=E4=EE=E2. =C2=EB=E0=F1=F2=FC =F0=FF=E4=E0 =E2=FB=F1=EE=EA=EE= =EF=EE=F1=F2=E0=E2=EB=E5=ED=ED=FB=F5 =E8 =E1=EE=E3=E0=F2=FB=F5 =EB=FE=E4=E5= =E9 "=EF=FF=F2=EE=E9 =EA=EE=EB=EE=ED=ED=FB" =E8 "=F2=E0=EA =ED=E0=E7=FB=E2= =E0=E5=EC=EE=E3=EE =E7=E0=EA=F3=EB=E8=F1=FC=FF" =EF=F0=EE=E4=E0=E2=EB=E8=E2= =E0=E5=F2 =E7=E0=EA=EE=ED=ED=EE=F1=F2=FC =EE=E4=ED=EE=E3=EE =E8=E7 =EE=EF= =E0=F1=ED=E5=E9=F8=E8=F5 =ED=E0=F0=EA=EE=F2=E8=EA=EE=E2- =E0=EB=EA=EE=E3=EE= =EB=FF, =F3=F1=F2=E0=ED=E0=E2=EB=E8=E2=E0=E5=F2 =EF=F0=EE=E3=F0=E0=EC=EC=FB= =F0=E0=E7=EB=EE=E6=E5=ED=E8=FF =EB=E8=F7=ED=EE=F1=F2=E8, =E8=ED=F1=F2=E8= =F2=F3=F2=EE=E2 =F1=E5=EC=FC=E8 =E8 =F0=EE=E4=E0 =E2 =D1=CC=C8 =E8 =E3=EE= =F1=F3=E4=E0=F0=F1=F2=E2=E5, =E4=E8=E1=E8=EB=E8=E7=E8=F0=F3=E5=F2 =EF=F0=EE= =EF=E0=E3=E0=ED=E4=EE=E9 =EA=F3=EB=FC=F2=E0 =E4=E5=ED=E5=E3 =E8 =E2=EB=E0= =F1=F2=E8 =E8 =F1=F2=F0=E0=E2=EB=E8=E2=E0=E5=F2 =E2 =E3=EE=F0=FF=F7=E8=F5= =E2=EE=E9=ED=E0=F5(=F5=EE=EB=EE=E4=ED=FB=E5 =F3=E6=E5 =E4=E0=E2=ED=EE =EF= =F0=EE=E8=E3=F0=E0=ED=FB)! =CE=E1=EC=E0=ED=FB=E2=E0=FF =ED=E0=F1 =EB=EE=E6= =ED=FB=EC=E8 =F6=E5=ED=ED=EE=F1=F2=FF=EC=E8 =E8 =EF=F0=E8=E7=FB=E2=E0=FF = =EA =ED=E8=E7=EC=E5=ED=ED=FB=EC =F6=E5=EB=FF=EC, =E2=F0=E0=E3 =EF=EE=F0=E0= =E1=EE=F9=E0=E5=F2 =E8, =E2 =E8=F2=EE=E3=E5, =E2=E5=E4=E5=F2 =ED=E0=F1 =F1= =E2=E0=EC=E8 =ED=E0 =E1=EE=E9=ED=FE. =CE=ED =ED=E5 =EE=F1=F2=E0=ED=EE=E2= =E8=F2=F1=FF, =EF=EE=EA=E0 =ED=E5 =E1=F3=E4=E5=F2 =EF=EE=F0=E0=E1=EE=F9=E5= =ED=EE =E8=EB=E8 =E8=F1=F2=F0=E5=E1=EB=E5=ED=EE =E2=F1=E5 =F7=E5=EB=EE=E2= =E5=F7=E5=F1=F2=E2=EE(=ED=E0=F1=F2=F3=EF=EB=E5=ED=E8=E5 =E3=EB=EE=E1=E0=EB= =FC=ED=EE=E3=EE =F2=EE=EB=EF=EE=FD=EB=E8=F2=E0=F0=ED=EE=E3=EE-=F0=E0=E1=F1= =EA=EE=E3=EE =EE=E1=F9=E5=F1=F2=E2=E0). =CB=FE=E4=E8, =F0=E0=E1=EE=F2=E0=FE= =F9=E8=E5 =ED=E0 =ED=E0=F8=E5=E3=EE =E2=F0=E0=E3=E0, =E2 =F2=EE=EC =F7=E8= =F1=EB=E5 =E2=EE =E2=EB=E0=F1=F2=E8 =D1=D8=C0 =E8 =C5=E2=F0=EE=F1=EE=FE=E7= =E0, =E2=E2=E8=E4=F3 =F1=E2=EE=E8=F5 =ED=E5=E1=EB=E0=E3=EE=E2=E8=E4=ED=FB= =F5 =E8=ED=F2=E5=F0=E5=F1=EE=E2, =ED=E5 =EF=F0=E8=ED=E8=EC=E0=FE=F2 =E5=E4= =E8=ED=F1=F2=E2=E5=ED=ED=EE =E2=EE=E7=EC=EE=E6=ED=EE=E5 =F3=F1=F2=F0=EE=E9= =F1=F2=E2=EE =FD=F4=F4=E5=EA=F2=E8=E2=ED=EE=E3=EE =EC=E8=F0=E0- =E2 =F1=E5= =EC=FC=E5(/=E5=E4=E8=ED=EE=EC =D0=EE=E4=E5) =F1=E8=EB=FC=ED=FB=F5 =ED=E0=F0= =EE=E4=EE=E2, =E8=F1=EA=EB=FE=F7=E0=FE=F9=E5=E9 =EC=E0=ED=E8=EF=F3=EB=FF=F6= =E8=E8 =E8 =E3=E5=ED=EE=F6=E8=E4- =EE=E1=F9=E5=F1=F2=E2=E5 =E0=E1=F1=EE=EB= =FE=F2=ED=EE=E9 =EF=EE=F0=FF=E4=EE=F7=ED=EE=F1=F2=E8. =CC=FB- =F0=F3=F1=F1=EA=E8=E9 =ED=E0=F0=EE=E4, =F0=EE=E4=ED=FF =E8 =E4=F0= =E5=E2=ED=E8=E9 =D0=EE=E4- =F1=E8=EB=FC=ED=E5=E9=F8=E0=FF =E5=E4=E8=ED=E0= =FF =F0=F3=F1=F1=EA=E0=FF =F6=E8=E2=E8=EB=E8=E7=E0=F6=E8=FF =F1 "=E8=F5 =EF= =EE=EC=EE=F9=FC=FE" =EF=F0=E5=E2=F0=E0=F9=E0=E5=EC=F1=FF =E2 =E6=E8=E2=EE= =F2=ED=FB=F5 =E8 =ED=E5 =EC=EE=E6=E5=EC =E4=E0=E6=E5 =E7=E0=F9=E8=F2=E8=F2= =FC =F1=E2=EE=FE "=F3=EA=F0=E0=E8=ED=F1=EA=F3=FE" =F7=E0=F1=F2=FC, =EF=EE= =E3=F0=FF=E7=F8=F3=FE =E2 =E3=F0=E0=E6=E4=E0=ED=F1=EA=EE=E9 =E2=EE=E9=ED=E5= . =CC=FB =EF=EE=E7=E2=EE=EB=E8=EB=E8 =E2=F0=E0=E3=F3 =F0=E0=E7=E4=E5=EB=E8= =F2=FC =ED=E0=F1 =E3=F0=E0=ED=E8=F6=E0=EC=E8, =F0=E0=E7=E4=E5=EB=E8=F2=FC= =ED=E0=F8=F3 =E2=E5=F0=F3, =EE=E1=F9=F3=FE =EA=F3=EB=FC=F2=F3=F0=F3, =E2= =EA=EE=ED=E5=F7=ED=EE=EC =E8=F2=EE=E3=E5- =E8=E4=E5=ED=F2=E8=F7=ED=EE=F1= =F2=FC, =F1=E4=E5=EB=E0=F2=FC =EF=F0=EE=F1=F2=EE =F1=EE=F1=E5=E4=FF=EC=E8= , =E0 =EF=EE=F2=EE=EC =F7=F3=F2=FC =EB=E8 =ED=E5 =E2=F0=E0=E3=E0=EC=E8. =CC= =FB =E2=F1=E5 =E8 =F2=E0=EA =E2=FB=EC=E8=F0=E0=E5=EC =EE=F2 =E0=EB=EA=EE=E3= =EE=EB=FF, =F0=E0=E7=F0=F3=F8=E5=ED=E8=FF =E8=ED=F1=F2=E8=F2=F3=F2=EE=E2 = =E7=E4=EE=F0=EE=E2=FB=F5 =F1=E5=EC=E5=E9=ED=FB=F5 =E8 =EE=E1=F9=E5=F1=F2=E2= =E5=ED=ED=FB=F5 =EE=F2=ED=EE=F8=E5=ED=E8=E9 =E8 =ED=E0=F1=E8=EB=E8=FF =E8= =ED=F3=E6=ED=EE =EE=E1=FA=E5=E4=E8=ED=FF=F2=FC=F1=FF, =E0 =ED=E5 =E2=F0=E0= =E6=E4=EE=E2=E0=F2=FC. =C2=EC=E5=F1=F2=E5 =EC=FB =F1=EC=EE=E6=E5=EC =EF=F0= =EE=F2=E8=E2=EE=F1=F2=EE=FF=F2=FC =F1=EA=F0=FB=F2=EE=E9 =E0=E3=F0=E5=F1=F1= =E8=E8 =F5=EE=E7=FF=E5=E2 =E7=E0=EF=E0=E4=ED=EE=E9 =F6=E8=E2=E8=EB=E8=E7=E0= =F6=E8=E8, =F1=EE=F5=F0=E0=ED=E8=F2=FC =F1=E2=EE=E8 =F1=E5=EC=FC=E8 =EE=F2= =F0=E0=F1=EF=E0=E4=E0 =E8 =D0=EE=E4 =EE=F2 =E2=FB=EC=E8=F0=E0=ED=E8=FF. =D2=E0=EA=EE=E9 =E6=E5 =E2=FB=E1=EE=F0 =E2=EC=E5=F1=F2=E5 =F1 =ED=E0=EC=E8= =E4=EE=EB=E6=ED=FB =F1=E4=E5=EB=E0=F2=FC =EF=E0=F2=F0=E8=EE=F2=FB =E4=F0= =F3=E3=E8=F5 =F1=F2=F0=E0=ED =E8 =ED=E0=F0=EE=E4=EE=E2. =C2 =EF=E5=F0=E2=F3= =FE =EE=F7=E5=F0=E5=E4=FC =F2=E5=F5, =F7=F2=EE =EF=F0=E5=E1=FB=E2=E0=FE=F2= =E2 =F2=E5=F7=E5=ED=E8=E5 =E4=EB=E8=F2=E5=EB=FC=ED=EE=E3=EE =E2=F0=E5=EC= =E5=ED=E8 =EF=EE=E4 =E2=EB=E0=F1=F2=FC=FE =ED=E0=F8=E8=F5 =E2=F0=E0=E3=EE= =E2 =E8 =E2 =ED=E0=E8=E1=EE=EB=FC=F8=E5=E9 =F1=F2=E5=EF=E5=ED=E8 =EF=EE=F1= =F2=F0=E0=E4=E0=EB=E8 =EE=F2 =E1=EE=EB=E5=E7=ED=E5=E9 =E3=EB=EE=E1=E0=EB=FC= =ED=EE=E3=EE =F3=EF=F0=E0=E2=EB=E5=ED=E8=FF(=D1=D8=C0 =E8 =C5=E2=F0=EE=F1= =EE=FE=E7), =E0 =F2=E0=EA=E6=E5 =F1=F2=F0=E0=ED- =ED=E0=F8=E8=F5 =F1=EE=F1= =E5=E4=E5=E9- =E0=F0=E0=E1=F1=EA=E8=E9 =EC=E8=F0, =CA=E8=F2=E0=E9. =CA=F2= =EE =E1=FB =E2=FB =ED=E8 =E1=FB=EB=E8- =EF=EE=EB=FF=EA, =EB=E8=F2=EE=E2=E5= =F6, =ED=E5=EC=E5=F6 =E8=EB=E8 =E0=EC=E5=F0=E8=EA=E0=ED=E5=F6- =E2=FB =E4= =EE=EB=E6=ED=FB =F1=E4=E5=EB=E0=F2=FC =E2=FB=E1=EE=F0. =C2=FB =F5=EE=F2=E8= =F2=E5 =F1=E2=EE=E1=EE=E4=FB =E8 =F0=EE=E4=F1=F2=E2=E0 =F1 =EE=F1=F2=E0=EB= =FC=ED=FB=EC=E8 =ED=E0=F0=EE=E4=E0=EC=E8 =E8=EB=E8 =E1=FB=F2=FC "=E8=F1=EA= =EB=FE=F7=E8=F2=E5=EB=FC=ED=FB=EC=E8"- =E8=F1=EF=EE=EB=FC=E7=EE=E2=E0=F2=FC= =F1=FF =EA=E0=EA =F0=E0=E1=FB =E8 =E2=F1=E5 =F0=E0=E2=ED=EE =F3=EC=E5=F0=E5= =F2=FC =E2 =E4=EE=EB=E3=EE=F1=F0=EE=F7=ED=EE=E9 =EF=E5=F0=F1=EF=E5=EA=F2=E8= =E2=E5? =CC=FB- =F2=E2=EE=F0=F6=FB =EF=EE =F1=F3=F2=E8 =EC=E8=F0=E0 =E8 =EF=F0=E8= =E7=E2=E0=ED=FB =F2=E2=EE=F0=E8=F2=FC =E8 =EF=EB=EE=E4=E8=F2=FC, =E0 =ED=E5= =F0=E0=F1=F2=E2=EE=F0=FF=F2=FC=F1=FF =E8 =F3=EC=E8=F0=E0=F2=FC! =CF=D0=CE=D1=CD=C8=D2=C5=D1=DC, =E2=EE=E9=ED=E0 =EF=F0=EE=F2=E8=E2 =ED=E0= =F1 =F3=E6=E5 =E4=E0=E2=ED=EE =E8=E4=E5=F2, =F1=F2=F0=E0=ED=FB =F1 =F0=F3= =F1=F1=EA=E8=EC=E8 =ED=E0=F0=EE=E4=E0=EC=E8 =F0=E0=E7=E4=E5=EB=E5=ED=FB =E8= =ED=E0=F1 =F3=E6=E5 =EF=FB=F2=E0=FE=F2=F1=FF =E4=EE=E1=E8=F2=FC- =E2=E2=E5= =F0=E3=ED=F3=F2=FC =E2 =E7=E0=E2=E8=F1=E8=EC=EE=F1=F2=FC =E8 =E8=F1=F2=F0= =E5=E1=E8=F2=FC(=F7=E5=F0=E5=E7 =F1=EC=E5=F0=F2=FC =D0=EE=E4=E0 =E8 =F1=E5= =EC=FC=E8 =E8=EB=E8 =F4=E8=E7=E8=F7=E5=F1=EA=E8). =C2=D0=C0=C3 =D1=C8=CB=C5=CD =C8 =C1=C5=D1=CF=CE=D9=C0=C4=C5=CD, =CD=CE =D0= =F3=F1=FC =E2=F1=E5=E3=E4=E0 =E1=FB=EB=E0 =E8 =E5=F1=F2=FC(=EA=E0=EA =F7=E0= =F1=F2=FC =F1=E2=EE=E5=E3=EE =D0=EE=E4=E0- =F1=E2=EE=E8=F5 =EF=F0=E5=E4=EA= =EE=E2-=F1=EB=E0=E2=FF=ED =E8 =E2=EF=EB=EE=F2=FC =E4=EE "=EC=E8=F4=E8=F7=E5= =F1=EA=EE=E9 =C3=E8=EF=E5=F0=E1=EE=F0=E5=E8") , =E4=EE=EB=E6=ED=E0 =EF=F0= =EE=F1=ED=F3=F2=FC=F1=FF =E8 =EE=F2=E2=E5=F2=E8=F2=FC =ED=E0 =E0=E3=F0=E5= =F1=F1=E8=FE- =E7=E0=F9=E8=F2=E8=F2=FC =F1=E2=EE=E8=F5 =E4=E5=F2=E5=E9 =EE= =F2 =E2=F1=E5=F5 =F3=E3=F0=EE=E7- =EE=F2 =EF=EE=F2=E5=F0=E8 =F7=E5=EB=EE=E2= =E5=F7=E5=F1=EA=E8=F5 =F1=E2=EE=E1=EE=E4 =E4=EE =EF=EE=EB=ED=EE=E3=EE =F0= =E0=E1=F1=F2=E2=E0 =E8 =F1=EC=E5=F0=F2=E8. =C0=ED=F2=E8=F7=E5=EB=EE=E2=E5= =F7=ED=EE=E5 =F3=EF=F0=E0=E2=EB=E5=ED=E8=E5 =E2 =E7=E0=EF=E0=E4=ED=FB=F5 = =F1=F2=F0=E0=ED=E0=F5 =F3=E6=E5 =EF=F0=E8=E2=E5=EB=EE =EA =EE=F1=F2=E0=ED= =EE=E2=EA=E5 =E4=E5=EC=EE=E3=F0=E0=F4=E8=F7=E5=F1=EA=EE=E3=EE =F0=EE=F1=F2= =E0, =F6=E5=ED=ED=EE=F1=F2=E8 =D0=EE=E4=E0 =EF=EE=EB=ED=EE=F1=F2=FC=FE =EF= =EE=E4=E0=E2=EB=E5=ED=FB =F0=FB=ED=EE=F7=ED=FB=EC=E8 =EE=F2=ED=EE=F8=E5=ED= =E8=FF=EC=E8, =EB=FE=E4=E8 =EF=F0=E5=E2=F0=E0=F9=E5=ED=FB =E2 =F0=EE=E1=EE= =F2=EE=E2, =EE=E1=F1=EB=F3=E6=E8=E2=E0=FE=F9=E8=F5 =E8=ED=F2=E5=F0=E5=F1=FB= =E3=EB=EE=E1=E0=EB=FC=ED=EE=E3=EE =EE=EB=E8=E3=E0=F0=F5=E0=F2=E0. =C0=F0=F5=E8=F2=E5=EA=F2=EE=F0=FB(=EC=E0=F1=EE=ED=FB) =E8 =F1=F2=F0=EE=E8= =F2=E5=EB=E8(=E5=E2=F0=E5=E9=F1=EA=E8=E5 =EA=EB=E0=ED=FB- =F0=EE=EA=F4=E5= =EB=E5=F0=FB, =F0=EE=F2=F8=E8=EB=FC=E4=FB, =E1=E0=F0=F3=F5=E8 =E8 =EF=F0.= ) =E7=E0=EF=E0=E4=ED=EE=E9 =F6=E8=E2=E8=EB=E8=E7=E0=F6=E8=E8, =E8=F5 =F3=EF= =F0=E0=E2=EB=FF=FE=F9=E8=E5(=F2=E0=E9=ED=FB=E5 =EE=E1=F9=E5=F1=F2=E2=E0) = =E8 =E8=F5 =F5=EE=E7=FF=E8=ED =F3=E1=E8=EB=E8 =E4=E5=F1=FF=F2=EA=E8 =EC=E8= =EB=EB=E8=EE=ED=EE=E2 =F0=F3=F1=F1=EA=E8=F5 =F1=E2=EE=E8=EC=E8 =EF=F0=EE=E5= =EA=F2=E0=EC=E8 =F0=E5=E2=EE=EB=FE=F6=E8=E9, =E3=F0=E0=E6=E4=E0=ED=F1=EA=E8= =F5 =E8 =EC=E8=F0=EE=E2=FB=F5 =E2=EE=E9=ED, =F3=E7=E0=EA=EE=ED=E5=ED=ED=EE= =E3=EE =ED=E0=F1=E8=EB=E8=FF =ED=E0=E4 =F1=E2=EE=E8=EC=E8 =E8 =F1=EF=E0=E8= =E2=E0=ED=E8=FF(=E8=F2=EE=E3=EE- =EE=EA=EE=EB=EE =EC=E8=EB=EB=E8=E0=F0=E4= =E0 =F0=F3=F1=F1=EA=E8=F5, =F1=F7=E8=F2=E0=FF =ED=E5 =F0=EE=E4=E8=E2=F8=E8= =F5=F1=FF =E4=E5=F2=E5=E9 =F3=E1=E8=F2=FB=F5 =F0=EE=E4=E8=F2=E5=EB=E5=E9 = =E8 =E8=F5 =EF=EE=F2=EE=EC=EA=EE=E2). =D0=F3=F1=F1=EA=E8=E5 =ED=E5 =EC=EE= =E3=F3=F2(=EF=EE =EF=F0=E0=E2=F3 =D0=EE=E4=E0 =E8 =E3=E5=ED=E5=F2=E8=F7=E5= =F1=EA=E8=EC =EF=F0=E8=F7=E8=ED=E0=EC) =E1=FB=F2=FC =F0=E0=E1=E0=EC=E8, =EF= =EE=FD=F2=EE=EC=F3 =CE=CD=E8 =EF=F0=E8=E3=EE=E2=EE=F0=E8=EB=E8 =E2=F1=E5=F5= =ED=E0=F1 =EA =F1=EC=E5=F0=F2=E8. =DD=F2=EE =E2=F0=E0=E3, =EF=F0=EE=F2=E8=E2 =EA=EE=F2=EE=F0=EE=E3=EE =E4=EE= =EB=E6=ED=FB =EE=E1=FA=E5=E4=E8=ED=E8=F2=FC=F1=FF =F0=EE=E4=ED=FB=E5 =EB=FE= =E4=E8, =F7=F2=EE=E1 =ED=E5 =E8=F1=F7=E5=E7=ED=F3=F2=FC =F1 =EB=E8=F6=E0 = =C7=E5=EC=EB=E8 =E8 =ED=E5 =EF=F0=E5=E2=F0=E0=F2=E8=F2=FC=F1=FF =E2 =F0=E0= =E1=EE=E2(=EA=EE=F2=EE=F0=FB=F5 =EF=EE=F2=EE=EC =F2=EE=E6=E5 =F3=E1=FC=FE= =F2- =EF=F0=E5=E2=F0=E0=F2=FF=F2 =E2 =F0=EE=E1=EE=F2=EE=E2 =E8 =E7=E0=EC=E5= =ED=FF=F2 =EC=E0=F8=E8=ED=E0=EC=E8). =C2=EE=E8=ED=FB =D0=F3=F1=E8! =CD=E5 =F1=EB=F3=F8=E0=E9=F2=E5 =EF=F0=E8=EA= =E0=E7=EE=E2 =EA=F0=EE=E2=E0=E2=FB=F5 =EE=F4=E8=F6=E5=F0=EE=E2! =C1=F3=E4= =FC=F2=E5 =EF=EE=F0=FF=E4=EE=F7=ED=FB, =EF=EE=EB=ED=FB =F1=E8=EB=FB =E4=F3= =F5=E0, =E0 =F1=EB=F3=F8=E0=E9=F2=E5 =F2=EE=EB=FC=EA=EE =F1=E2=EE=FE =F1=EE= =E2=E5=F1=F2=FC! =D1=EB=E0=E2=E0 =F2=E5=EC, =EA=F2=EE =ED=E5 =EE=E1=EC=E0=ED=F3=EB =E8 =ED= =E5 =EF=F0=E5=E4=E0=EB! =D1=EB=E0=E2=E0 =F2=E5=EC, =EA=F2=EE =ED=E5 =EE=F2= =E4=E0=EB =EF=F0=E8=EA=E0=E7 =F3=E1=E8=F2=FC! =D1=EB=E0=E2=E0 =E7=E0=F9=E8=F2=ED=E8=EA=E0=EC =F1=E2=EE=E5=E3=EE =ED=E0=F0= =EE=E4=E0! =D1=CB=C0=C2=C0 =D0=D3=D1=C8! =D1=CB=C0=C2=C0 =D0=CE=C4=D3! =C2=F1=E5, =E2 =EA=EE=EC =EE=F1=F2=E0=EB=E0=F1=FC =F1=E8=EB=E0 =F1=EE=EF=F0= =EE=F2=E8=E2=EB=FF=F2=FC=F1=FF, =EF=F0=E8=F1=EE=E5=E4=E8=ED=FF=E9=F2=E5=F1= =FC =EA =ED=E0=EC-=20 =C2=F1=E5, =E2 =EA=EE=EC =EE=F1=F2=E0=EB=E0=F1=FC =F1=E8=EB=E0 =F1=EE=EF= =F0=EE=F2=E8=E2=EB=FF=F2=FC=F1=FF, =EF=F0=E8=F1=EE=E5=E4=E8=ED=FF=E9=F2=E5= =F1=FC =EA =ED=E0=EC- https://vk.com/club75017598 ------=_NextPart_000_0F04_01CFD04E.A579E790 Content-Type: text/html; charset="windows-1251" Content-Transfer-Encoding: quoted-printable

=C7=E4=F0=E0=E2=F1=F2=E2=F3=E9=F2= =E5!

=CF=E5=F0=E5=E4=E0=E9=F2=E5 =FD=F2= =EE =EE=E1=F0=E0=F9=E5=ED=E8=E5 =F0=EE=E4=ED=FB=EC, =E1=EB=E8=E7=EA=E8=EC= ,=20 =F1=EE=F1=E5=E4=FF=EC.

=CC=FB =EE=E1=F0=E0=F9=E0=E5=EC=F1= =FF =EA =F0=F3=F1=F1=EA=E8=EC =EB=FE=E4=FF=EC (=F0=EE=F1=F1=E8=E9=F1=EA=E8= =EC,=20 =F3=EA=F0=E0=E8=ED=F1=EA=E8=EC, =E1=E5=EB=EE=F0=F3=F1=F1=EA=E8=EC =E8 =EF= =F0.)!

=C2=D0=C0=C3 =E2 =ED=E0=F8=E5=EC= =E4=EE=EC=E5! =CF=F0=E8=F7=E5=EC, =E2=F0=E0=E3 =E3=EB=EE=E1=E0=EB=FC=ED=EE= =E3=EE=20 =EC=E0=F1=F8=F2=E0=E1=E0! =CF=EE=E4 =E5=E3=EE =EA=EE=ED=F2=F0=EE=EB=E5=EC= =EC=ED=EE=E6=E5=F1=F2=E2=EE =EC=E0=F0=E8=EE=ED=E5=F2=EE=EA-=EF=F0=E5=E7=E8= =E4=E5=ED=F2=EE=E2 =F1=EE=E2=E5=F0=F8=E0=FE=F2 =F1=E0=EC=FB=E5=20 =F0=E0=E7=ED=FB=E5 =EE=EF=E0=F1=ED=FB=E5 =E4=E5=FF=ED=E8=FF =E8 "=E1=E5=E7= =E4=E5=E9=F1=F2=E2=E8=FF" =E2=EF=EB=EE=F2=FC =E4=EE =E3=E5=ED=EE=F6=E8=E4= =E0 =F1=E2=EE=E5=E3=EE =E8 =F7=F3=E6=E8=F5 =ED=E0=F0=EE=E4=EE=E2.=20 =C2=EB=E0=F1=F2=FC =F0=FF=E4=E0 =E2=FB=F1=EE=EA=EE=EF=EE=F1=F2=E0=E2=EB=E5= =ED=ED=FB=F5 =E8 =E1=EE=E3=E0=F2=FB=F5 =EB=FE=E4=E5=E9 "=EF=FF=F2=EE=E9 =EA= =EE=EB=EE=ED=ED=FB" =E8 "=F2=E0=EA=20 =ED=E0=E7=FB=E2=E0=E5=EC=EE=E3=EE =E7=E0=EA=F3=EB=E8=F1=FC=FF" =EF=F0=EE=E4= =E0=E2=EB=E8=E2=E0=E5=F2 =E7=E0=EA=EE=ED=ED=EE=F1=F2=FC =EE=E4=ED=EE=E3=EE= =E8=E7 =EE=EF=E0=F1=ED=E5=E9=F8=E8=F5 =ED=E0=F0=EA=EE=F2=E8=EA=EE=E2-=20 =E0=EB=EA=EE=E3=EE=EB=FF, =F3=F1=F2=E0=ED=E0=E2=EB=E8=E2=E0=E5=F2 =EF=F0=EE= =E3=F0=E0=EC=EC=FB =F0=E0=E7=EB=EE=E6=E5=ED=E8=FF =EB=E8=F7=ED=EE=F1=F2=E8= , =E8=ED=F1=F2=E8=F2=F3=F2=EE=E2 =F1=E5=EC=FC=E8 =E8 =F0=EE=E4=E0 =E2=20 =D1=CC=C8 =E8 =E3=EE=F1=F3=E4=E0=F0=F1=F2=E2=E5, =E4=E8=E1=E8=EB=E8=E7=E8= =F0=F3=E5=F2 =EF=F0=EE=EF=E0=E3=E0=ED=E4=EE=E9 =EA=F3=EB=FC=F2=E0 =E4=E5=ED= =E5=E3 =E8 =E2=EB=E0=F1=F2=E8 =E8 =F1=F2=F0=E0=E2=EB=E8=E2=E0=E5=F2=20 =E2 =E3=EE=F0=FF=F7=E8=F5 =E2=EE=E9=ED=E0=F5(=F5=EE=EB=EE=E4=ED=FB=E5 =F3= =E6=E5 =E4=E0=E2=ED=EE =EF=F0=EE=E8=E3=F0=E0=ED=FB)! =CE=E1=EC=E0=ED=FB=E2= =E0=FF =ED=E0=F1 =EB=EE=E6=ED=FB=EC=E8 =F6=E5=ED=ED=EE=F1=F2=FF=EC=E8=20 =E8 =EF=F0=E8=E7=FB=E2=E0=FF =EA =ED=E8=E7=EC=E5=ED=ED=FB=EC =F6=E5=EB=FF= =EC, =E2=F0=E0=E3 =EF=EE=F0=E0=E1=EE=F9=E0=E5=F2 =E8, =E2 =E8=F2=EE=E3=E5= , =E2=E5=E4=E5=F2 =ED=E0=F1 =F1 =E2=E0=EC=E8 =ED=E0=20 =E1=EE=E9=ED=FE. =CE=ED =ED=E5 =EE=F1=F2=E0=ED=EE=E2=E8=F2=F1=FF, =EF=EE=EA= =E0 =ED=E5 =E1=F3=E4=E5=F2 =EF=EE=F0=E0=E1=EE=F9=E5=ED=EE =E8=EB=E8 =E8=F1= =F2=F0=E5=E1=EB=E5=ED=EE =E2=F1=E5=20 =F7=E5=EB=EE=E2=E5=F7=E5=F1=F2=E2=EE(=ED=E0=F1=F2=F3=EF=EB=E5=ED=E8=E5 =E3= =EB=EE=E1=E0=EB=FC=ED=EE=E3=EE =F2=EE=EB=EF=EE=FD=EB=E8=F2=E0=F0=ED=EE=E3= =EE-=F0=E0=E1=F1=EA=EE=E3=EE =EE=E1=F9=E5=F1=F2=E2=E0). =CB=FE=E4=E8,=20 =F0=E0=E1=EE=F2=E0=FE=F9=E8=E5 =ED=E0 =ED=E0=F8=E5=E3=EE =E2=F0=E0=E3=E0,= =E2 =F2=EE=EC =F7=E8=F1=EB=E5 =E2=EE =E2=EB=E0=F1=F2=E8 =D1=D8=C0 =E8 =C5= =E2=F0=EE=F1=EE=FE=E7=E0, =E2=E2=E8=E4=F3 =F1=E2=EE=E8=F5=20 =ED=E5=E1=EB=E0=E3=EE=E2=E8=E4=ED=FB= =F5 =E8=ED=F2=E5=F0=E5=F1=EE=E2, =ED=E5 =EF=F0=E8=ED=E8=EC=E0=FE=F2=20 =E5=E4=E8=ED=F1=F2=E2=E5=ED=ED=EE =E2=EE=E7=EC=EE=E6=ED=EE=E5 =F3=F1=F2=F0= =EE=E9=F1=F2=E2=EE =FD=F4=F4=E5=EA=F2=E8=E2=ED=EE=E3=EE =EC=E8=F0=E0- =E2= =F1=E5=EC=FC=E5(/=E5=E4=E8=ED=EE=EC =D0=EE=E4=E5)=20 =F1=E8=EB=FC=ED=FB=F5 =ED=E0=F0=EE=E4=EE=E2, =E8=F1=EA=EB=FE=F7=E0=FE=F9=E5= =E9 =EC=E0=ED=E8=EF=F3=EB=FF=F6=E8=E8 =E8 =E3=E5=ED=EE=F6=E8=E4- =EE=E1=F9= =E5=F1=F2=E2=E5 =E0=E1=F1=EE=EB=FE=F2=ED=EE=E9=20 =EF=EE=F0=FF=E4=EE=F7=ED=EE=F1=F2=E8.

=CC=FB- =F0=F3=F1=F1=EA=E8=E9 =ED= =E0=F0=EE=E4, =F0=EE=E4=ED=FF =E8 =E4=F0=E5=E2=ED=E8=E9 =D0=EE=E4-=20 =F1=E8=EB=FC=ED=E5=E9=F8=E0=FF =E5=E4=E8=ED=E0=FF =F0=F3=F1=F1=EA=E0=FF =F6= =E8=E2=E8=EB=E8=E7=E0=F6=E8=FF =F1 "=E8=F5 =EF=EE=EC=EE=F9=FC=FE" =EF=F0=E5= =E2=F0=E0=F9=E0=E5=EC=F1=FF =E2 =E6=E8=E2=EE=F2=ED=FB=F5 =E8=20 =ED=E5 =EC=EE=E6=E5=EC =E4=E0=E6=E5 =E7=E0=F9=E8=F2=E8=F2=FC =F1=E2=EE=FE= "=F3=EA=F0=E0=E8=ED=F1=EA=F3=FE" =F7=E0=F1=F2=FC, =EF=EE=E3=F0=FF=E7=F8=F3= =FE =E2 =E3=F0=E0=E6=E4=E0=ED=F1=EA=EE=E9 =E2=EE=E9=ED=E5.=20 =CC=FB =EF=EE=E7=E2=EE=EB=E8=EB=E8 =E2=F0=E0=E3=F3 =F0=E0=E7=E4=E5=EB=E8=F2= =FC =ED=E0=F1 =E3=F0=E0=ED=E8=F6=E0=EC=E8, =F0=E0=E7=E4=E5=EB=E8=F2=FC =ED= =E0=F8=F3 =E2=E5=F0=F3, =EE=E1=F9=F3=FE =EA=F3=EB=FC=F2=F3=F0=F3,=20 =E2 =EA=EE=ED=E5=F7=ED=EE=EC =E8=F2=EE=E3=E5- =E8=E4=E5=ED=F2=E8=F7=ED=EE= =F1=F2=FC, =F1=E4=E5=EB=E0=F2=FC =EF=F0=EE=F1=F2=EE =F1=EE=F1=E5=E4=FF=EC= =E8, =E0 =EF=EE=F2=EE=EC =F7=F3=F2=FC =EB=E8 =ED=E5=20 =E2=F0=E0=E3=E0=EC=E8. =CC=FB =E2=F1=E5 =E8 =F2=E0=EA =E2=FB=EC=E8=F0=E0=E5= =EC =EE=F2 =E0=EB=EA=EE=E3=EE=EB=FF, =F0=E0=E7=F0=F3=F8=E5=ED=E8=FF =E8=ED= =F1=F2=E8=F2=F3=F2=EE=E2 =E7=E4=EE=F0=EE=E2=FB=F5=20 =F1=E5=EC=E5=E9=ED=FB=F5 =E8 =EE=E1=F9=E5=F1=F2=E2=E5=ED=ED=FB=F5 =EE=F2=ED= =EE=F8=E5=ED=E8=E9 =E8 =ED=E0=F1=E8=EB=E8=FF =E8 =ED=F3=E6=ED=EE =EE=E1=FA= =E5=E4=E8=ED=FF=F2=FC=F1=FF, =E0 =ED=E5=20 =E2=F0=E0=E6=E4=EE=E2=E0=F2=FC.=20 =C2=EC=E5=F1=F2=E5 =EC=FB =F1=EC=EE=E6=E5=EC= =EF=F0=EE=F2=E8=E2=EE=F1=F2=EE=FF=F2=FC =F1=EA=F0=FB=F2=EE=E9 =E0=E3=F0=E5= =F1=F1=E8=E8=20 =F5=EE=E7=FF=E5=E2 =E7=E0=EF=E0=E4=ED=EE=E9 =F6=E8=E2=E8=EB=E8=E7=E0=F6=E8= =E8, =F1=EE=F5=F0=E0=ED=E8=F2=FC =F1=E2=EE=E8 =F1=E5=EC=FC=E8 =EE=F2 =F0=E0= =F1=EF=E0=E4=E0 =E8 =D0=EE=E4 =EE=F2=20 =E2=FB=EC=E8=F0=E0=ED=E8=FF.

=D2=E0=EA=EE=E9 =E6=E5 =E2=FB=E1= =EE=F0 =E2=EC=E5=F1=F2=E5 =F1 =ED=E0=EC=E8 =E4=EE=EB=E6=ED=FB =F1=E4=E5=EB= =E0=F2=FC=20 =EF=E0=F2=F0=E8=EE=F2=FB =E4=F0=F3=E3=E8=F5 =F1=F2=F0=E0=ED =E8 =ED=E0=F0= =EE=E4=EE=E2. =C2 =EF=E5=F0=E2=F3=FE =EE=F7=E5=F0=E5=E4=FC =F2=E5=F5, =F7= =F2=EE =EF=F0=E5=E1=FB=E2=E0=FE=F2 =E2 =F2=E5=F7=E5=ED=E8=E5=20 =E4=EB=E8=F2=E5=EB=FC=ED=EE=E3=EE =E2=F0=E5=EC=E5=ED=E8 =EF=EE=E4 =E2=EB=E0= =F1=F2=FC=FE =ED=E0=F8=E8=F5 =E2=F0=E0=E3=EE=E2 =E8 =E2 =ED=E0=E8=E1=EE=EB= =FC=F8=E5=E9 =F1=F2=E5=EF=E5=ED=E8 =EF=EE=F1=F2=F0=E0=E4=E0=EB=E8=20 =EE=F2 =E1=EE=EB=E5=E7=ED=E5=E9 =E3=EB=EE=E1=E0=EB=FC=ED=EE=E3=EE =F3=EF=F0= =E0=E2=EB=E5=ED=E8=FF(=D1=D8=C0 =E8 =C5=E2=F0=EE=F1=EE=FE=E7), =E0 =F2=E0= =EA=E6=E5 =F1=F2=F0=E0=ED- =ED=E0=F8=E8=F5=20 =F1=EE=F1=E5=E4=E5=E9- =E0=F0=E0=E1=F1=EA=E8=E9 =EC=E8=F0, =CA=E8=F2=E0=E9= . =CA=F2=EE =E1=FB =E2=FB =ED=E8 =E1=FB=EB=E8- =EF=EE=EB=FF=EA, =EB=E8=F2= =EE=E2=E5=F6, =ED=E5=EC=E5=F6 =E8=EB=E8=20 =E0=EC=E5=F0=E8=EA=E0=ED=E5=F6- =E2=FB =E4=EE=EB=E6=ED=FB =F1=E4=E5=EB=E0= =F2=FC =E2=FB=E1=EE=F0. =C2=FB =F5=EE=F2=E8=F2=E5 =F1=E2=EE=E1=EE=E4=FB =E8= =F0=EE=E4=F1=F2=E2=E0 =F1 =EE=F1=F2=E0=EB=FC=ED=FB=EC=E8=20 =ED=E0=F0=EE=E4=E0=EC=E8 =E8=EB=E8 =E1=FB=F2=FC "=E8=F1=EA=EB=FE=F7=E8=F2= =E5=EB=FC=ED=FB=EC=E8"- =E8=F1=EF=EE=EB=FC=E7=EE=E2=E0=F2=FC=F1=FF =EA=E0= =EA =F0=E0=E1=FB =E8 =E2=F1=E5 =F0=E0=E2=ED=EE =F3=EC=E5=F0=E5=F2=FC=20 =E2 =E4=EE=EB=E3=EE=F1=F0=EE=F7=ED=EE=E9 =EF=E5=F0=F1=EF=E5=EA=F2=E8=E2=E5= ?

=CC=FB- =F2=E2=EE=F0=F6=FB =EF=EE= =F1=F3=F2=E8 =EC=E8=F0=E0 =E8 =EF=F0=E8=E7=E2=E0=ED=FB =F2=E2=EE=F0=E8=F2= =FC =E8=20 =EF=EB=EE=E4=E8=F2=FC, =E0 =ED=E5 =F0=E0=F1=F2=E2=EE=F0=FF=F2=FC=F1=FF =E8= =F3=EC=E8=F0=E0=F2=FC!

=CF=D0=CE=D1=CD=C8=D2=C5=D1=DC, = =E2=EE=E9=ED=E0 =EF=F0=EE=F2=E8=E2 =ED=E0=F1 =F3=E6=E5 =E4=E0=E2=ED=EE =E8= =E4=E5=F2,=20 =F1=F2=F0=E0=ED=FB =F1 =F0=F3=F1=F1=EA=E8=EC=E8 =ED=E0=F0=EE=E4=E0=EC=E8 = =F0=E0=E7=E4=E5=EB=E5=ED=FB =E8 =ED=E0=F1 =F3=E6=E5 =EF=FB=F2=E0=FE=F2=F1= =FF =E4=EE=E1=E8=F2=FC- =E2=E2=E5=F0=E3=ED=F3=F2=FC =E2=20 =E7=E0=E2=E8=F1=E8=EC=EE=F1=F2=FC =E8 =E8=F1=F2=F0=E5=E1=E8=F2=FC(=F7=E5=F0= =E5=E7 =F1=EC=E5=F0=F2=FC =D0=EE=E4=E0 =E8 =F1=E5=EC=FC=E8 =E8=EB=E8 =F4=E8= =E7=E8=F7=E5=F1=EA=E8).

=C2=D0=C0=C3 =D1=C8=CB=C5=CD =C8= =C1=C5=D1=CF=CE=D9=C0=C4=C5=CD, =CD=CE =D0=F3=F1=FC =E2=F1=E5=E3=E4=E0 =E1= =FB=EB=E0=20 =E8 =E5=F1=F2=FC(=EA=E0=EA =F7=E0=F1=F2=FC =F1=E2=EE=E5=E3=EE =D0=EE=E4=E0= - =F1=E2=EE=E8=F5 =EF=F0=E5=E4=EA=EE=E2-=F1=EB=E0=E2=FF=ED =E8 =E2=EF=EB=EE= =F2=FC =E4=EE "=EC=E8=F4=E8=F7=E5=F1=EA=EE=E9=20 =C3=E8=EF=E5=F0=E1=EE=F0=E5=E8") , =E4=EE=EB=E6=ED=E0 =EF=F0=EE=F1=ED=F3=F2= =FC=F1=FF =E8 =EE=F2=E2=E5=F2=E8=F2=FC =ED=E0 =E0=E3=F0=E5=F1=F1=E8=FE- =E7= =E0=F9=E8=F2=E8=F2=FC =F1=E2=EE=E8=F5 =E4=E5=F2=E5=E9 =EE=F2=20 =E2=F1=E5=F5 =F3=E3=F0=EE=E7- =EE=F2 =EF=EE=F2=E5=F0=E8 =F7=E5=EB=EE=E2=E5= =F7=E5=F1=EA=E8=F5 =F1=E2=EE=E1=EE=E4 =E4=EE =EF=EE=EB=ED=EE=E3=EE =F0=E0= =E1=F1=F2=E2=E0 =E8 =F1=EC=E5=F0=F2=E8.=20 =C0=ED=F2=E8=F7=E5=EB=EE=E2=E5=F7=ED=EE=E5 =F3=EF=F0=E0=E2=EB=E5=ED=E8=E5= =E2 =E7=E0=EF=E0=E4=ED=FB=F5 =F1=F2=F0=E0=ED=E0=F5 =F3=E6=E5 =EF=F0=E8=E2= =E5=EB=EE =EA =EE=F1=F2=E0=ED=EE=E2=EA=E5=20 =E4=E5=EC=EE=E3=F0=E0=F4=E8=F7=E5=F1=EA=EE=E3=EE =F0=EE=F1=F2=E0, =F6=E5=ED= =ED=EE=F1=F2=E8 =D0=EE=E4=E0 =EF=EE=EB=ED=EE=F1=F2=FC=FE =EF=EE=E4=E0=E2=EB= =E5=ED=FB =F0=FB=ED=EE=F7=ED=FB=EC=E8 =EE=F2=ED=EE=F8=E5=ED=E8=FF=EC=E8,=20 =EB=FE=E4=E8 =EF=F0=E5=E2=F0=E0=F9=E5=ED=FB =E2 =F0=EE=E1=EE=F2=EE=E2, =EE= =E1=F1=EB=F3=E6=E8=E2=E0=FE=F9=E8=F5 =E8=ED=F2=E5=F0=E5=F1=FB =E3=EB=EE=E1= =E0=EB=FC=ED=EE=E3=EE=20 =EE=EB=E8=E3=E0=F0=F5=E0=F2=E0.

=C0=F0=F5=E8=F2=E5=EA=F2=EE=F0=FB= (=EC=E0=F1=EE=ED=FB) =E8 =F1=F2=F0=EE=E8=F2=E5=EB=E8(=E5=E2=F0=E5=E9=F1=EA= =E8=E5=20 =EA=EB=E0=ED=FB- =F0=EE=EA=F4=E5=EB=E5=F0=FB, =F0=EE=F2=F8=E8=EB=FC=E4=FB= , =E1=E0=F0=F3=F5=E8 =E8 =EF=F0.) =E7=E0=EF=E0=E4=ED=EE=E9 =F6=E8=E2=E8=EB= =E8=E7=E0=F6=E8=E8, =E8=F5=20 =F3=EF=F0=E0=E2=EB=FF=FE=F9=E8=E5(=F2=E0=E9=ED=FB=E5 =EE=E1=F9=E5=F1=F2=E2= =E0) =E8 =E8=F5 =F5=EE=E7=FF=E8=ED =F3=E1=E8=EB=E8 =E4=E5=F1=FF=F2=EA=E8 = =EC=E8=EB=EB=E8=EE=ED=EE=E2 =F0=F3=F1=F1=EA=E8=F5 =F1=E2=EE=E8=EC=E8=20 =EF=F0=EE=E5=EA=F2=E0=EC=E8 =F0=E5=E2=EE=EB=FE=F6=E8=E9, =E3=F0=E0=E6=E4=E0= =ED=F1=EA=E8=F5 =E8 =EC=E8=F0=EE=E2=FB=F5 =E2=EE=E9=ED, =F3=E7=E0=EA=EE=ED= =E5=ED=ED=EE=E3=EE =ED=E0=F1=E8=EB=E8=FF =ED=E0=E4 =F1=E2=EE=E8=EC=E8=20 =E8 =F1=EF=E0=E8=E2=E0=ED=E8=FF(=E8=F2=EE=E3=EE- =EE=EA=EE=EB=EE =EC=E8=EB= =EB=E8=E0=F0=E4=E0 =F0=F3=F1=F1=EA=E8=F5, =F1=F7=E8=F2=E0=FF =ED=E5 =F0=EE= =E4=E8=E2=F8=E8=F5=F1=FF =E4=E5=F2=E5=E9 =F3=E1=E8=F2=FB=F5=20 =F0=EE=E4=E8=F2=E5=EB=E5=E9 =E8 =E8=F5 =EF=EE=F2=EE=EC=EA=EE=E2). =D0=F3=F1= =F1=EA=E8=E5 =ED=E5 =EC=EE=E3=F3=F2(=EF=EE =EF=F0=E0=E2=F3 =D0=EE=E4=E0 =E8= =E3=E5=ED=E5=F2=E8=F7=E5=F1=EA=E8=EC=20 =EF=F0=E8=F7=E8=ED=E0=EC) =E1=FB=F2=FC =F0=E0=E1=E0=EC=E8, =EF=EE=FD=F2=EE= =EC=F3 =CE=CD=E8 =EF=F0=E8=E3=EE=E2=EE=F0=E8=EB=E8 =E2=F1=E5=F5 =ED=E0=F1= =EA =F1=EC=E5=F0=F2=E8.

=DD=F2=EE =E2=F0=E0=E3, =EF=F0=EE= =F2=E8=E2 =EA=EE=F2=EE=F0=EE=E3=EE =E4=EE=EB=E6=ED=FB =EE=E1=FA=E5=E4=E8=ED= =E8=F2=FC=F1=FF=20 =F0=EE=E4=ED=FB=E5 =EB=FE=E4=E8, =F7=F2=EE=E1 =ED=E5 =E8=F1=F7=E5=E7=ED=F3= =F2=FC =F1 =EB=E8=F6=E0 =C7=E5=EC=EB=E8 =E8 =ED=E5 =EF=F0=E5=E2=F0=E0=F2=E8= =F2=FC=F1=FF =E2 =F0=E0=E1=EE=E2(=EA=EE=F2=EE=F0=FB=F5=20 =EF=EE=F2=EE=EC =F2=EE=E6=E5 =F3=E1=FC=FE=F2- =EF=F0=E5=E2=F0=E0=F2=FF=F2= =E2 =F0=EE=E1=EE=F2=EE=E2 =E8 =E7=E0=EC=E5=ED=FF=F2 =EC=E0=F8=E8=ED=E0=EC= =E8).

=C2=EE=E8=ED=FB =D0=F3=F1=E8!= =CD=E5 =F1=EB=F3=F8=E0=E9=F2=E5 =EF=F0=E8=EA=E0=E7=EE=E2 =EA=F0=EE=E2=E0= =E2=FB=F5=20 =EE=F4=E8=F6=E5=F0=EE=E2! =C1=F3=E4=FC=F2=E5 =EF=EE=F0=FF=E4=EE=F7=ED=FB,= =EF=EE=EB=ED=FB =F1=E8=EB=FB =E4=F3=F5=E0, =E0 =F1=EB=F3=F8=E0=E9=F2=E5 = =F2=EE=EB=FC=EA=EE =F1=E2=EE=FE=20 =F1=EE=E2=E5=F1=F2=FC!

=D1=EB=E0=E2=E0 =F2=E5=EC, =EA=F2= =EE =ED=E5 =EE=E1=EC=E0=ED=F3=EB =E8 =ED=E5 =EF=F0=E5=E4=E0=EB! =D1=EB=E0= =E2=E0=20 =F2=E5=EC, =EA=F2=EE =ED=E5 =EE=F2=E4=E0=EB =EF=F0=E8=EA=E0=E7 =F3=E1=E8=F2= =FC!

=D1=EB=E0=E2=E0 =E7=E0=F9=E8=F2=ED= =E8=EA=E0=EC =F1=E2=EE=E5=E3=EE=20 =ED=E0=F0=EE=E4=E0!

=D1=CB=C0= =C2=C0 =D0=D3=D1=C8! =D1=CB=C0=C2=C0=20 =D0=CE=C4=D3!

=C2=F1=E5, =E2 =EA=EE=EC =EE=F1=F2=E0=EB=E0=F1=FC =F1=E8= =EB=E0 =F1=EE=EF=F0=EE=F2=E8=E2=EB=FF=F2=FC=F1=FF, =EF=F0=E8=F1=EE=E5=E4=E8= =ED=FF=E9=F2=E5=F1=FC =EA =ED=E0=EC-=20

 =C2=F1=E5, =E2 =EA=EE=EC =EE= =F1=F2=E0=EB=E0=F1=FC =F1=E8=EB=E0=20 =F1=EE=EF=F0=EE=F2=E8=E2=EB=FF=F2=FC=F1=FF, =EF=F0=E8=F1=EE=E5=E4=E8=ED=FF= =E9=F2=E5=F1=FC =EA =ED=E0=EC- https://vk.com/club75017598

------=_NextPart_000_0F04_01CFD04E.A579E790-- From bounce@client25.emailb.biz Sun Sep 14 19:04:30 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: *** X-Spam-Status: No, score=3.5 required=5.0 tests=DATE_IN_PAST_24_48, HTML_IMAGE_RATIO_02,HTML_MESSAGE,NORMAL_HTTP_TO_IP,RCVD_NUMERIC_HELO autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 7023E7F4E for ; Sun, 14 Sep 2014 19:04:30 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5A298304032 for ; Sun, 14 Sep 2014 17:04:27 -0700 (PDT) X-ASG-Debug-ID: 1410739461-04cbb05488dad3f0001-NocioJ Received: from server25.emailb.biz (server25.emailb.biz [149.210.165.4]) by cuda.sgi.com with ESMTP id mzFdqY6RmbN3UghR (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sun, 14 Sep 2014 17:04:22 -0700 (PDT) X-Barracuda-Envelope-From: bounce@client25.emailb.biz X-Barracuda-Apparent-Source-IP: 149.210.165.4 Received: from localhost ([::1]:42593 helo=149.210.165.4) by server25.emailb.biz with esmtpa (Exim 4.82) (envelope-from ) id 1XTJmF-00043o-WA for xfs@oss.sgi.com; Mon, 15 Sep 2014 02:04:20 +0200 To: xfs@oss.sgi.com Subject: Season End Sale : Upto 50% off on Clother, Shoes, Toys !!! Message-ID: <7eec9658646b0362332977aa55ffe9f1@149.210.165.4> X-ASG-Orig-Subj: Season End Sale : Upto 50% off on Clother, Shoes, Toys !!! Date: Sat, 13 Sep 2014 20:11:09 +0000 From: "FlipKart Offers" Reply-To: noreply@client25.emailb.biz MIME-Version: 1.0 X-Mailer-LID: 11,5,6,9 List-Unsubscribe: X-Mailer-SID: 42 X-Mailer-Sent-By: 1 Content-Type: multipart/alternative; charset="UTF-8"; boundary="b1_259456a4f6b684460b0cd6a3ded767d9" Content-Transfer-Encoding: 8bit X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - server25.emailb.biz X-AntiAbuse: Original Domain - oss.sgi.com X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - client25.emailb.biz X-Get-Message-Sender-Via: server25.emailb.biz: authenticated_id: client25/from_h X-Barracuda-Connect: server25.emailb.biz[149.210.165.4] X-Barracuda-Start-Time: 1410739462 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.51 X-Barracuda-Spam-Status: No, SCORE=1.51 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DATE_IN_PAST_24_48, DATE_IN_PAST_24_48_2, HTML_IMAGE_RATIO_02, HTML_MESSAGE, NORMAL_HTTP_TO_IP, PLING_PLING X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9485 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 DATE_IN_PAST_24_48 Date: is 24 to 48 hours before Received: date 0.00 NORMAL_HTTP_TO_IP URI: Uses a dotted-decimal IP address in URL 0.55 HTML_IMAGE_RATIO_02 BODY: HTML has a low ratio of text to image area 0.00 HTML_MESSAGE BODY: HTML included in message 0.46 PLING_PLING Subject has lots of exclamation marks 0.48 DATE_IN_PAST_24_48_2 DATE_IN_PAST_24_48_2 --b1_259456a4f6b684460b0cd6a3ded767d9 Content-Type: text/plain; format=flowed; charset="UTF-8" Content-Transfer-Encoding: 8bit Your email client cannot read this email. To view it online, please go here: http://149.210.165.4/~client25/display.php?M=1947004&C=17353e1fdaf8141dccfd43ef4c96781e&S=42&L=6&N=6 To stop receiving these emails:http://149.210.165.4/~client25/unsubscribe.php?M=1947004&C=17353e1fdaf8141dccfd43ef4c96781e&L=6&N=42 --b1_259456a4f6b684460b0cd6a3ded767d9 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: 8bit
via-italia.jpeg p-oye.jpeg shoppertree.jpeg kidzblush.jpeg
Via Italia Girl's Layered Dress
Our Price: Rs.700
Oye Girl's A-line Dress
Our Price: Rs.699
Shoppertree Girl's Dress
Our Price: Rs.845
Kidzblush Girl's Gathered Dress
Our Price: Rs.699
kittens-21.jpeg kittens-26.jpeg willy-winkies.jpeg puma-3.jpeg
Kittens Sports Sandals
Our Price: Rs.500
Kittens Bellies
Our Price: Rs.807
Willy Winkies Flats
Our Price: Rs.755
Puma Kuris Jr Ind. Sports Shoes
Our Price: Rs.1872
miss-chase-xs.jpeg 20d-xl.jpeg cottinfab-s.jpeg reya.jpeg
Miss Chase Women's Sheath Dress
Our Price: Rs.799
20D Women's Gathered Dress
Our Price: Rs.1195
Cottinfab Women's Gathered Dress
Our Price: Rs.749
Reya Cotton Printed Dress
Our Price: Rs.699
sant-footwear-38.jpeg sant-footwear-36.jpeg pink-fp5009-sindhi-footwear-36.jpeg sindhi-footwear-40.jpeg
Sant Footwear Bellies
Our Price: Rs.449
Sant Footwear Bellies
Our Price: Rs.449
Sindhi Footwear Ballerinas Bellies
Our Price: Rs.419
Sindhi Footwear Heels
Our Price: Rs.599
Unsubscribe me from this list
--b1_259456a4f6b684460b0cd6a3ded767d9-- From david@fromorbit.com Sun Sep 14 20:47:39 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E00A87F4E for ; Sun, 14 Sep 2014 20:47:39 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id C7D148F8039 for ; Sun, 14 Sep 2014 18:47:39 -0700 (PDT) X-ASG-Debug-ID: 1410745628-04cb6c54fdadcb20001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id itmsjHbhcKAv7Hkn for ; Sun, 14 Sep 2014 18:47:09 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgApABREFlR5LCtm/2dsb2JhbABfgw2BKoIssCkGmHuFawICAQEBgQ0XeIQDAQEBAwEnExwjBQsIAw4HAwklDwUlAyETFIgiB7k8ARcYhWSJUQeDLoEdBYRblVyCUJVAg3ArL4JKAQEB Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail07.adl2.internode.on.net with ESMTP; 15 Sep 2014 11:17:07 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XTLNW-0004Xx-SA; Mon, 15 Sep 2014 11:46:54 +1000 Date: Mon, 15 Sep 2014 11:46:54 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc Message-ID: <20140915014654.GD4267@dastard> X-ASG-Orig-Subj: Re: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc References: <1410355231-50495-1-git-send-email-bfoster@redhat.com> <20140911044243.GA10111@dastard> <20140911152012.GB54638@bfoster.bfoster> <20140911211915.GA4322@dastard> <20140912195128.GA42029@bfoster.bfoster> <20140912200536.GB42029@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140912200536.GB42029@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1410745628 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9489 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 12, 2014 at 04:05:36PM -0400, Brian Foster wrote: > On Fri, Sep 12, 2014 at 03:51:29PM -0400, Brian Foster wrote: > > On Fri, Sep 12, 2014 at 07:19:15AM +1000, Dave Chinner wrote: > > > On Thu, Sep 11, 2014 at 11:20:13AM -0400, Brian Foster wrote: > > > > On Thu, Sep 11, 2014 at 02:42:43PM +1000, Dave Chinner wrote: > > > > > On Wed, Sep 10, 2014 at 09:20:26AM -0400, Brian Foster wrote: > > > > > > Hi all, > > > > > > > > > > > > Here's v2 of the collapse clean up. We refactor a bit more via the > > > > > > insertion of patch 3, otherwise it's similar to v1. This will see some > > > > > > continued testing, but it survived ~500m fsx operations overnight. > > > > > > > > > > > > Brian > > > > > > > > > > I'm not sure about the invalidation patch now. On a 1k block size > > > > > filesystem, generic/127 fails with: > > > > > > > > > > +ltp/fsx -q -l 262144 -o 65536 -S 191110531 -N 100000 -R -W fsx_std_nommap > > > > > +collapse range: 1000 to 3000 > > > > > +do_collapse_range: fallocate: Device or resource busy > > > > > > > > > > which indicates we had an invalidation failure. This is probably > > > > > exposing some other bug, but I haven't had time to look into it yet > > > > > so I don't know. .... > > > It's likely that it is leaving a dirty buffer on the page beyond EOF > > > as a result of the truncate zeroing the remainder of the page in > > > memory. ..... > ... and it just hit me that truncate dirties the buffer. ;) Exactly. ;) > So I'm > wondering if we have something like the following sequence of events for > this particular page: > > - first pwrite writes to complete page > - first collapse: xfs_collapse_file_space: dev 7:0 ino 0x43 > - flush xfs_map_blocks_alloc: dev 7:0 ino 0x43 size 0x0 offset 0x2d000 count 1024 type startoff 0xb4 startblock 32 blockcount 0x38 xfs_extlist: dev 7:0 ino 0x43 state idx 0 offset 180 block 32 count 56 flag 0 caller xfs_iextents_copy > - invalidate xfs_releasepage: dev 7:0 ino 0x43 pgoff 0x2d000 size 0x3adc0 offset 0 length 0 delalloc 0 unwritten 0 .... xfs_releasepage: dev 7:0 ino 0x43 pgoff 0x3a000 size 0x3adc0 offset 0 length 0 delalloc 0 unwritten 0 > - truncate -> dirty last buffer of page xfs_setattr: dev 7:0 ino 0x43 .... xfs_invalidatepage: dev 7:0 ino 0x43 pgoff 0x30000 size 0x30dc0 offset dc0 length 240 delalloc 0 unwritten 0 .... xfs_itruncate_extents_start: dev 7:0 ino 0x43 size 0x30dc0 new_size 0x30dc0 xfs_extlist: dev 7:0 ino 0x43 state idx 0 offset 140 block 32 count 56 flag 0 caller xfs_iextents_copy And so we have truncate dirtying the last buffer in the page (the offset/len indicated by the xfs_invalidatepage tracepoint). > - second pwrite writes to first buffer in page (dirty first buffer) > - flush > - xfs_convert_page() hits the first buffer, breaks out > and causes the last buffer to be passed over due to > the issue below > - invalidate > - finds dirty buffer, error! > > Brian > > > Brian > > > > P.S., As a datapoint from experimentation, this problem doesn't occur if > > I ensure that writepage() handles this particular page rather than > > xfs_convert_page(). I can do that by either jumping out of > > xfs_convert_page() sooner, before the page is set for writeback, or > > hacking xfs_start_page_writeback() to use __test_set_page_writeback() > > and keep the write tag such that write_cache_pages() can still find the > > page. writepage is still supposed to find the page again, because we haven't fully cleaned it. Indeed, the code used to come back and write this page because it was still dirty and the write_cache_pages() iteration would then see it and write it again because it is dirty. > > This calls out an interesting bit of behavior in > > xfs_convert_page() since commit a49935f2: if we handle a part of a > > page, break and mark the page for writeback without handling the rest, > > we'll still clear the PAGECACHE_TAG_TOWRITE tag and writeback won't > > finish off the page during the current iteration (for WB_SYNC_ALL). Right, commit a49935f2 made the assumption that the page being left dirty was sufficient to have the page written as the current writeback sweep went past it. That *used* to be the way the generic writeback code worked. And this is instructive: this same assumption was found in ext4 back in May i.e. commit 1c8349a ("ext4: fix data integrity sync in ordered mode") and that introduced the new functions like __test_set_page_writeback(). That fix wasn't cc'd to linux-fsdevel which might have got our attention and so noticed the bug earlier... > > It's not clear to me if this is contributing to the problem in this > > particular case, but it seems like an independent bug at the very > > least. Thoughts? We definitely need to use set_page_writeback_keepwrite() for partial page writes that leave the page dirty. Patch below. Cheers, Dave. -- Dave Chinner david@fromorbit.com xfs: ensure WB_SYNC_ALL writeback handles partial pages correctly From: Dave Chinner XFS has been having trouble with stray delayed allocation extents beyond EOF for a long time. Recent changes to the collapse range code has triggered erroneous EBUSY errors on page invalidtion for block size smaller than page size filesystems. These have been caused by dirty buffers beyond EOF on a partial page which do not get written to disk during a sync. The issue is that write-ahead in xfs_cluster_write() finds such a partial page and handles it by leaving the page dirty but pushing it into a writeback state. This used to work just fine, as the write_cache_pages() code would then find the dirty partial page in the next mapping tree lookup as the dirty tag is still set. Unfortunately, when we moved to a mark and sweep approach to writeback to fix other writeback sync issues, we broken this. THe act of marking the page as under writeback now clears the TOWRITE tag in the radix tree, even though the page is still dirty. This causes the TOWRITE tag to be cleared, and hence the next lookup on the mapping tree does not find the dirty partial page and so doesn't try to write it again. This same writeback bug was found recently in ext4 and fixed in commit 1c8349a ("ext4: fix data integrity sync in ordered mode") without communication to the wider filesystem community. We can use exactly the same fix here so the TOWRITE flag is not cleared on partial page writes. cc: stable@vger.kernel.org # dependent on 1c8349a17137b93f0a83f276c764a6df1b9a116e Root-cause-found-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/xfs_aops.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index b984647..2f50253 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -434,10 +434,22 @@ xfs_start_page_writeback( { ASSERT(PageLocked(page)); ASSERT(!PageWriteback(page)); - if (clear_dirty) + + /* + * if the page was not fully cleaned, we need to ensure that the higher + * layers come back to it correctly. That means we need to keep the page + * dirty, and for WB_SYNC_ALL writeback we need to ensure the + * PAGECACHE_TAG_TOWRITE index mark is not removed so another attempt to + * write this page in this writeback sweep will be made. + */ + if (clear_dirty) { clear_page_dirty_for_io(page); - set_page_writeback(page); + set_page_writeback(page); + } else + set_page_writeback_keepwrite(page); + unlock_page(page); + /* If no buffers on the page are to be written, finish it here */ if (!buffers) end_page_writeback(page); From olaf@sgi.com Mon Sep 15 02:16:30 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B4A6E7F4E for ; Mon, 15 Sep 2014 02:16:30 -0500 (CDT) Received: from xmail.sgi.com (pv-excas1-dc21.corp.sgi.com [137.38.106.7]) by relay1.corp.sgi.com (Postfix) with ESMTP id 91B588F8040; Mon, 15 Sep 2014 00:16:27 -0700 (PDT) Received: from [144.253.208.65] (144.253.208.65) by xmail.sgi.com (137.38.106.6) with Microsoft SMTP Server (TLS) id 14.3.195.1; Mon, 15 Sep 2014 02:16:26 -0500 Message-ID: <54169248.1090105@sgi.com> Date: Mon, 15 Sep 2014 09:16:24 +0200 From: Olaf Weber Organization: SGI User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.1 MIME-Version: 1.0 To: Christoph Hellwig CC: Dave Chinner , Ben Myers , , Subject: Re: [RFC] Unicode/UTF-8 support for XFS References: <20140911203735.GA19952@sgi.com> <20140912100230.GB4267@dastard> <5412DF37.9030005@sgi.com> <20140912205528.GB11717@infradead.org> In-Reply-To: <20140912205528.GB11717@infradead.org> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [144.253.208.65] On 12-09-14 22:55, Christoph Hellwig wrote: > On Fri, Sep 12, 2014 at 01:55:35PM +0200, Olaf Weber wrote: >> I looked up those discussions in the archives. For example, here's >> Christoph about rejecting filenames if they're not well-formed unicode. >> http://marc.info/?l=linux-fsdevel&m=120876935526856&w=2 >> And Jamie Lokier making a similar point: >> http://oss.sgi.com/archives/xfs/2008-04/msg01263.html > > And I might now disagree with my past self. While non-ut8 characters > are perfectly valid unix filenames, and I think everyones life is easier > if we generally stay out of the utf8 business it seems that for this > particular use case (shared filesystem with Windows, right) just > accepting utf8 should be fine. ZFS is doing, MacOS X apparently is, > and NFSv4 requires it, although as far as I know most implementations > ignore that requirement. > One issue is working in environments that are not UTF-8 clean. For example, unpacking a tarball with non-UTF-8 filenames in it. The names would have to be transcoded, which is only really possible if you know the original character set. And if the filesystem flat out rejects non-UTF-8 filenames, then you'd be unable to unpack the tarball at all. -- Olaf Weber SGI Phone: +31(0)30-6696796 Veldzigt 2b Fax: +31(0)30-6696799 Technical Lead 3454 PW de Meern Vnet: 955-6796 Storage Software The Netherlands Email: olaf@sgi.com From bfoster@redhat.com Mon Sep 15 08:18:37 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id E410A7F4E for ; Mon, 15 Sep 2014 08:18:37 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id B5863304059 for ; Mon, 15 Sep 2014 06:18:34 -0700 (PDT) X-ASG-Debug-ID: 1410787113-04bdf0109aa74600001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id f590P2BDMVvCONPO (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 15 Sep 2014 06:18:33 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8FDIPEj023976 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 15 Sep 2014 09:18:25 -0400 Received: from laptop.bfoster (vpn-51-35.rdu2.redhat.com [10.10.51.35]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8FDIMwh026767 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Mon, 15 Sep 2014 09:18:24 -0400 Date: Mon, 15 Sep 2014 09:18:22 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc Message-ID: <20140915131822.GA4143@laptop.bfoster> X-ASG-Orig-Subj: Re: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc References: <1410355231-50495-1-git-send-email-bfoster@redhat.com> <20140911044243.GA10111@dastard> <20140911152012.GB54638@bfoster.bfoster> <20140911211915.GA4322@dastard> <20140912195128.GA42029@bfoster.bfoster> <20140912200536.GB42029@bfoster.bfoster> <20140915014654.GD4267@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140915014654.GD4267@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410787113 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Sep 15, 2014 at 11:46:54AM +1000, Dave Chinner wrote: > On Fri, Sep 12, 2014 at 04:05:36PM -0400, Brian Foster wrote: > > On Fri, Sep 12, 2014 at 03:51:29PM -0400, Brian Foster wrote: > > > On Fri, Sep 12, 2014 at 07:19:15AM +1000, Dave Chinner wrote: > > > > On Thu, Sep 11, 2014 at 11:20:13AM -0400, Brian Foster wrote: > > > > > On Thu, Sep 11, 2014 at 02:42:43PM +1000, Dave Chinner wrote: > > > > > > On Wed, Sep 10, 2014 at 09:20:26AM -0400, Brian Foster wrote: > > > > > > > Hi all, > > > > > > > > > > > > > > Here's v2 of the collapse clean up. We refactor a bit more via the > > > > > > > insertion of patch 3, otherwise it's similar to v1. This will see some > > > > > > > continued testing, but it survived ~500m fsx operations overnight. > > > > > > > > > > > > > > Brian > > > > > > > > > > > > I'm not sure about the invalidation patch now. On a 1k block size > > > > > > filesystem, generic/127 fails with: > > > > > > > > > > > > +ltp/fsx -q -l 262144 -o 65536 -S 191110531 -N 100000 -R -W fsx_std_nommap > > > > > > +collapse range: 1000 to 3000 > > > > > > +do_collapse_range: fallocate: Device or resource busy > > > > > > > > > > > > which indicates we had an invalidation failure. This is probably > > > > > > exposing some other bug, but I haven't had time to look into it yet > > > > > > so I don't know. > > .... > > > > > It's likely that it is leaving a dirty buffer on the page beyond EOF > > > > as a result of the truncate zeroing the remainder of the page in > > > > memory. > ..... > > > ... and it just hit me that truncate dirties the buffer. ;) > > Exactly. ;) > > > So I'm > > wondering if we have something like the following sequence of events for > > this particular page: > > > > - first pwrite writes to complete page > > - first collapse: > > xfs_collapse_file_space: dev 7:0 ino 0x43 > > > - flush > > xfs_map_blocks_alloc: dev 7:0 ino 0x43 size 0x0 offset 0x2d000 count 1024 type startoff 0xb4 startblock 32 blockcount 0x38 > xfs_extlist: dev 7:0 ino 0x43 state idx 0 offset 180 block 32 count 56 flag 0 caller xfs_iextents_copy > > > - invalidate > > xfs_releasepage: dev 7:0 ino 0x43 pgoff 0x2d000 size 0x3adc0 offset 0 length 0 delalloc 0 unwritten 0 > .... > xfs_releasepage: dev 7:0 ino 0x43 pgoff 0x3a000 size 0x3adc0 offset 0 length 0 delalloc 0 unwritten 0 > > > - truncate -> dirty last buffer of page > > xfs_setattr: dev 7:0 ino 0x43 > .... > xfs_invalidatepage: dev 7:0 ino 0x43 pgoff 0x30000 size 0x30dc0 offset dc0 length 240 delalloc 0 unwritten 0 > .... > xfs_itruncate_extents_start: dev 7:0 ino 0x43 size 0x30dc0 new_size 0x30dc0 > xfs_extlist: dev 7:0 ino 0x43 state idx 0 offset 140 block 32 count 56 flag 0 caller xfs_iextents_copy > > And so we have truncate dirtying the last buffer in the page (the > offset/len indicated by the xfs_invalidatepage tracepoint). > > > - second pwrite writes to first buffer in page (dirty first buffer) > > - flush > > - xfs_convert_page() hits the first buffer, breaks out > > and causes the last buffer to be passed over due to > > the issue below > > - invalidate > > - finds dirty buffer, error! > > > > Brian > > > > > Brian > > > > > > P.S., As a datapoint from experimentation, this problem doesn't occur if > > > I ensure that writepage() handles this particular page rather than > > > xfs_convert_page(). I can do that by either jumping out of > > > xfs_convert_page() sooner, before the page is set for writeback, or > > > hacking xfs_start_page_writeback() to use __test_set_page_writeback() > > > and keep the write tag such that write_cache_pages() can still find the > > > page. > > writepage is still supposed to find the page again, because we > haven't fully cleaned it. Indeed, the code used to come back and > write this page because it was still dirty and the > write_cache_pages() iteration would then see it and write it again > because it is dirty. > > > > This calls out an interesting bit of behavior in > > > xfs_convert_page() since commit a49935f2: if we handle a part of a > > > page, break and mark the page for writeback without handling the rest, > > > we'll still clear the PAGECACHE_TAG_TOWRITE tag and writeback won't > > > finish off the page during the current iteration (for WB_SYNC_ALL). > > Right, commit a49935f2 made the assumption that the page being left > dirty was sufficient to have the page written as the current > writeback sweep went past it. That *used* to be the way the generic > writeback code worked. > > And this is instructive: this same assumption was found in ext4 back > in May i.e. commit 1c8349a ("ext4: fix data integrity sync in > ordered mode") and that introduced the new functions like > __test_set_page_writeback(). That fix wasn't cc'd to linux-fsdevel > which might have got our attention and so noticed the bug earlier... > > > > It's not clear to me if this is contributing to the problem in this > > > particular case, but it seems like an independent bug at the very > > > least. Thoughts? > > We definitely need to use set_page_writeback_keepwrite() for partial > page writes that leave the page dirty. Patch below. > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > xfs: ensure WB_SYNC_ALL writeback handles partial pages correctly > > From: Dave Chinner > > XFS has been having trouble with stray delayed allocation extents > beyond EOF for a long time. Recent changes to the collapse range > code has triggered erroneous EBUSY errors on page invalidtion for > block size smaller than page size filesystems. These > have been caused by dirty buffers beyond EOF on a partial page which > do not get written to disk during a sync. > > The issue is that write-ahead in xfs_cluster_write() finds such a > partial page and handles it by leaving the page dirty but pushing it > into a writeback state. This used to work just fine, as the > write_cache_pages() code would then find the dirty partial page in > the next mapping tree lookup as the dirty tag is still set. > > Unfortunately, when we moved to a mark and sweep approach to > writeback to fix other writeback sync issues, we broken this. THe > act of marking the page as under writeback now clears the TOWRITE > tag in the radix tree, even though the page is still dirty. This > causes the TOWRITE tag to be cleared, and hence the next lookup on > the mapping tree does not find the dirty partial page and so doesn't > try to write it again. > > This same writeback bug was found recently in ext4 and fixed in > commit 1c8349a ("ext4: fix data integrity sync in ordered mode") > without communication to the wider filesystem community. We can use > exactly the same fix here so the TOWRITE flag is not cleared on > partial page writes. > > cc: stable@vger.kernel.org # dependent on 1c8349a17137b93f0a83f276c764a6df1b9a116e > Root-cause-found-by: Brian Foster > Signed-off-by: Dave Chinner > --- Looks good and fixes the collapse failure in my test. Reviewed-by: Brian Foster I suppose we should prepend the collapse rework series with this patch to avoid the regression as it pertains to collapse (obviously the failure to retain towrite goes further back). I'll continue testing with this. Are you still seeing an increase in such failures with the xfs_free_file_space() patch or has this quieted those down? Brian > fs/xfs/xfs_aops.c | 16 ++++++++++++++-- > 1 file changed, 14 insertions(+), 2 deletions(-) > > diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c > index b984647..2f50253 100644 > --- a/fs/xfs/xfs_aops.c > +++ b/fs/xfs/xfs_aops.c > @@ -434,10 +434,22 @@ xfs_start_page_writeback( > { > ASSERT(PageLocked(page)); > ASSERT(!PageWriteback(page)); > - if (clear_dirty) > + > + /* > + * if the page was not fully cleaned, we need to ensure that the higher > + * layers come back to it correctly. That means we need to keep the page > + * dirty, and for WB_SYNC_ALL writeback we need to ensure the > + * PAGECACHE_TAG_TOWRITE index mark is not removed so another attempt to > + * write this page in this writeback sweep will be made. > + */ > + if (clear_dirty) { > clear_page_dirty_for_io(page); > - set_page_writeback(page); > + set_page_writeback(page); > + } else > + set_page_writeback_keepwrite(page); > + > unlock_page(page); > + > /* If no buffers on the page are to be written, finish it here */ > if (!buffers) > end_page_writeback(page); > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From sandeen@redhat.com Mon Sep 15 16:26:53 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 1AA6C7F4E for ; Mon, 15 Sep 2014 16:26:53 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id EDCFB8F8052 for ; Mon, 15 Sep 2014 14:26:49 -0700 (PDT) X-ASG-Debug-ID: 1410816407-04bdf0109aa93110001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id dHoXCZMWK3RZUQiW (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 15 Sep 2014 14:26:47 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8FLQlE1012915 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Mon, 15 Sep 2014 17:26:47 -0400 Received: from liberator.sandeen.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8FLQjZI020572 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Mon, 15 Sep 2014 17:26:46 -0400 Message-ID: <54175996.10303@redhat.com> Date: Mon, 15 Sep 2014 16:26:46 -0500 From: Eric Sandeen MIME-Version: 1.0 To: xfs-oss Subject: [PATCH] xfsprogs: add supported file attributes to xfs.5 manpage Content-Type: text/plain; charset=utf-8 X-ASG-Orig-Subj: [PATCH] xfsprogs: add supported file attributes to xfs.5 manpage Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410816407 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The chattr(1) manpage suffers from the same problems mount(1) had: many options listed, not kept up to date for various filesystems. I've submitted a manpage update for chattr(1) which says to refer to filesystem-specific manpages for supported attributes; this patch updates xfs(5) to list the attributes supported by xfs. Signed-off-by: Eric Sandeen --- diff --git a/man/man5/xfs.5 b/man/man5/xfs.5 index 5e47c4c..3214455 100644 --- a/man/man5/xfs.5 +++ b/man/man5/xfs.5 @@ -1,6 +1,6 @@ .TH xfs 5 .SH NAME -xfs \- layout and mount options for the XFS filesystem +xfs \- layout, mount options, and supported file attributes for the XFS filesystem .SH DESCRIPTION An XFS filesystem can reside on a regular disk partition or on a logical volume. @@ -302,7 +302,27 @@ namespace is on stable storage. This is useful in HA setups where failover must not result in clients seeing inconsistent namespace presentation during or after a failover event. +.SH FILE ATTRIBUTES +The XFS filesystem supports setting the following file +attributes on Linux systems using the +.BR chattr (1) +utility: +.sp +.BR a " - append only" +.sp +.BR A " - no atime updates" +.sp +.BR d " - no dump" +.sp +.BR i " - immutable" +.sp +.BR S " - synchronous updates" +.sp +For descriptions of these attribute flags, please refer to the +.BR chattr (1) +man page. .SH SEE ALSO +.BR chattr (1), .BR xfsctl (3), .BR mount (8), .BR mkfs.xfs (8), From david@fromorbit.com Mon Sep 15 17:55:41 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 5327B7F4E for ; Mon, 15 Sep 2014 17:55:41 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0F4E08F8068 for ; Mon, 15 Sep 2014 15:55:40 -0700 (PDT) X-ASG-Debug-ID: 1410821738-04bdf01097a96c40001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id uB2AwDjotk8E6hcu for ; Mon, 15 Sep 2014 15:55:39 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtZDACJtF1R5LCtmPGdsb2JhbABggw2BKoczrCAGmHqFawICAQEBgRoXBQEBAQE4N4QDAQEBAwE6DQ8jBQsIAw4HAwklDwUlAwcaExSIIgeqbpBCGBiFZIlRB4MugR0FnQeZMCsvgkoBAQE Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail04.adl6.internode.on.net with ESMTP; 16 Sep 2014 08:25:37 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XTfBH-00089C-AO; Tue, 16 Sep 2014 08:55:35 +1000 Date: Tue, 16 Sep 2014 08:55:35 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc Message-ID: <20140915225535.GF4267@dastard> X-ASG-Orig-Subj: Re: [PATCH v2 0/5] clean up collapse range and handle post-eof delalloc References: <1410355231-50495-1-git-send-email-bfoster@redhat.com> <20140911044243.GA10111@dastard> <20140911152012.GB54638@bfoster.bfoster> <20140911211915.GA4322@dastard> <20140912195128.GA42029@bfoster.bfoster> <20140912200536.GB42029@bfoster.bfoster> <20140915014654.GD4267@dastard> <20140915131822.GA4143@laptop.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140915131822.GA4143@laptop.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1410821738 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9528 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Sep 15, 2014 at 09:18:22AM -0400, Brian Foster wrote: > On Mon, Sep 15, 2014 at 11:46:54AM +1000, Dave Chinner wrote: > > xfs: ensure WB_SYNC_ALL writeback handles partial pages correctly > > > > From: Dave Chinner > > > > XFS has been having trouble with stray delayed allocation extents > > beyond EOF for a long time. Recent changes to the collapse range > > code has triggered erroneous EBUSY errors on page invalidtion for > > block size smaller than page size filesystems. These > > have been caused by dirty buffers beyond EOF on a partial page which > > do not get written to disk during a sync. > > > > The issue is that write-ahead in xfs_cluster_write() finds such a > > partial page and handles it by leaving the page dirty but pushing it > > into a writeback state. This used to work just fine, as the > > write_cache_pages() code would then find the dirty partial page in > > the next mapping tree lookup as the dirty tag is still set. > > > > Unfortunately, when we moved to a mark and sweep approach to > > writeback to fix other writeback sync issues, we broken this. THe > > act of marking the page as under writeback now clears the TOWRITE > > tag in the radix tree, even though the page is still dirty. This > > causes the TOWRITE tag to be cleared, and hence the next lookup on > > the mapping tree does not find the dirty partial page and so doesn't > > try to write it again. > > > > This same writeback bug was found recently in ext4 and fixed in > > commit 1c8349a ("ext4: fix data integrity sync in ordered mode") > > without communication to the wider filesystem community. We can use > > exactly the same fix here so the TOWRITE flag is not cleared on > > partial page writes. > > > > cc: stable@vger.kernel.org # dependent on 1c8349a17137b93f0a83f276c764a6df1b9a116e > > Root-cause-found-by: Brian Foster > > Signed-off-by: Dave Chinner > > --- > > Looks good and fixes the collapse failure in my test. > > Reviewed-by: Brian Foster > > I suppose we should prepend the collapse rework series with this patch > to avoid the regression as it pertains to collapse (obviously the > failure to retain towrite goes further back). Agreed, I will do that. > I'll continue testing with this. Are you still seeing an increase in > such failures with the xfs_free_file_space() patch or has this quieted > those down? To early to sayi for sure, but signs are good - I've had xfstests actually complete without any stray delalloc asserts occurring on 1k block size filesystems for the first time in a couple of weeks. Cheers, Dave. -- Dave Chinner david@fromorbit.com From debbugs@buxtehude.debian.org Mon Sep 15 18:09:19 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=3.0 required=5.0 tests=TVD_SUBJ_NUM_OBFU_MINFP autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 74CD47F51 for ; Mon, 15 Sep 2014 18:09:19 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 61B2F304039 for ; Mon, 15 Sep 2014 16:09:16 -0700 (PDT) X-ASG-Debug-ID: 1410822554-04cbb05488de4880001-NocioJ Received: from buxtehude.debian.org (buxtehude.debian.org [140.211.166.26]) by cuda.sgi.com with ESMTP id ZH82HLfGA0rFkojy (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO) for ; Mon, 15 Sep 2014 16:09:14 -0700 (PDT) X-Barracuda-Envelope-From: debbugs@buxtehude.debian.org X-Barracuda-Apparent-Source-IP: 140.211.166.26 Received: from debbugs by buxtehude.debian.org with local (Exim 4.80) (envelope-from ) id 1XTfOR-00067a-Sk; Mon, 15 Sep 2014 23:09:11 +0000 X-Loop: owner@bugs.debian.org Subject: Bug#757455: please run dh_autoreconf or manually update m4/libtool.m4 for ppc64el Reply-To: Dave Chinner , 757455@bugs.debian.org X-ASG-Orig-Subj: Bug#757455: please run dh_autoreconf or manually update m4/libtool.m4 for ppc64el Resent-From: Dave Chinner Resent-To: debian-bugs-dist@lists.debian.org Resent-Cc: XFS Development Team X-Loop: owner@bugs.debian.org Resent-Date: Mon, 15 Sep 2014 23:09:08 +0000 Resent-Message-ID: X-Debian-PR-Message: followup 757455 X-Debian-PR-Package: src:xfsprogs X-Debian-PR-Keywords: X-Debian-PR-Source: xfsprogs Received: via spool by 757455-submit@bugs.debian.org id=B757455.141082230222068 (code B ref 757455); Mon, 15 Sep 2014 23:09:08 +0000 Received: (at 757455) by bugs.debian.org; 15 Sep 2014 23:05:02 +0000 Received: from ipmail04.adl6.internode.on.net ([150.101.137.141]) by buxtehude.debian.org with esmtp (Exim 4.80) (envelope-from ) id 1XTfKQ-0005jM-FI for 757455@bugs.debian.org; Mon, 15 Sep 2014 23:05:02 +0000 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AopDALdvF1R5LCtmPGdsb2JhbABggw1TV7NUBpcZgWGFawICAQEBgRsXBQEBAQE4N4QEAQEEOhwjEAgDDgoJJQ8FJQMHAxcBEog9uywBFxiFZIdBghAHhEsFlgSHA4wxiyqBVSsvgkoBAQE Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail04.adl6.internode.on.net with ESMTP; 16 Sep 2014 08:34:58 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XTfKK-0008D3-V3; Tue, 16 Sep 2014 09:04:57 +1000 Date: Tue, 16 Sep 2014 09:04:56 +1000 From: Dave Chinner To: Andreas Barth , 757455@bugs.debian.org Cc: Matthias Klose Message-ID: <20140915230456.GG4267@dastard> References: <53E4C0A5.8060704@debian.org> <20140910142226.GA32059@mails.so.argh.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140910142226.GA32059@mails.so.argh.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: buxtehude.debian.org[140.211.166.26] X-Barracuda-Start-Time: 1410822554 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9528 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Sep 10, 2014 at 04:22:26PM +0200, Andreas Barth wrote: > * Matthias Klose (doko@debian.org) [140910 14:19]: > > trying to use dh_autoreconf: > > It works with the following patch: > diff -ur xfsprogs-3.2.1~/debian/control xfsprogs-3.2.1/debian/control > --- xfsprogs-3.2.1~/debian/control 2014-05-02 00:09:15.000000000 +0000 > +++ xfsprogs-3.2.1/debian/control 2014-09-10 14:14:34.026319172 +0000 > @@ -3,7 +3,7 @@ > Priority: optional > Maintainer: XFS Development Team > Uploaders: Nathan Scott , Anibal Monsalve Salazar > -Build-Depends: uuid-dev, autoconf, debhelper (>= 5), gettext, libtool, libreadline-gplv2-dev | libreadline5-dev, libblkid-dev (>= 2.17), linux-libc-dev, autotools-dev > +Build-Depends: uuid-dev, dh-autoreconf, debhelper (>= 5), gettext, libtool, libreadline-gplv2-dev | libreadline5-dev, libblkid-dev (>= 2.17), linux-libc-dev > Standards-Version: 3.9.1 > Homepage: http://oss.sgi.com/projects/xfs/ > > diff -ur xfsprogs-3.2.1~/debian/rules xfsprogs-3.2.1/debian/rules > --- xfsprogs-3.2.1~/debian/rules 2014-05-02 00:09:15.000000000 +0000 > +++ xfsprogs-3.2.1/debian/rules 2014-09-10 14:13:18.182294515 +0000 > @@ -35,7 +35,7 @@ > .census: > @echo "== dpkg-buildpackage: configure" 1>&2 > $(checkdir) > - dh_autotools-dev_updateconfig > + AUTOHEADER=/bin/true dh_autoreconf > $(options) $(MAKE) include/platform_defs.h > touch .census > > @@ -58,7 +58,7 @@ > $(MAKE) distclean > -rm -rf $(dirme) $(dirdev) $(dirdi) > -rm -f debian/*substvars debian/files* debian/*.debhelper > - dh_autotools-dev_restoreconfig > + dh_autoreconf_clean > dh_clean > > binary-indep: > > As this package is required to build ceph, libvirt and redhat-cluster > I'd be willing to help fixing it, if required also by an NMU. Unless > there is a reason why not, I intend to upload the fix within the next > days. The debian packaging is maintained in the upstream repository. Can you please send the patch to xfs@oss.sgi.com with a commit message and a SOB so we can apply it? Cheers, Dave. -- Dave Chinner david@fromorbit.com From janecek@atrey.karlin.mff.cuni.cz Mon Sep 15 22:52:40 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id EB7137F53 for ; Mon, 15 Sep 2014 22:52:39 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9A1608F8039 for ; Mon, 15 Sep 2014 20:52:36 -0700 (PDT) X-ASG-Debug-ID: 1410839552-04bdf010a0aa3180001-NocioJ Received: from atrey.karlin.mff.cuni.cz (atrey.karlin.mff.cuni.cz [195.113.26.193]) by cuda.sgi.com with ESMTP id XOXT1BTqWUF29aKr for ; Mon, 15 Sep 2014 20:52:33 -0700 (PDT) X-Barracuda-Envelope-From: janecek@atrey.karlin.mff.cuni.cz X-Barracuda-Apparent-Source-IP: 195.113.26.193 Received: by atrey.karlin.mff.cuni.cz (Postfix, from userid 16216) id 9A64E81C2B; Tue, 16 Sep 2014 05:52:31 +0200 (CEST) Date: Tue, 16 Sep 2014 05:52:31 +0200 From: Petr Janecek To: xfs@oss.sgi.com Subject: possible irq lock inversion dependency detected on 3.16.2 Message-ID: <20140916035230.GA7100@atrey.karlin.mff.cuni.cz> X-ASG-Orig-Subj: possible irq lock inversion dependency detected on 3.16.2 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: atrey.karlin.mff.cuni.cz[195.113.26.193] X-Barracuda-Start-Time: 1410839552 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9534 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hello, this happened during nightly ext4 -> xfs rsync, both of them on lvm on md raid1. I would happily provide more info if needed. Probably not easy to reproduce, same job has been running daily since January. Regards, Petr [ 5935.518518] [ INFO: possible irq lock inversion dependency detected ] [ 5935.524971] 3.16.2 #59 Not tainted [ 5935.528381] --------------------------------------------------------- [ 5935.534826] kswapd0/66 just changed the state of lock: [ 5935.539999] (&xfs_dir_ilock_class){++++-+}, at: [] xfs_ilock+0x9a/0xda [xfs] [ 5935.548866] but this lock took another, RECLAIM_FS-unsafe lock in the past: [ 5935.555862] (&mm->mmap_sem){++++++} [ 5935.555862] [ 5935.555862] and interrupts could create inverse lock ordering between them. [ 5935.555862] [ 5935.565508] [ 5935.565508] other info that might help us debug this: [ 5935.572057] Possible interrupt unsafe locking scenario: [ 5935.572057] [ 5935.578880] CPU0 CPU1 [ 5935.583438] ---- ---- [ 5935.587994] lock(&mm->mmap_sem); [ 5935.591459] local_irq_disable(); [ 5935.597399] lock(&xfs_dir_ilock_class); [ 5935.603991] lock(&mm->mmap_sem); [ 5935.609976] [ 5935.612619] lock(&xfs_dir_ilock_class); [ 5935.616864] [ 5935.616864] *** DEADLOCK *** [ 5935.616864] [ 5935.622834] 3 locks held by kswapd0/66: [ 5935.626695] #0: (shrinker_rwsem){++++..}, at: [] shrink_slab+0x39/0x137 [ 5935.635209] #1: (&type->s_umount_key#30){.+.+.+}, at: [] grab_super_passive+0x4c/0x76 [ 5935.644963] #2: (&pag->pag_ici_reclaim_lock){+.+...}, at: [] xfs_reclaim_inodes_ag+0x6a/0x279 [xfs] [ 5935.655929] [ 5935.655929] the shortest dependencies between 2nd lock and 1st lock: [ 5935.663824] -> (&mm->mmap_sem){++++++} ops: 488821045 { [ 5935.669303] HARDIRQ-ON-W at: [ 5935.672577] [] __lock_acquire+0x345/0xe77 [ 5935.680130] [] lock_acquire+0xd8/0x11a [ 5935.687415] [] down_write+0x3f/0x5b [ 5935.694432] [] do_execve_common.isra.27+0x25a/0x5ca [ 5935.702850] [] do_execve+0x13/0x15 [ 5935.709781] [] run_init_process+0x26/0x28 [ 5935.717333] [] kernel_init+0x3d/0xda [ 5935.724436] [] ret_from_fork+0x7c/0xb0 [ 5935.731722] HARDIRQ-ON-R at: [ 5935.735056] [] __lock_acquire+0x31c/0xe77 [ 5935.742634] [] lock_acquire+0xd8/0x11a [ 5935.749920] [] might_fault+0x82/0xa5 [ 5935.757023] [] __clear_user+0x12/0x56 [ 5935.764213] [] clear_user+0x29/0x2b [ 5935.771228] [] padzero+0x1e/0x2b [ 5935.777984] [] load_elf_binary+0x920/0xd15 [ 5935.785693] [] search_binary_handler+0x6f/0x167 [ 5935.793862] [] load_script+0x1aa/0x1bc [ 5935.801145] [] search_binary_handler+0x6f/0x167 [ 5935.809264] [] do_execve_common.isra.27+0x43c/0x5ca [ 5935.817682] [] do_execve+0x13/0x15 [ 5935.824654] [] run_init_process+0x26/0x28 [ 5935.832200] [] kernel_init+0x3d/0xda [ 5935.839327] [] ret_from_fork+0x7c/0xb0 [ 5935.846646] SOFTIRQ-ON-W at: [ 5935.849922] [] __lock_acquire+0x367/0xe77 [ 5935.857509] [] lock_acquire+0xd8/0x11a [ 5935.864803] [] down_write+0x3f/0x5b [ 5935.871820] [] do_execve_common.isra.27+0x25a/0x5ca [ 5935.880230] [] do_execve+0x13/0x15 [ 5935.887219] [] run_init_process+0x26/0x28 [ 5935.900221] [] kernel_init+0x3d/0xda [ 5935.907359] [] ret_from_fork+0x7c/0xb0 [ 5935.914730] SOFTIRQ-ON-R at: [ 5935.918005] [] __lock_acquire+0x367/0xe77 [ 5935.925593] [] lock_acquire+0xd8/0x11a [ 5935.932877] [] might_fault+0x82/0xa5 [ 5935.939970] [] __clear_user+0x12/0x56 [ 5935.947160] [] clear_user+0x29/0x2b [ 5935.954176] [] padzero+0x1e/0x2b [ 5935.960932] [] load_elf_binary+0x920/0xd15 [ 5935.968564] [] search_binary_handler+0x6f/0x167 [ 5935.976628] [] load_script+0x1aa/0x1bc [ 5935.983914] [] search_binary_handler+0x6f/0x167 [ 5935.991995] [] do_execve_common.isra.27+0x43c/0x5ca [ 5936.000413] [] do_execve+0x13/0x15 [ 5936.007344] [] run_init_process+0x26/0x28 [ 5936.014913] [] kernel_init+0x3d/0xda [ 5936.022052] [] ret_from_fork+0x7c/0xb0 [ 5936.029337] RECLAIM_FS-ON-W at: [ 5936.032868] [] mark_held_locks+0x54/0x76 [ 5936.040583] [] lockdep_trace_alloc+0xc3/0xcd [ 5936.048643] [] __alloc_pages_nodemask+0x8d/0x878 [ 5936.057123] [] alloc_pages_current+0xc9/0xe6 [ 5936.065177] [] __pmd_alloc+0x1d/0xec [ 5936.072541] [] move_page_tables+0x1b0/0x505 [ 5936.080528] [] shift_arg_pages+0xa3/0x14d [ 5936.088358] [] setup_arg_pages+0x1c0/0x1f0 [ 5936.096240] [] load_elf_binary+0x397/0xd15 [ 5936.104123] [] search_binary_handler+0x6f/0x167 [ 5936.112437] [] load_script+0x1aa/0x1bc [ 5936.119966] [] search_binary_handler+0x6f/0x167 [ 5936.128290] [] do_execve_common.isra.27+0x43c/0x5ca [ 5936.136951] [] do_execve+0x13/0x15 [ 5936.144124] [] run_init_process+0x26/0x28 [ 5936.151919] [] kernel_init+0x3d/0xda [ 5936.159272] [] ret_from_fork+0x7c/0xb0 [ 5936.166826] RECLAIM_FS-ON-R at: [ 5936.170351] [] mark_held_locks+0x54/0x76 [ 5936.178070] [] lockdep_trace_alloc+0xc3/0xcd [ 5936.186125] [] __alloc_pages_nodemask+0x8d/0x878 [ 5936.194535] [] alloc_pages_current+0xc9/0xe6 [ 5936.202590] [] __get_free_pages+0x9/0x36 [ 5936.210300] [] get_zeroed_page+0x11/0x13 [ 5936.218010] [] __pud_alloc+0x1b/0x76 [ 5936.225373] [] pud_alloc+0x25/0x30 [ 5936.232545] [] handle_mm_fault+0x98/0x818 [ 5936.240340] [] __do_page_fault+0x36f/0x3bb [ 5936.248221] [] do_page_fault+0xc/0xe [ 5936.255584] [] page_fault+0x22/0x30 [ 5936.262853] [] clear_user+0x29/0x2b [ 5936.270129] [] padzero+0x1e/0x2b [ 5936.277128] [] load_elf_binary+0x920/0xd15 [ 5936.285010] [] search_binary_handler+0x6f/0x167 [ 5936.293325] [] load_script+0x1aa/0x1bc [ 5936.300852] [] search_binary_handler+0x6f/0x167 [ 5936.309168] [] do_execve_common.isra.27+0x43c/0x5ca [ 5936.317829] [] do_execve+0x13/0x15 [ 5936.325002] [] run_init_process+0x26/0x28 [ 5936.332797] [] kernel_init+0x3d/0xda [ 5936.340152] [] ret_from_fork+0x7c/0xb0 [ 5936.347686] INITIAL USE at: [ 5936.350866] [] __lock_acquire+0x3ae/0xe77 [ 5936.358308] [] lock_acquire+0xd8/0x11a [ 5936.365478] [] down_write+0x3f/0x5b [ 5936.372401] [] do_execve_common.isra.27+0x25a/0x5ca [ 5936.380715] [] do_execve+0x13/0x15 [ 5936.387541] [] run_init_process+0x26/0x28 [ 5936.394989] [] kernel_init+0x3d/0xda [ 5936.401988] [] ret_from_fork+0x7c/0xb0 [ 5936.409160] } [ 5936.410927] ... key at: [] __key.48993+0x0/0x8 [ 5936.417581] ... acquired at: [ 5936.420654] [] lock_acquire+0xd8/0x11a [ 5936.426268] [] might_fault+0x82/0xa5 [ 5936.431708] [] filldir+0x84/0xf7 [ 5936.436802] [] dir_emit+0x13/0x1a [xfs] [ 5936.442520] [] xfs_dir2_block_getdents+0x145/0x190 [xfs] [ 5936.449716] [] xfs_readdir+0xfc/0x15a [xfs] [ 5936.455815] [] xfs_file_readdir+0x26/0x35 [xfs] [ 5936.462225] [] iterate_dir+0x88/0x11a [ 5936.467759] [] SyS_getdents+0x76/0xd2 [ 5936.473285] [] system_call_fastpath+0x16/0x1b [ 5936.479504] [ 5936.481011] -> (&xfs_dir_ilock_class){++++-+} ops: 462317 { [ 5936.486720] HARDIRQ-ON-W at: [ 5936.489916] [] __lock_acquire+0x345/0xe77 [ 5936.497280] [] lock_acquire+0xd8/0x11a [ 5936.504372] [] down_write_nested+0x45/0x62 [ 5936.511823] [] xfs_ilock+0x9a/0xda [xfs] [ 5936.519117] [] xfs_setattr_nonsize+0x167/0x40a [xfs] [ 5936.527475] [] xfs_vn_setattr+0x55/0x5e [xfs] [ 5936.535192] [] notify_change+0x1f1/0x2d4 [ 5936.542504] [] utimes_common+0x116/0x176 [ 5936.549780] [] do_utimes+0xeb/0x122 [ 5936.556604] [] SyS_utimensat+0x65/0x7f [ 5936.563690] [] system_call_fastpath+0x16/0x1b [ 5936.571399] HARDIRQ-ON-R at: [ 5936.574577] [] __lock_acquire+0x31c/0xe77 [ 5936.581949] [] lock_acquire+0xd8/0x11a [ 5936.589033] [] down_read_nested+0x48/0x57 [ 5936.596398] [] xfs_ilock+0xb2/0xda [xfs] [ 5936.603700] [] xfs_ilock_data_map_shared+0x28/0x2e [xfs] [ 5936.612388] [] xfs_lookup+0x6e/0xfd [xfs] [ 5936.619767] [] xfs_vn_lookup+0x49/0x88 [xfs] [ 5936.627407] [] lookup_real+0x27/0x42 [ 5936.634320] [] __lookup_hash+0x2e/0x37 [ 5936.641405] [] walk_component+0x73/0x17d [ 5936.648681] [] lookup_last+0x2e/0x30 [ 5936.655592] [] path_lookupat+0x8b/0x2c6 [ 5936.662766] [] filename_lookup.isra.27+0x21/0x57 [ 5936.670733] [] user_path_at_empty+0x52/0x90 [ 5936.678270] [] user_path_at+0xc/0xe [ 5936.685104] [] SYSC_faccessat+0x9a/0x182 [ 5936.697629] [] SyS_access+0x13/0x15 [ 5936.704455] [] system_call_fastpath+0x16/0x1b [ 5936.712163] SOFTIRQ-ON-W at: [ 5936.715343] [] __lock_acquire+0x367/0xe77 [ 5936.722730] [] lock_acquire+0xd8/0x11a [ 5936.729817] [] down_write_nested+0x45/0x62 [ 5936.737267] [] xfs_ilock+0x9a/0xda [xfs] [ 5936.744567] [] xfs_setattr_nonsize+0x167/0x40a [xfs] [ 5936.752900] [] xfs_vn_setattr+0x55/0x5e [xfs] [ 5936.760626] [] notify_change+0x1f1/0x2d4 [ 5936.767904] [] utimes_common+0x116/0x176 [ 5936.775185] [] do_utimes+0xeb/0x122 [ 5936.782013] [] SyS_utimensat+0x65/0x7f [ 5936.789099] [] system_call_fastpath+0x16/0x1b [ 5936.796816] SOFTIRQ-ON-R at: [ 5936.799996] [] __lock_acquire+0x367/0xe77 [ 5936.807394] [] lock_acquire+0xd8/0x11a [ 5936.814480] [] down_read_nested+0x48/0x57 [ 5936.821841] [] xfs_ilock+0xb2/0xda [xfs] [ 5936.829150] [] xfs_ilock_data_map_shared+0x28/0x2e [xfs] [ 5936.837840] [] xfs_lookup+0x6e/0xfd [xfs] [ 5936.845220] [] xfs_vn_lookup+0x49/0x88 [xfs] [ 5936.852860] [] lookup_real+0x27/0x42 [ 5936.859771] [] __lookup_hash+0x2e/0x37 [ 5936.866857] [] walk_component+0x73/0x17d [ 5936.874134] [] lookup_last+0x2e/0x30 [ 5936.881049] [] path_lookupat+0x8b/0x2c6 [ 5936.888235] [] filename_lookup.isra.27+0x21/0x57 [ 5936.896239] [] user_path_at_empty+0x52/0x90 [ 5936.903775] [] user_path_at+0xc/0xe [ 5936.910600] [] SYSC_faccessat+0x9a/0x182 [ 5936.917876] [] SyS_access+0x13/0x15 [ 5936.924701] [] system_call_fastpath+0x16/0x1b [ 5936.932410] IN-RECLAIM_FS-W at: [ 5936.935849] [] __lock_acquire+0x396/0xe77 [ 5936.943473] [] lock_acquire+0xd8/0x11a [ 5936.950835] [] down_write_nested+0x45/0x62 [ 5936.958543] [] xfs_ilock+0x9a/0xda [xfs] [ 5936.966106] [] xfs_reclaim_inode+0x2f/0x248 [xfs] [ 5936.974438] [] xfs_reclaim_inodes_ag+0x196/0x279 [xfs] [ 5936.983205] [] xfs_reclaim_inodes_nr+0x2e/0x37 [xfs] [ 5936.991831] [] xfs_fs_free_cached_objects+0x10/0x12 [xfs] [ 5937.000858] [] super_cache_scan+0x128/0x145 [ 5937.008653] [] shrink_slab_node+0x156/0x23b [ 5937.016448] [] shrink_slab+0x78/0x137 [ 5937.023725] [] balance_pgdat+0x317/0x47e [ 5937.031261] [] kswapd+0x30c/0x379 [ 5937.038173] [] kthread+0xb5/0xbd [ 5937.044999] [] ret_from_fork+0x7c/0xb0 [ 5937.052378] RECLAIM_FS-ON-R at: [ 5937.055818] [] mark_held_locks+0x54/0x76 [ 5937.063353] [] lockdep_trace_alloc+0xc3/0xcd [ 5937.071236] [] __alloc_pages_nodemask+0x8d/0x878 [ 5937.079465] [] alloc_pages_vma+0xe0/0x123 [ 5937.087087] [] handle_mm_fault+0x2ea/0x818 [ 5937.094795] [] __do_page_fault+0x36f/0x3bb [ 5937.102506] [] do_page_fault+0xc/0xe [ 5937.109677] [] page_fault+0x22/0x30 [ 5937.116763] [] dir_emit+0x13/0x1a [xfs] [ 5937.124228] [] xfs_dir2_block_getdents+0x145/0x190 [xfs] [ 5937.133170] [] xfs_readdir+0xfc/0x15a [xfs] [ 5937.141002] [] xfs_file_readdir+0x26/0x35 [xfs] [ 5937.149166] [] iterate_dir+0x88/0x11a [ 5937.156442] [] SyS_getdents+0x76/0xd2 [ 5937.163718] [] system_call_fastpath+0x16/0x1b [ 5937.171689] INITIAL USE at: [ 5937.174781] [] __lock_acquire+0x3ae/0xe77 [ 5937.182056] [] lock_acquire+0xd8/0x11a [ 5937.189059] [] down_read_nested+0x48/0x57 [ 5937.196339] [] xfs_ilock+0xb2/0xda [xfs] [ 5937.203539] [] xfs_ilock_data_map_shared+0x28/0x2e [xfs] [ 5937.212138] [] xfs_lookup+0x6e/0xfd [xfs] [ 5937.219441] [] xfs_vn_lookup+0x49/0x88 [xfs] [ 5937.226987] [] lookup_real+0x27/0x42 [ 5937.233812] [] __lookup_hash+0x2e/0x37 [ 5937.240811] [] walk_component+0x73/0x17d [ 5937.247981] [] lookup_last+0x2e/0x30 [ 5937.254808] [] path_lookupat+0x8b/0x2c6 [ 5937.261893] [] filename_lookup.isra.27+0x21/0x57 [ 5937.269809] [] user_path_at_empty+0x52/0x90 [ 5937.277259] [] user_path_at+0xc/0xe [ 5937.283999] [] SYSC_faccessat+0x9a/0x182 [ 5937.291170] [] SyS_access+0x13/0x15 [ 5937.297910] [] system_call_fastpath+0x16/0x1b [ 5937.305540] } [ 5937.307220] ... key at: [] xfs_dir_ilock_class+0x0/0xfffffffffffdb4cf [xfs] [ 5937.316333] ... acquired at: [ 5937.319321] [] check_usage_forwards+0x95/0xa6 [ 5937.325542] [] mark_lock+0x105/0x212 [ 5937.330982] [] __lock_acquire+0x396/0xe77 [ 5937.336890] [] lock_acquire+0xd8/0x11a [ 5937.342500] [] down_write_nested+0x45/0x62 [ 5937.348461] [] xfs_ilock+0x9a/0xda [xfs] [ 5937.354273] [] xfs_reclaim_inode+0x2f/0x248 [xfs] [ 5937.360878] [] xfs_reclaim_inodes_ag+0x196/0x279 [xfs] [ 5937.367889] [] xfs_reclaim_inodes_nr+0x2e/0x37 [xfs] [ 5937.374750] [] xfs_fs_free_cached_objects+0x10/0x12 [xfs] [ 5937.382042] [] super_cache_scan+0x128/0x145 [ 5937.388088] [] shrink_slab_node+0x156/0x23b [ 5937.394168] [] shrink_slab+0x78/0x137 [ 5937.399695] [] balance_pgdat+0x317/0x47e [ 5937.405482] [] kswapd+0x30c/0x379 [ 5937.410661] [] kthread+0xb5/0xbd [ 5937.415756] [] ret_from_fork+0x7c/0xb0 [ 5937.421368] [ 5937.422902] [ 5937.422902] stack backtrace: [ 5937.427330] CPU: 0 PID: 66 Comm: kswapd0 Not tainted 3.16.2 #59 [ 5937.433271] Hardware name: Supermicro X8SIL/X8SIL, BIOS 1.1 05/27/2010 [ 5937.439819] ffff880234a2f6f8 ffff880234a2f688 ffffffff8139835a 0000000000000006 [ 5937.447388] ffffffff81a1bf40 ffff880234a2f6d8 ffffffff81393afc ffffffff810709e0 [ 5937.454898] ffffffff81579064 ffff880234a2f6ec 0000000000000000 ffff880235f51880 [ 5937.462408] Call Trace: [ 5937.464881] [] dump_stack+0x4e/0x68 [ 5937.470042] [] print_irq_inversion_bug.part.36+0x1a1/0x1b0 [ 5937.477214] [] ? noop_count+0xb/0xb [ 5937.482376] [] check_usage_forwards+0x95/0xa6 [ 5937.488405] [] ? check_usage_backwards+0xa0/0xa0 [ 5937.494694] [] mark_lock+0x105/0x212 [ 5937.499944] [] __lock_acquire+0x396/0xe77 [ 5937.505635] [] ? __lock_acquire+0x615/0xe77 [ 5937.516694] [] ? __lock_acquire+0x3ae/0xe77 [ 5937.522550] [] lock_acquire+0xd8/0x11a [ 5937.527997] [] ? xfs_ilock+0x9a/0xda [xfs] [ 5937.533781] [] ? xfs_reclaim_inode+0x2f/0x248 [xfs] [ 5937.540334] [] down_write_nested+0x45/0x62 [ 5937.546160] [] ? xfs_ilock+0x9a/0xda [xfs] [ 5937.551989] [] xfs_ilock+0x9a/0xda [xfs] [ 5937.557622] [] xfs_reclaim_inode+0x2f/0x248 [xfs] [ 5937.564021] [] xfs_reclaim_inodes_ag+0x196/0x279 [xfs] [ 5937.570833] [] ? trace_hardirqs_on_caller+0x145/0x1a1 [ 5937.577562] [] ? trace_hardirqs_on+0xd/0xf [ 5937.583357] [] ? try_to_wake_up+0x1c5/0x1d7 [ 5937.589212] [] ? wake_up_process+0x30/0x34 [ 5937.595007] [] ? xfs_ail_push+0x49/0x4e [xfs] [ 5937.601051] [] xfs_reclaim_inodes_nr+0x2e/0x37 [xfs] [ 5937.607703] [] xfs_fs_free_cached_objects+0x10/0x12 [xfs] [ 5937.614801] [] super_cache_scan+0x128/0x145 [ 5937.620656] [] shrink_slab_node+0x156/0x23b [ 5937.626520] [] shrink_slab+0x78/0x137 [ 5937.631854] [] balance_pgdat+0x317/0x47e [ 5937.637450] [] kswapd+0x30c/0x379 [ 5937.642431] [] ? bit_waitqueue+0x87/0x87 [ 5937.648027] [] ? balance_pgdat+0x47e/0x47e [ 5937.653799] [] kthread+0xb5/0xbd [ 5937.658716] [] ? __kthread_parkme+0x5c/0x5c [ 5937.664596] [] ret_from_fork+0x7c/0xb0 [ 5937.670021] [] ? __kthread_parkme+0x5c/0x5c [ 5937.675900] [sched_delayed] sched: RT throttling activated From sandeen@sandeen.net Tue Sep 16 10:26:47 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 0F1457F50 for ; Tue, 16 Sep 2014 10:26:47 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id F0D7A304048 for ; Tue, 16 Sep 2014 08:26:46 -0700 (PDT) X-ASG-Debug-ID: 1410881202-04cbb05488e11ee0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id kjOOu2a8Dfw05kQ8 for ; Tue, 16 Sep 2014 08:26:42 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id B3EB865B096C for ; Tue, 16 Sep 2014 10:26:41 -0500 (CDT) Message-ID: <541856B1.3000009@sandeen.net> Date: Tue, 16 Sep 2014 10:26:41 -0500 From: Eric Sandeen MIME-Version: 1.0 To: xfs-oss Subject: [PATCH 1/2 V2] xfs_db: fix inode CRC validity state, and warn on read if invalid References: <540B4399.4020804@sandeen.net> X-ASG-Orig-Subj: [PATCH 1/2 V2] xfs_db: fix inode CRC validity state, and warn on read if invalid In-Reply-To: <540B4399.4020804@sandeen.net> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410881202 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9550 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Currently, the "ino_crc_ok" field on the io cursor reflects overall inode validity, not CRC correctness. Because it is only used when printing CRC validity, change it to reflect only that state - and update it whenever we re-write the inode (thus updating the CRC). In addition, when reading an inode, warn if the CRC is bad. Note, when specifying an inode which doesn't actually exist, this will claim corruption; I'm not sure if that's good or bad. Today, it already issues corruption errors on the way; this adds a new message as well: xfs_db> inode 129 Metadata corruption detected at block 0x80/0x2000 Metadata corruption detected at block 0x80/0x2000 ... Metadata CRC error detected for ino 129 Signed-off-by: Eric Sandeen --- V2: fix whitespace damage, introduce libxfs_verify_cksum diff --git a/db/inode.c b/db/inode.c index 24170ba..982acb7 100644 --- a/db/inode.c +++ b/db/inode.c @@ -684,13 +684,18 @@ set_cur_inode( numblks, DB_RING_IGN, NULL); off_cur(offset << mp->m_sb.sb_inodelog, mp->m_sb.sb_inodesize); dip = iocur_top->data; - iocur_top->ino_crc_ok = libxfs_dinode_verify(mp, ino, dip); + iocur_top->ino_crc_ok = libxfs_verify_cksum((char *)dip, + mp->m_sb.sb_inodesize, + XFS_DINODE_CRC_OFF); iocur_top->ino_buf = 1; iocur_top->ino = ino; iocur_top->mode = be16_to_cpu(dip->di_mode); if ((iocur_top->mode & S_IFMT) == S_IFDIR) iocur_top->dirino = ino; + if (xfs_sb_version_hascrc(&mp->m_sb) && !iocur_top->ino_crc_ok) + dbprintf(_("Metadata CRC error detected for ino %lld\n"), ino); + /* track updated info in ring */ ring_add(); } diff --git a/db/io.c b/db/io.c index 7f1b76a..f7393c5 100644 --- a/db/io.c +++ b/db/io.c @@ -464,8 +464,10 @@ write_cur(void) return; } - if (iocur_top->ino_buf) + if (iocur_top->ino_buf) { libxfs_dinode_calc_crc(mp, iocur_top->data); + iocur_top->ino_crc_ok = 1; + } if (iocur_top->dquot_buf) xfs_update_cksum(iocur_top->data, sizeof(struct xfs_dqblk), XFS_DQUOT_CRC_OFF); diff --git a/include/libxfs.h b/include/libxfs.h index 45a924f..962e319 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -782,6 +782,8 @@ extern uint32_t crc32c_le(uint32_t crc, unsigned char const *p, size_t len); #include +#define libxfs_verify_cksum xfs_verify_cksum + static inline int xfs_buf_verify_cksum(struct xfs_buf *bp, unsigned long cksum_offset) { From sandeen@sandeen.net Tue Sep 16 10:29:19 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 972707F50 for ; Tue, 16 Sep 2014 10:29:19 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8082D8F8035 for ; Tue, 16 Sep 2014 08:29:16 -0700 (PDT) X-ASG-Debug-ID: 1410881354-04cb6c54ffb40d00001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id OSRPAFANrXFStrfG for ; Tue, 16 Sep 2014 08:29:14 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 5AB7D65B096C for ; Tue, 16 Sep 2014 10:29:14 -0500 (CDT) Message-ID: <5418574A.8040102@sandeen.net> Date: Tue, 16 Sep 2014 10:29:14 -0500 From: Eric Sandeen MIME-Version: 1.0 To: xfs-oss Subject: [PATCH 2/2 V2] xfs_db: add crc manipulation commands References: <540B4399.4020804@sandeen.net> X-ASG-Orig-Subj: [PATCH 2/2 V2] xfs_db: add crc manipulation commands In-Reply-To: <540B4399.4020804@sandeen.net> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410881354 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9550 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This adds a new "crc" command to xfs_db for CRC-enabled filesystems. If a structure has a CRC field, we can validate it, invalidate/corrupt it, or revalidate/rewrite it: xfs_db> sb 0 xfs_db> crc -v crc = 0x796c814f (correct) xfs_db> crc -i Metadata CRC error detected at block 0x0/0x200 crc = 0x796c8150 (bad) xfs_db> crc -r crc = 0x796c814f (correct) (-i and -r require "expert" write-capable mode) This requires temporarily replacing the write verifier with a dummy which won't recalculate the CRC on the way to disk. It also required me to write a new flist function, which is totally foreign to me, so hopefully done right - but it seems to work here. Signed-off-by: Eric Sandeen --- Note, "-i" and "-r" are shown in help even if not in expert mode, not sure if I should fix that? V2: Fix whitespace damage, clarify write_cur() changes a bit w/ code & comments. diff --git a/db/Makefile b/db/Makefile index bae6154..f0175cc 100644 --- a/db/Makefile +++ b/db/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_db HFILES = addr.h agf.h agfl.h agi.h attr.h attrshort.h bit.h block.h bmap.h \ - btblock.h bmroot.h check.h command.h convert.h debug.h \ + btblock.h bmroot.h check.h command.h convert.h crc.h debug.h \ dir2.h dir2sf.h dquot.h echo.h faddr.h field.h \ flist.h fprint.h frag.h freesp.h hash.h help.h init.h inode.h input.h \ io.h malloc.h metadump.h output.h print.h quit.h sb.h sig.h strvec.h \ diff --git a/db/command.c b/db/command.c index b7e3165..d44e0a5 100644 --- a/db/command.c +++ b/db/command.c @@ -48,6 +48,7 @@ #include "write.h" #include "malloc.h" #include "dquot.h" +#include "crc.h" cmdinfo_t *cmdtab; int ncmds; @@ -123,6 +124,7 @@ init_commands(void) bmap_init(); check_init(); convert_init(); + crc_init(); debug_init(); echo_init(); frag_init(); diff --git a/db/crc.c b/db/crc.c new file mode 100644 index 0000000..410f5ff --- /dev/null +++ b/db/crc.c @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2014 Red Hat, Inc. + * All Rights Reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "addr.h" +#include "command.h" +#include "type.h" +#include "faddr.h" +#include "fprint.h" +#include "field.h" +#include "flist.h" +#include "io.h" +#include "init.h" +#include "output.h" +#include "bit.h" +#include "print.h" + +static int crc_f(int argc, char **argv); +static void crc_help(void); + +static const cmdinfo_t crc_cmd = + { "crc", NULL, crc_f, 0, 1, 0, "[-i|-r|-v]", + N_("manipulate crc values for V5 filesystem structures"), crc_help }; + +void +crc_init(void) +{ + if (xfs_sb_version_hascrc(&mp->m_sb)) + add_command(&crc_cmd); +} + +static void +crc_help(void) +{ + dbprintf(_( +"\n" +" 'crc' validates, invalidates, or recalculates the crc value for\n" +" the current on-disk metadata structures in Version 5 filesystems.\n" +"\n" +" Usage: \"crc [-i|-r|-v]\"\n" +"\n" +)); + +} + +void +xfs_dummy_verify( + struct xfs_buf *bp) +{ + return; +} + +static int +crc_f( + int argc, + char **argv) +{ + const struct xfs_buf_ops *stashed_ops = NULL; + extern char *progname; + const field_t *fields; + const ftattr_t *fa; + flist_t *fl; + int invalidate = 0; + int recalculate = 0; + int validate = 0; + int c; + + if (cur_typ == NULL) { + dbprintf(_("no current type\n")); + return 0; + } + + if (cur_typ->fields == NULL) { + dbprintf(_("current type (%s) is not a structure\n"), + cur_typ->name); + return 0; + } + + if (argc) while ((c = getopt(argc, argv, "irv")) != EOF) { + switch (c) { + case 'i': + invalidate = 1; + break; + case 'r': + recalculate = 1; + break; + case 'v': + validate = 1; + break; + default: + dbprintf(_("bad option for crc command\n")); + return 0; + } + } else + validate = 1; + + if (invalidate + recalculate + validate > 1) { + dbprintf(_("crc command accepts only one option\n")); + return 0; + } + + if ((invalidate || recalculate) && + ((x.isreadonly & LIBXFS_ISREADONLY) || !expert_mode)) { + dbprintf(_("%s not in expert mode, writing disabled\n"), + progname); + return 0; + } + + fields = cur_typ->fields; + + /* if we're a root field type, go down 1 layer to get field list */ + if (fields->name[0] == '\0') { + fa = &ftattrtab[fields->ftyp]; + ASSERT(fa->ftyp == fields->ftyp); + fields = fa->subfld; + } + + /* Search for a CRC field */ + fl = flist_find_ftyp(fields, FLDT_CRC); + if (!fl) { + dbprintf(_("No CRC field found for type %s\n"), cur_typ->name); + return 0; + } + + /* run down the field list and set offsets into the data */ + if (!flist_parse(fields, fl, iocur_top->data, 0)) { + flist_free(fl); + dbprintf(_("parsing error\n")); + return 0; + } + + if (invalidate) { + struct xfs_buf_ops nowrite_ops; + flist_t *sfl; + int bit_length; + int parentoffset; + int crc; + + sfl = fl; + parentoffset = 0; + while (sfl->child) { + parentoffset = sfl->offset; + sfl = sfl->child; + } + ASSERT(sfl->fld->ftyp == FLDT_CRC); + + bit_length = fsize(sfl->fld, iocur_top->data, parentoffset, 0); + bit_length *= fcount(sfl->fld, iocur_top->data, parentoffset); + crc = getbitval(iocur_top->data, sfl->offset, bit_length, BVUNSIGNED); + /* Off by one.. */ + crc = cpu_to_be32(crc + 1); + setbitval(iocur_top->data, sfl->offset, bit_length, &crc); + + /* Temporarily remove write verifier to write a bad CRC */ + stashed_ops = iocur_top->bp->b_ops; + nowrite_ops.verify_read = stashed_ops->verify_read; + nowrite_ops.verify_write = xfs_dummy_verify; + iocur_top->bp->b_ops = &nowrite_ops; + } + + if (invalidate || recalculate) { + write_cur(); + if (stashed_ops) + iocur_top->bp->b_ops = stashed_ops; + /* re-verify to get proper b_error state */ + iocur_top->bp->b_ops->verify_read(iocur_top->bp); + } + + /* And show us what we've got! */ + flist_print(fl); + print_flist(fl); + flist_free(fl); + return 0; +} diff --git a/db/crc.h b/db/crc.h new file mode 100644 index 0000000..80ecec3 --- /dev/null +++ b/db/crc.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014 Red Hat, Inc. + * All Rights Reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +struct field; + +extern void crc_init(void); +extern void crc_struct(const field_t *fields, int argc, char **argv); +extern void xfs_dummy_verify(struct xfs_buf *bp); diff --git a/db/flist.c b/db/flist.c index 33f7da7..fa19f70 100644 --- a/db/flist.c +++ b/db/flist.c @@ -411,6 +411,40 @@ flist_split( return v; } +/* + * Given a set of fields, scan for a field of the given type. + * Return an flist leading to the first found field + * of that type. + * Return NULL if no field of the given type is found. + */ +flist_t * +flist_find_ftyp( + const field_t *fields, + fldt_t type) +{ + flist_t *fl; + const field_t *f; + const ftattr_t *fa; + + for (f = fields; f->name; f++) { + fl = flist_make(f->name); + fl->fld = f; + if (f->ftyp == type) + return fl; + fa = &ftattrtab[f->ftyp]; + if (fa->subfld) { + flist_t *nfl; + nfl = flist_find_ftyp(fa->subfld, type); + if (nfl) { + fl->child = nfl; + return fl; + } + } + flist_free(fl); + } + return NULL; +} + static void ftok_free( ftok_t *ft) diff --git a/db/flist.h b/db/flist.h index 5c9fba0..3f4b312 100644 --- a/db/flist.h +++ b/db/flist.h @@ -37,3 +37,4 @@ extern int flist_parse(const struct field *fields, flist_t *fl, void *obj, int startoff); extern void flist_print(flist_t *fl); extern flist_t *flist_scan(char *name); +extern flist_t *flist_find_ftyp(const field_t *fields, fldt_t type); diff --git a/db/io.c b/db/io.c index f7393c5..eb3daa1 100644 --- a/db/io.c +++ b/db/io.c @@ -27,6 +27,7 @@ #include "output.h" #include "init.h" #include "malloc.h" +#include "crc.h" static int pop_f(int argc, char **argv); static void pop_help(void); @@ -459,22 +460,37 @@ write_cur_bbs(void) void write_cur(void) { + int skip_crc = (iocur_top->bp->b_ops->verify_write == xfs_dummy_verify); + if (iocur_sp < 0) { dbprintf(_("nothing to write\n")); return; } - if (iocur_top->ino_buf) { + if (iocur_top->ino_buf && !skip_crc) { libxfs_dinode_calc_crc(mp, iocur_top->data); iocur_top->ino_crc_ok = 1; } - if (iocur_top->dquot_buf) + + if (iocur_top->dquot_buf && !skip_crc) xfs_update_cksum(iocur_top->data, sizeof(struct xfs_dqblk), XFS_DQUOT_CRC_OFF); if (iocur_top->bbmap) write_cur_bbs(); else write_cur_buf(); + + /* If we didn't write the crc automatically, re-check validity */ + if (iocur_top->ino_buf && skip_crc) { + xfs_dinode_t *dip; + xfs_ino_t ino; + + dip = iocur_top->data; + ino = iocur_top->ino; + iocur_top->ino_crc_ok = xfs_verify_cksum((char *)dip, + mp->m_sb.sb_inodesize, + XFS_DINODE_CRC_OFF); + } } void diff --git a/db/write.h b/db/write.h index 31e2665..664ddcc 100644 --- a/db/write.h +++ b/db/write.h @@ -20,5 +20,5 @@ struct field; extern void write_init(void); extern void write_block(const field_t *fields, int argc, char **argv); -extern void write_string(const field_t *fields, int argc, char **argv); extern void write_struct(const field_t *fields, int argc, char **argv); +extern void write_string(const field_t *fields, int argc, char **argv); diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8 index 4d8d4ff..0764832 100644 --- a/man/man8/xfs_db.8 +++ b/man/man8/xfs_db.8 @@ -87,16 +87,14 @@ or .I filename read-only. This option is required if the filesystem is mounted. It is only necessary to omit this flag if a command that changes data -.RB ( write ", " blocktrash ) +.RB ( write ", " blocktrash ", " crc ) is to be used. .TP .B \-x Specifies expert mode. This enables the -.B write -and -.B blocktrash -commands. +.RB ( write ", " blocktrash ", " crc +invalidate/revalidate) commands. .TP .B \-V Prints the version number and exits. @@ -409,6 +407,25 @@ conversions such as .I agb .BR fsblock . .TP +.B crc [\-i|\-r|\-v] +Invalidates, revalidates, or validates the CRC (checksum) +field of the current structure, if it has one. +This command is available only on CRC-enabled filesystems. +With no argument, validation is performed. +Each command will display the resulting CRC value and state. +.RS 1.0i +.TP 0.4i +.B \-i +Invalidate the structure's CRC value (incrementing it by one), +and write it to disk. +.TP +.B \-r +Recalculate the current structure's correct CRC value, and write it to disk. +.TP +.B \-v +Validate and display the current value and state of the structure's CRC. +.RE +.TP .BI "daddr [" d ] Set current address to the daddr (512 byte block) given by .IR d . From alex@zadarastorage.com Tue Sep 16 11:01:32 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id C9CBA7F47 for ; Tue, 16 Sep 2014 11:01:32 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9B0A130405F for ; Tue, 16 Sep 2014 09:01:29 -0700 (PDT) X-ASG-Debug-ID: 1410883286-04bdf010a1acc370001-NocioJ Received: from mail-we0-f174.google.com (mail-we0-f174.google.com [74.125.82.174]) by cuda.sgi.com with ESMTP id vzBfhfoEdhQm0XeI (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Tue, 16 Sep 2014 09:01:27 -0700 (PDT) X-Barracuda-Envelope-From: alex@zadarastorage.com X-Barracuda-Apparent-Source-IP: 74.125.82.174 Received: by mail-we0-f174.google.com with SMTP id t60so58087wes.19 for ; Tue, 16 Sep 2014 09:01:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=nMrWU5iysAzBOowwioHn9pEntXrx9/9LfvydmrXEKV0=; b=UqLstqe0BPuLDydp2lWEidhe9UcEeL0vFhEjuI9QLM/6AKjofLFNlC+XNj8cyR3SNW cU1fCH7EC37OuLFn+yJW2LsIkDlxXVTuB1zkXSzVHMYnkKUAlIywbNeRrDU8Cpc6v1xC rsN+0Oh10k2Sq/o6miq8iWK66gI7CPFZ/l/Dxo7ku2JwgKBk6XH4QtizsF4aqweOJIyC u6EyYnUvXLOKz9GkA8q5SA9vkd39GCi6WUFyWNdiFkxSunWeKa8404OCrFhQr6zgzWML vL9oHdzCxmKWigK1ELVflGMut07mfe/j4eqfPx+H485dXdkbkWiyn7tEyY8U9rxCIung mTVA== X-Gm-Message-State: ALoCoQkhEvjJ/2yHxktqvAbTieFMbtsDDj3hpMIGL7347UYX9yiGVqYx2EBlHtcosYSaCvTZXkl/ MIME-Version: 1.0 X-Received: by 10.181.27.197 with SMTP id ji5mr23068026wid.54.1410883286027; Tue, 16 Sep 2014 09:01:26 -0700 (PDT) Received: by 10.194.15.232 with HTTP; Tue, 16 Sep 2014 09:01:25 -0700 (PDT) In-Reply-To: <20140902220216.GJ20518@dastard> References: <1408648692-15957-1-git-send-email-bfoster@redhat.com> <20140825142025.GA10135@bfoster.bfoster> <20140831210507.GA11913@bfoster.bfoster> <3476A2CBDE694DC6BD06DBDD15165151@alyakaslap> <20140902220216.GJ20518@dastard> Date: Tue, 16 Sep 2014 19:01:25 +0300 Message-ID: Subject: Re: [PATCH] xfs: fix double free of trans in log recovery on I/O error From: Alex Lyakas X-ASG-Orig-Subj: Re: [PATCH] xfs: fix double free of trans in log recovery on I/O error To: Dave Chinner Cc: Brian Foster , xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=001a1134894815676c050330dd1b X-Barracuda-Connect: mail-we0-f174.google.com[74.125.82.174] X-Barracuda-Start-Time: 1410883286 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE, MARKETING_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9550 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 HTML_MESSAGE BODY: HTML included in message --001a1134894815676c050330dd1b Content-Type: text/plain; charset=UTF-8 Hi Dave, On Wed, Sep 3, 2014 at 1:02 AM, Dave Chinner wrote: > On Tue, Sep 02, 2014 at 12:51:35PM +0300, Alex Lyakas wrote: > > Hi Brian, Dave, > > I tested this patch on 3.8.13 kernel with the scenario I described > > in http://oss.sgi.com/pipermail/xfs/2014-August/037637.html, but I > > still see the issue. > > I placed the metadump at > https://drive.google.com/file/d/0ByBy89zr3kJNV2UxMERNTkE4aHM/edit?usp=sharing > > > > During log recovery, 3 IO errors are encountered: > > [ 340.381199] XFS (dm-0): Mounting Filesystem > > [ 340.439897] XFS (dm-0): Sleep 10s before xlog_do_recover > > [ 350.440143] XFS (dm-0): Starting recovery (logdev: internal) > > [ 351.584647] XFS (dm-0): metadata I/O error: block 0x1 > > ("xlog_recover_iodone") error 28 numblks 1 > > [ 351.584660] XFS (dm-0): metadata I/O error: block 0x40 > > ("xlog_recover_iodone") error 28 numblks 16 > > [ 351.584665] XFS (dm-0): xfs_do_force_shutdown(0x1) called from > > line 377 of file > > /mnt/work/alex/zadara-btrfs/fs/xfs/xfs_log_recover.c. Return > > address = 0xffffffffa0372728 > > [ 351.584969] XFS (dm-0): I/O Error Detected. Shutting down filesystem > > [ 351.584970] XFS (dm-0): Please umount the filesystem and rectify > > the problem(s) > > [ 351.585047] XFS (dm-0): metadata I/O error: block 0x1e00040 > > ("xlog_recover_iodone") error 28 numblks 16 > > [ 351.585050] XFS (dm-0): xfs_do_force_shutdown(0x1) called from > > line 377 of file > > /mnt/work/alex/zadara-btrfs/fs/xfs/xfs_log_recover.c. Return > > address = 0xffffffffa0372728 > > [ 351.585068] XFS (dm-0): log mount/recovery failed: error 28 > > [ 351.585332] XFS (dm-0): log mount failed > > > > Two IO error callbacks are handled before XFS is unmounted, but the > > last one crashes with stack[1]. > > > > Do I need some or all of the 9 patches that Dave posted? (They do > > not apply to my kernel, so I need to apply them by hand). > > No, I suspect that there are other problems that have been fixed > since 3.8 that you are missing. e.g. > > 9c23ecc xfs: unmount does not wait for shutdown during unmount > I applied this patch, and on top of that applied your patch "[PATCH 1/9] xfs: synchronous buffer IO needs a reference". However, the log recovery problem still reproduces. At least with the 9c23ecc patch, the unmount-while-IO-error problems that I reported long ago seem to be fixed. Thanks, Alex. > > THere's bound to be others, so you're really going to need to look > at the differences between 3.8 and a current mainline to determine > what other patches you are going to need... > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > --001a1134894815676c050330dd1b Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi Dave,

On Wed, Sep 3, 2014 at 1:02 AM, Dave Chinner = <david@fromorbi= t.com> wrote:
On Tue, Sep 02, 2014 at 12:51:35PM +0300, Alex Lyaka= s wrote:
> Hi Brian, Dave,
> I tested this patch on 3.8.13 kernel wit= h the scenario I described
> in http://oss.sgi.com/pipermail/xfs/2014-August/037637.htm= l, but I
> still see the issue.
> I placed the metadump at https://dr= ive.google.com/file/d/0ByBy89zr3kJNV2UxMERNTkE4aHM/edit?usp=3Dsharing >
> During log recovery, 3 IO errors are encountered:
> [=C2=A0 340.381199] XFS (dm-0): Mounting Filesystem
> [=C2=A0 340.439897] XFS (dm-0): Sleep 10s before xlog_do_recover
> [=C2=A0 350.440143] XFS (dm-0): Starting recovery (logdev: internal) > [=C2=A0 351.584647] XFS (dm-0): metadata I/O error: block 0x1
> ("xlog_recover_iodone") error 28 numblks 1
> [=C2=A0 351.584660] XFS (dm-0): metadata I/O error: block 0x40
> ("xlog_recover_iodone") error 28 numblks 16
> [=C2=A0 351.584665] XFS (dm-0): xfs_do_force_shutdown(0x1) called from=
> line 377 of file
> /mnt/work/alex/zadara-btrfs/fs/xfs/xfs_log_recover.c.=C2=A0 Return
> address =3D 0xffffffffa0372728
> [=C2=A0 351.584969] XFS (dm-0): I/O Error Detected. Shutting down file= system
> [=C2=A0 351.584970] XFS (dm-0): Please umount the filesystem and recti= fy
> the problem(s)
> [=C2=A0 351.585047] XFS (dm-0): metadata I/O error: block 0x1e00040 > ("xlog_recover_iodone") error 28 numblks 16
> [=C2=A0 351.585050] XFS (dm-0): xfs_do_force_shutdown(0x1) called from=
> line 377 of file
> /mnt/work/alex/zadara-btrfs/fs/xfs/xfs_log_recover.c.=C2=A0 Return
> address =3D 0xffffffffa0372728
> [=C2=A0 351.585068] XFS (dm-0): log mount/recovery failed: error 28 > [=C2=A0 351.585332] XFS (dm-0): log mount failed
>
> Two IO error callbacks are handled before XFS is unmounted, but the > last one crashes with stack[1].
>
> Do I need some or all of the 9 patches that Dave posted? (They do
> not apply to my kernel, so I need to apply them by hand).

No, I suspect that there are other problems that have been fixe= d
since 3.8 that you are missing. e.g.

9c23ecc xfs: unmount does not wait for shutdown during unmount
I applied this patch, and on top of that applied your patch "= [PATCH 1/9] xfs: synchronous buffer IO needs a reference". However, th= e log recovery problem still reproduces.

At least with th= e 9c23ecc patch, the unmount-while-IO-error problems that I reported long a= go seem to be fixed.

Thanks,
Alex.

=
=C2=A0

THere's bound to be others, so you're really going to need to look<= br> at the differences between 3.8 and a current mainline to determine
what other patches you are going to need...

Cheers,

Dave.
--
Dave Chinner
david@fromorbit.com

--001a1134894815676c050330dd1b-- From fabf@skynet.be Tue Sep 16 12:43:14 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 19FF87F47 for ; Tue, 16 Sep 2014 12:43:14 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id ECBE78F8035 for ; Tue, 16 Sep 2014 10:43:10 -0700 (PDT) X-ASG-Debug-ID: 1410889387-04bdf01097ad29d0001-NocioJ Received: from mailrelay005.isp.belgacom.be (mailrelay005.isp.belgacom.be [195.238.6.171]) by cuda.sgi.com with ESMTP id L7IXi6x26cV80WIv for ; Tue, 16 Sep 2014 10:43:09 -0700 (PDT) X-Barracuda-Envelope-From: fabf@skynet.be X-Barracuda-Apparent-Source-IP: 195.238.6.171 X-Belgacom-Dynamic: yes X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AkMOADV2GFRXQAMM/2dsb2JhbABggw2BKrQRBQFvmxiBFBcBeYRgI4EaN4hCAbw0hXyIa2QdhDUFnQqMMYkUg2A7L4EGgUQBAQE Received: from 12.3-64-87.adsl-dyn.isp.belgacom.be (HELO linux-zvq9.site) ([87.64.3.12]) by relay.skynet.be with ESMTP; 16 Sep 2014 19:42:58 +0200 From: Fabian Frederick To: linux-kernel@vger.kernel.org Cc: Fabian Frederick , Dave Chinner , xfs@oss.sgi.com Subject: [PATCH 1/1] xfs: remove second xfs_quota.h inclusion in xfs_icache.c Date: Tue, 16 Sep 2014 19:42:24 +0200 X-ASG-Orig-Subj: [PATCH 1/1] xfs: remove second xfs_quota.h inclusion in xfs_icache.c Message-Id: <1410889344-28339-1-git-send-email-fabf@skynet.be> X-Mailer: git-send-email 2.1.0 X-Barracuda-Connect: mailrelay005.isp.belgacom.be[195.238.6.171] X-Barracuda-Start-Time: 1410889388 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9552 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header xfs_quota.h was included twice. Signed-off-by: Fabian Frederick --- fs/xfs/xfs_icache.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 981b2cf..b45f7b2 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -33,7 +33,6 @@ #include "xfs_trace.h" #include "xfs_icache.h" #include "xfs_bmap_util.h" -#include "xfs_quota.h" #include "xfs_dquot_item.h" #include "xfs_dquot.h" -- 2.1.0 From david@fromorbit.com Tue Sep 16 15:54:23 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id F3B417F47 for ; Tue, 16 Sep 2014 15:54:22 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id DEBDC30404E for ; Tue, 16 Sep 2014 13:54:22 -0700 (PDT) X-ASG-Debug-ID: 1410900860-04cbb05488e23b20001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id N1uLFZaJd10eE0hJ for ; Tue, 16 Sep 2014 13:54:21 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AusfAL6iGFR5LCtm/2dsb2JhbABggw1TV4IssWsGlDmBXYVrBAIBgRMXAXmEBAEBBDocIxAIAxgJJQ8FJQMhExmIJA68bRiFZIc/ghAHhEsFlgSHBYFgik6JGINwKy8BgkkBAQE Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail07.adl2.internode.on.net with ESMTP; 17 Sep 2014 06:24:19 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XTzlG-0002r0-Gt; Wed, 17 Sep 2014 06:54:06 +1000 Date: Wed, 17 Sep 2014 06:54:06 +1000 From: Dave Chinner To: Olaf Weber Cc: Christoph Hellwig , Ben Myers , tinguely@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC] Unicode/UTF-8 support for XFS Message-ID: <20140916205406.GJ4322@dastard> X-ASG-Orig-Subj: Re: [RFC] Unicode/UTF-8 support for XFS References: <20140911203735.GA19952@sgi.com> <20140912100230.GB4267@dastard> <5412DF37.9030005@sgi.com> <20140912205528.GB11717@infradead.org> <54169248.1090105@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <54169248.1090105@sgi.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1410900860 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-ASG-Whitelist: Body =?UTF-8?B?aHR0cDovL21hcmNcLmluZm8vXD8=?= X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Sep 15, 2014 at 09:16:24AM +0200, Olaf Weber wrote: > On 12-09-14 22:55, Christoph Hellwig wrote: > >On Fri, Sep 12, 2014 at 01:55:35PM +0200, Olaf Weber wrote: > >>I looked up those discussions in the archives. For example, here's > >>Christoph about rejecting filenames if they're not well-formed unicode. > >> http://marc.info/?l=linux-fsdevel&m=120876935526856&w=2 > >>And Jamie Lokier making a similar point: > >> http://oss.sgi.com/archives/xfs/2008-04/msg01263.html > > > >And I might now disagree with my past self. While non-ut8 characters > >are perfectly valid unix filenames, and I think everyones life is easier > >if we generally stay out of the utf8 business it seems that for this > >particular use case (shared filesystem with Windows, right) just > >accepting utf8 should be fine. ZFS is doing, MacOS X apparently is, > >and NFSv4 requires it, although as far as I know most implementations > >ignore that requirement. > > > > One issue is working in environments that are not UTF-8 clean. For > example, unpacking a tarball with non-UTF-8 filenames in it. The > names would have to be transcoded, which is only really possible if > you know the original character set. And if the filesystem flat out > rejects non-UTF-8 filenames, then you'd be unable to unpack the > tarball at all. So how do existing utf8/unicode enabled filesystems handle this? I think we should be consistent with ZFS, MacOS and others that already deal with this problem if at all possible. However, this really is a wider policy decision for the kernel/VFS as we want consistent behaviour across all linux filesystems, hence this patchset really needs to discussed at the lkml/-fsdevel level... Cheers, Dave. -- Dave Chinner david@fromorbit.com From BATV+c00b5fb9ff0a5cc65cd5+4041+infradead.org+hch@bombadil.srs.infradead.org Tue Sep 16 16:02:41 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 0909D7F47 for ; Tue, 16 Sep 2014 16:02:41 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id EA0E2304051 for ; Tue, 16 Sep 2014 14:02:37 -0700 (PDT) X-ASG-Debug-ID: 1410901355-04cb6c54fdb51a50001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id t5hhEBUbbYkD3uIs (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO); Tue, 16 Sep 2014 14:02:35 -0700 (PDT) X-Barracuda-Envelope-From: BATV+c00b5fb9ff0a5cc65cd5+4041+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XTztT-0006g3-7B; Tue, 16 Sep 2014 21:02:35 +0000 Date: Tue, 16 Sep 2014 14:02:35 -0700 From: Christoph Hellwig To: Dave Chinner Cc: Olaf Weber , Ben Myers , tinguely@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC] Unicode/UTF-8 support for XFS Message-ID: <20140916210235.GA24591@infradead.org> X-ASG-Orig-Subj: Re: [RFC] Unicode/UTF-8 support for XFS References: <20140911203735.GA19952@sgi.com> <20140912100230.GB4267@dastard> <5412DF37.9030005@sgi.com> <20140912205528.GB11717@infradead.org> <54169248.1090105@sgi.com> <20140916205406.GJ4322@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140916205406.GJ4322@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1410901355 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9557 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Wed, Sep 17, 2014 at 06:54:06AM +1000, Dave Chinner wrote: > So how do existing utf8/unicode enabled filesystems handle this? > > I think we should be consistent with ZFS, MacOS and others that > already deal with this problem if at all possible. However, this > really is a wider policy decision for the kernel/VFS as we want > consistent behaviour across all linux filesystems, hence this > patchset really needs to discussed at the lkml/-fsdevel level... Absolutely. I've also talked to a few Samba folks at SDC, and one thing they would love to see is conditional case insensitive lookups, e.g.: - we hash case insensitive with collisions, but perform normal case sensitive lookups. - with a new AT_CASE_INSENSTIVE flag to the various *at calls that gets passed down to the dcache we enable CI lookups. From weber@zbfmail.de Tue Sep 16 16:27:52 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2BD397F47 for ; Tue, 16 Sep 2014 16:27:52 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 173DD8F8052 for ; Tue, 16 Sep 2014 14:27:48 -0700 (PDT) X-ASG-Debug-ID: 1410902866-04cbb05486e24c30001-NocioJ Received: from mail.zbfmail.de (mail.zbfmail.de [176.9.84.12]) by cuda.sgi.com with ESMTP id i8TRdNnhhcKwe6xY (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 16 Sep 2014 14:27:46 -0700 (PDT) X-Barracuda-Envelope-From: weber@zbfmail.de X-Barracuda-Apparent-Source-IP: 176.9.84.12 Received: from mail.zbfmail.de (localhost [127.0.0.1]) by mail.zbfmail.de (Postfix) with ESMTP id 8E66710C084 for ; Tue, 16 Sep 2014 23:27:45 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.9.2 mail.zbfmail.de 8E66710C084 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zbfmail.de; s=dkim; t=1410902865; bh=tEIBvEYi37wHnLmH5O/sMfhMmLcEGq8yzuiN9Sgdmlo=; h=Date:From:To:Subject:Reply-To:In-Reply-To:References; b=iZeKSfApB7RRGtmzKtUFKslrPnGr/j06/bSS3asNXwzrT++xZjAyxMvdfcQi87g90 HgCU7REsTI9EkUrRGPSp+4j1u80nAJdX8drkspY81HYkfLzmizwB78kXnbmY6ObiaJ MKYj3VhVV2dlY2dIgBzOaA538UZOUDLskicApRrE= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable Date: Tue, 16 Sep 2014 23:27:45 +0200 From: Marko Weber|8000 To: Xfs Subject: Re: unclean shutdown of usb hdd destroyed xfs partially Organization: zbf mail X-ASG-Orig-Subj: Re: unclean shutdown of usb hdd destroyed xfs partially Reply-To: weber@zbfmail.de Mail-Reply-To: weber@zbfmail.de In-Reply-To: <20140913220916.GC4267@dastard> References: <3999c95c0dc7ebfdfbb2853a6d13f7dc@zbfmail.de> <082ebd288523ee6155b66debade2a775@zbfmail.de> <20140913220916.GC4267@dastard> Message-ID: <330c89398cb4eef9b7289c1ffef8bcc3@zbfmail.de> X-Sender: weber@zbfmail.de User-Agent: Roundcube zbfmail Webmail X-DCC--Metrics: mailserver 1282; Body=1 Fuz1=1 Fuz2=1 X-Barracuda-Connect: mail.zbfmail.de[176.9.84.12] X-Barracuda-Start-Time: 1410902866 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9558 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature Am 2014-09-14 00:09, schrieb Dave Chinner: > On Sat, Sep 13, 2014 at 04:36:59PM +0200, Marko Weber|8000 wrote: >>=20 >> an output of xfs_repair -v -L /dev/sde1 > ... >>=20 >> # xfs_repair -v -L /dev/sde1 >=20 > What version? first it was 3.1.10 later like posted 3.2.1 >=20 >> Phase 1 - Superblock finden und =C3=BCberpr=C3=BCfen... >> - Berichts-Prozess in Abst=C3=A4nden von 15 Minutes >> - Block-Zwischenspeichergr=C3=B6=C3=9Fe ist auf 1487792 Eintr=C3= =A4ge gesetzt >> Phase 2 - ein internes Protokoll benutzen >> - Null-Protokoll... >> zero_log: head block 40 tail block 40 >> - freier Speicher und Inode-Karten des Dateisystems werden >> gescannt... >> bad magic numberbad magic numberbad magic number > .... >> falscher on-disk-Superblock 12 - falsche Magische Nummer >> Metadata corruption detected at block >> 0x20bf8e50/0x1000prim=C3=A4re/sekund=C3=A4rer Superblock-12-Konflikt - >> AG-Superblock-Geometrie-Info hat einen Konflikt mit der >> Dateisystem-Geometrie >> flasche magische # 0x0 f=C3=BCr agf 12 >> falsche Version # 0 f=C3=BCr agf 12 >>=20 >> Metadata corruption detected at block 0x417f1c90/0x1000 >> falscher on-disk-Superblock 6 - falsche Magische Nummer >> prim=C3=A4re/sekund=C3=A4rer Superblock-6-Konflikt - >> AG-Superblock-Geometrie-Info hat einen Konflikt mit der >> Dateisystem-Geometrie >> falscher on-disk-Superblock 3 - falsche Magische Nummer >> ungenutzten Anteil des =C2=BBsekund=C3=A4r=C2=AB-Superblocks nullen (AG = #6) >> Metadata corruption detected at block 0x57542610/0x1000 >> falsche Sequenz # 0 f=C3=BCr agf 12 >> Metadata corruption detected at block >> 0x7813b450/0x1000Speicherzugriffsfehler >=20 > I don't read german(?) but that looks like many AG header block > have been overwritten with zeros (0 magic number, 0 sequence #, 0 > length, etc) and so even if we can repair the filesystem, I'd > suggest that you need to verify that the data in every file in the > filesystem is correct. >=20 > Is that as far as xfs_repair got? If so, it would have appeared to > crash. Can you run the lastest version inside gdb to get a stack > trace when it dies? Or, alternatively, provide a metadump for one of > us to look at more closely? yes, this is as far xfs_repair got it. what is ment 'run latest version in gdb?' gnudebugger? how do i do that?=20 console example needed. and how do i do the metadump? thank you marko >=20 > Cheers, >=20 > Dave. From sandeen@redhat.com Tue Sep 16 16:30:47 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BC1FB7F47 for ; Tue, 16 Sep 2014 16:30:47 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3F1CAAC008 for ; Tue, 16 Sep 2014 14:30:44 -0700 (PDT) X-ASG-Debug-ID: 1410903042-04cb6c5500b52930001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id dEdX1kMTaKJ6vBoz (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 16 Sep 2014 14:30:43 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8GLUgAc013982 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 16 Sep 2014 17:30:42 -0400 Received: from liberator.sandeen.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8GLUfi1004047 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Tue, 16 Sep 2014 17:30:41 -0400 Message-ID: <5418AC01.30006@redhat.com> Date: Tue, 16 Sep 2014 16:30:41 -0500 From: Eric Sandeen MIME-Version: 1.0 To: xfs-oss Subject: [PATCH] xfs_repair: validate & fix inode CRCs Content-Type: text/plain; charset=utf-8 X-ASG-Orig-Subj: [PATCH] xfs_repair: validate & fix inode CRCs Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410903042 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xfs_repair doesn't ever check an inode's CRC, so it never repairs them. If the root inode or realtime inodes have bad crcs, the fs won't even mount and can't be fixed (without using xfs_db). It's fairly straightforward to just test the inode CRC before we do any other checking or modification of the inode, once we get past the "verify only" phase of process_dinode_int(); just mark it dirty if it's wrong and needs to be re-written. Signed-off-by: Eric Sandeen --- forgive the gratuitous big honkin' comment line, but process_dinode_int is so long, I thought the visual delimiter was useful. ;) diff --git a/repair/dinode.c b/repair/dinode.c index 8891e84..27c0da6 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -2524,6 +2524,30 @@ _("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"), if (verify_mode) return retval; + /* =========== END OF VERIFY MODE =================== */ + + /* + * We'd really like to know if the CRC is bad before we + * go fixing anything; that way we have some hint about + * bit-rot vs bugs. Also, any changes will invalidate the + * existing CRC, so this is the only valid point to test it. + * + * Of course if we make any modifications after this, the + * inode gets rewritten, and CRC is updated automagically. + */ + if (xfs_sb_version_hascrc(&mp->m_sb)) { + ASSERT(!verify_mode); + if(!xfs_verify_cksum((char *)dino, mp->m_sb.sb_inodesize, + XFS_DINODE_CRC_OFF)) { + do_warn(_("bad CRC for inode %" PRIu64), lino); + if (!no_modify) { + do_warn(_(", will rewrite\n")); + *dirty = 1; + } else + do_warn(_(", would rewrite\n")); + } + } + /* * clear the next unlinked field if necessary on a good * inode only during phase 4 -- when checking for inodes From bpm@sgi.com Tue Sep 16 16:42:51 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 8B52D7F47 for ; Tue, 16 Sep 2014 16:42:51 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6595D304048; Tue, 16 Sep 2014 14:42:51 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id D25E24266DC; Tue, 16 Sep 2014 16:42:50 -0500 (CDT) Date: Tue, 16 Sep 2014 16:42:50 -0500 From: Ben Myers To: Christoph Hellwig , Dave Chinner Cc: Olaf Weber , tinguely@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC] Unicode/UTF-8 support for XFS Message-ID: <20140916214250.GU19952@sgi.com> References: <20140911203735.GA19952@sgi.com> <20140912100230.GB4267@dastard> <5412DF37.9030005@sgi.com> <20140912205528.GB11717@infradead.org> <54169248.1090105@sgi.com> <20140916205406.GJ4322@dastard> <20140916210235.GA24591@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140916210235.GA24591@infradead.org> User-Agent: Mutt/1.5.20 (2009-06-14) Hey Gents, On Tue, Sep 16, 2014 at 02:02:35PM -0700, Christoph Hellwig wrote: > On Wed, Sep 17, 2014 at 06:54:06AM +1000, Dave Chinner wrote: > > So how do existing utf8/unicode enabled filesystems handle this? > > > > I think we should be consistent with ZFS, MacOS and others that > > already deal with this problem if at all possible. Here's a data point from man(zfs): The following three properties cannot be changed after the file system is created, and therefore, should be set when the file system is cre- ated. If the properties are not set with the "zfs create" or "zpool create" commands, these properties are inherited from the parent dataset. If the parent dataset lacks these properties due to having been created prior to these features being supported, the new file sys- tem will have the default values for these properties. casesensitivity = sensitive | insensitive | mixed Indicates whether the file name matching algorithm used by the file system should be case-sensitive, case-insensitive, or allow a com- bination of both styles of matching. The default value for the "casesensitivity" property is "sensitive." Traditionally, UNIX and POSIX file systems have case-sensitive file names. The "mixed" value for the "casesensitivity" property indicates that the file system can support requests for both case-sensitive and case-insensitive matching behavior. Currently, case-insensitive matching behavior on a file system that supports mixed behavior is limited to the Solaris CIFS server product. For more information about the "mixed" value behavior, see the ZFS Administration Guide. normalization =none | formD | formKCf Indicates whether the file system should perform a unicode normal- ization of file names whenever two file names are compared, and which normalization algorithm should be used. File names are always stored unmodified, names are normalized as part of any comparison process. If this property is set to a legal value other than "none," and the "utf8only" property was left unspecified, the "utf8only" property is automatically set to "on." The default value of the "normalization" property is "none." This property cannot be changed after the file system is created. utf8only =on | off Indicates whether the file system should reject file names that include characters that are not present in the UTF-8 character code set. If this property is explicitly set to "off," the normalization property must either not be explicitly set or be set to "none." The default value for the "utf8only" property is "off." This property cannot be changed after the file system is created. The "casesensitivity," "normalization," and "utf8only" properties are also new permissions that can be assigned to non-privileged users by using the ZFS delegated administration feature. The original link: https://www.freebsd.org/cgi/man.cgi?query=zfs&apropos=0&sektion=0&manpath=FreeBSD+8.1-RELEASE&format=html > > However, this > > really is a wider policy decision for the kernel/VFS as we want > > consistent behaviour across all linux filesystems, hence this > > patchset really needs to discussed at the lkml/-fsdevel level... > > Absolutely. I've also talked to a few Samba folks at SDC, and one > thing they would love to see is conditional case insensitive lookups, > e.g.: > > - we hash case insensitive with collisions, but perform normal case > sensitive lookups. > - with a new AT_CASE_INSENSTIVE flag to the various *at calls that > gets passed down to the dcache we enable CI lookups. I'm working on addressing some of the initial feedback and will be in a position to post for a wider audience later in the week. Thanks, Ben From david@fromorbit.com Tue Sep 16 16:53:52 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 923247F47 for ; Tue, 16 Sep 2014 16:53:52 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7D80B8F8039 for ; Tue, 16 Sep 2014 14:53:52 -0700 (PDT) X-ASG-Debug-ID: 1410904429-04cbb05488e25d70001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id BsM3qlmeVrWPDSDk for ; Tue, 16 Sep 2014 14:53:49 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AkE4ANKwGFR5LCtm/2dsb2JhbABggw2BKoIssWsGBZYRhWsCAgEBgRUXAXmERBwjGCQ0BSUDIROIPbxuGBiFZIlPhFIFhh+WapVGg3ArL4JKAQEB Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail07.adl2.internode.on.net with ESMTP; 17 Sep 2014 07:23:49 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XU0gq-00036z-AF; Wed, 17 Sep 2014 07:53:36 +1000 Date: Wed, 17 Sep 2014 07:53:36 +1000 From: Dave Chinner To: Al Viro Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Subject: [BUG, 3.17-rc4] dentry still in use during unmount Message-ID: <20140916215336.GL4322@dastard> X-ASG-Orig-Subj: [BUG, 3.17-rc4] dentry still in use during unmount MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1410904429 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9558 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi Al, One of my xfstest rigs tripped over this last night when running xfs/301 on a pair of 4G ramdisks during an auto group run: BUG: Dentry ffff8803c14fc870{i=0,n=dir} still in use (-127) [unmount of xfs ram1] ------------[ cut here ]------------ WARNING: CPU: 4 PID: 27856 at fs/dcache.c:1319 umount_check+0x7f/0x90() Modules linked in: CPU: 4 PID: 27856 Comm: umount Tainted: G W 3.17.0-rc4-dgc+ #479 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 0000000000000009 ffff88025eeefd80 ffffffff81cf7327 0000000000000000 ffff88025eeefdb8 ffffffff810933bd ffff8803c14fc870 ffff88011aeba800 ffffffff81db2860 ffff88023acf72c0 00000000002353d2 ffff88025eeefdc8 Call Trace: [] dump_stack+0x45/0x56 [] warn_slowpath_common+0x7d/0xa0 [] warn_slowpath_null+0x1a/0x20 [] umount_check+0x7f/0x90 [] d_walk+0x66/0x2c0 [] ? d_lru_del+0xa0/0xa0 [] do_one_tree+0x26/0x40 [] shrink_dcache_for_umount+0x5a/0x90 [] generic_shutdown_super+0x21/0xf0 [] kill_block_super+0x3c/0x90 [] deactivate_locked_super+0x49/0x60 [] deactivate_super+0x46/0x60 [] mntput_no_expire+0xca/0x120 [] SyS_umount+0x8e/0x100 [] system_call_fastpath+0x16/0x1b ---[ end trace 15254c3c565abf1a ]--- VFS: Busy inodes after unmount of ram1. Self-destruct in 5 seconds. Have a nice day... I can't reproduce it easily: $ sudo MKFS_OPTIONS="-m crc=1,finobt=1" ./check xfs/301 FSTYP -- xfs (debug) PLATFORM -- Linux/x86_64 test4 3.17.0-rc4-dgc+ MKFS_OPTIONS -- -f -m crc=1,finobt=1 /dev/ram1 MOUNT_OPTIONS -- /dev/ram1 /mnt/scr xfs/301 12s ... 12s Ran: xfs/301 Passed all 1 tests $ And even run in a loop for 20 minutes it hasn't triggered the error. I haven't seen this before, so I thought I better give you the heads up just in case. Cheers, Dave. -- Dave Chinner david@fromorbit.com From bmh@rincon.com Tue Sep 16 17:03:14 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 3F32F7F47 for ; Tue, 16 Sep 2014 17:03:14 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1E5928F8039 for ; Tue, 16 Sep 2014 15:03:10 -0700 (PDT) X-ASG-Debug-ID: 1410904989-04bdf010a0adf4b0001-NocioJ Received: from autodiscover.rincon.com (smtp.rincon.com [67.128.198.140]) by cuda.sgi.com with ESMTP id j6yCIPIJEIFyLlRq for ; Tue, 16 Sep 2014 15:03:09 -0700 (PDT) X-Barracuda-Envelope-From: bmh@rincon.com X-Barracuda-Apparent-Source-IP: 67.128.198.140 Received: from brhazbriklab3.rinconres.com (172.16.203.59) by autodiscover.rincon.com (172.16.203.52) with Microsoft SMTP Server id 14.3.195.1; Tue, 16 Sep 2014 15:03:08 -0700 Message-ID: <5418B39C.2060707@rincon.com> Date: Tue, 16 Sep 2014 15:03:08 -0700 From: Brian Hemme User-Agent: Mozilla/5.0 (X11; Linux i686 on x86_64; rv:7.0.1) Gecko/20110929 Thunderbird/7.0.1 MIME-Version: 1.0 To: Subject: mkfs.xfs fails with raid5 and smaller chunk sizes Content-Type: text/plain; charset="ISO-8859-1"; format=flowed X-ASG-Orig-Subj: mkfs.xfs fails with raid5 and smaller chunk sizes Content-Transfer-Encoding: 7bit X-Barracuda-Connect: smtp.rincon.com[67.128.198.140] X-Barracuda-Start-Time: 1410904989 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9558 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hello all, I am having some odd problems with mkfs.xfs when used on a raid 5 array. The array is built from 6 960GB SSDs all connected to SATA ports on the MB and created with mdadm. If I use a chunk size any smaller then 512K mkfs.xfs just hangs forever. It continues to use CPU and so does the raid array but never completes. If the system is just left running for an extended length of time the whole OS eventually locks up. I have tried this on three different systems with the same results. I have searched all over for someone with similar issues without success. I am hoping I am just doing something clearly wrong and you all can set me straight quickly. Some specifics: Arch linux with 3.14.1 kernel mkfs.xfs version 3.1.11 mdadm - v3.3 - 3rd September 2013 Commands: > mdadm --create /dev/md0 --chunk=64K --level=5 --raid-devices=6 /dev/sd[a-f] > mkfs.xfs /dev/md0 ** This command fails and locks up I have tried specifying the arguments to mkfs.xfs with the same results. Building a 4 drive array seems to require a chunk size of 1M or greater to work. Same results if I make a partition on the array and make the fs there. Any help would be appreciated Thanks Brian From david@fromorbit.com Tue Sep 16 17:03:49 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 4F3207F47 for ; Tue, 16 Sep 2014 17:03:49 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id C30D4AC007 for ; Tue, 16 Sep 2014 15:03:45 -0700 (PDT) X-ASG-Debug-ID: 1410905022-04cb6c54feb53bd0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id LOn23fJyhRtUVtLm for ; Tue, 16 Sep 2014 15:03:43 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AkAgACezGFR5LCtm/2dsb2JhbABggw0gM1eCLLFrBpQvAoFlhWsEgRcXAXmEYDskNAUlAzSIPZdApUgYhWSJbIIhD0SBQQWGH49lhwWVRoFGgiorL4JKAQEB Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail07.adl2.internode.on.net with ESMTP; 17 Sep 2014 07:33:42 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XU0qP-0003BO-G0 for xfs@oss.sgi.com; Wed, 17 Sep 2014 08:03:29 +1000 Date: Wed, 17 Sep 2014 08:03:29 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [ANNOUNCE] xfsprogs: master branch updated to 794b62f Message-ID: <20140916220329.GM4322@dastard> X-ASG-Orig-Subj: [ANNOUNCE] xfsprogs: master branch updated to 794b62f MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="ReaqsoxgOBHFXBhH" Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1410905022 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9558 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- --ReaqsoxgOBHFXBhH Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi folks, The xfsprogs repository at git://oss.sgi.com/xfs/cmds/xfsprogs has just been updated. The new head of the master branch is commit: 794b62f xfsprogs: add supported file attributes to xfs.5 manpage New Commits: Eric Sandeen (10): [713ba3f] xfs_io: free fshandlep in parent_check() [4f10a2f] xfs_fsr: fix leaks & catch error in fsrfile() [e3e2793] xfs_fsr: free handlep in fsrfs [8f1c8e1] libhandle: Fix handle leak in path_to_fshandle error paths [70ac12f] xfs_io: fix leaks in parent_list() [9c1c2e3] xfs_db: free flist on error in write_struct() [5cd0710] xfs_repair: clear bad flags in process_dinode_int [50aeb09] xfs_repair: preserve error state in process_shortform_attr [4f20f6a] xfs_io: add mremap command [794b62f] xfsprogs: add supported file attributes to xfs.5 manpage Jan Kara (1): [937ef31] repair: Set ftype for entries in lost+found Jan Tulak (1): [02ef543] libhandle: fix installation for symlinked /usr Mark Tinguely (1): [4263df5] mkfs: fix typo in output Code Diffstat: db/write.c | 1 + fsr/xfs_fsr.c | 31 ++++++++++++---------- include/buildmacros | 9 ++++--- io/mmap.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++= ++++ io/parent.c | 13 ++++++---- libhandle/handle.c | 1 + man/man5/xfs.5 | 22 +++++++++++++++- man/man8/xfs_io.8 | 14 ++++++++++ mkfs/xfs_mkfs.c | 2 +- po/pl.po | 2 +- repair/attr_repair.c | 3 ++- repair/dinode.c | 6 ++--- repair/phase6.c | 4 +-- 13 files changed, 149 insertions(+), 32 deletions(-) --=20 Dave Chinner david@fromorbit.com --ReaqsoxgOBHFXBhH Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAEBAgAGBQJUGLOwAAoJEK3oKUf0dfodj+AQAMCy7Bwrpp/EfbDfsfiYAo35 +ewYlCZ5nbEK5Jwtf/C/M1rVAzwSML2ykdJfLHh6aW63N+xCn2bUnBhKKeJyWJ+1 +4qzRC1oj86z6C3/jYClOvdFwqBRIcX3PZ8ZRbvLM0FNMCbYUvTUj2T8izeEHH40 kUx336+zLUZUyoeecIopcFH4W3WzSPMUcw1sDwwJIUJZHzg3PgjoHcjui038QfGP Ec8nouyV0E5BjSwLbgIIeMe9xLbwmGTHDzT2J/Ef8+MN0GGi5wP2OO9il9rK+wmI qaps27jwqARRbFjwpkCvdCCghAARJdMdi9KRwupGeS143GibZiufrwJsrCMl2GJ0 9g74TJY1nnJI7wIrwAfWPAD+1faS0fuwpfkvXdBwhqfHwgO7KNjci52AdxwdtKHS etkhQgZuaFpBzq9jRT9AZItLJfX92jqzKfsFVX6NOT8GbECsqVl+sqF8i7n5sr4R qb8s3uXG61iHjvLYFSB/iTteVW/t8GlSbMpa2HHX3CTJHy57h1rMK0y+xflLgIek jotyjJzO8TQcBf2UrBvLJpC2fIIK1yItPSg+alO/bY/aA31YtYmclUcX5vxDIC1T n40e3+LoXCKmjnIc0TMV/YTgztWfyeP19GQRICo+N7qxH/aTXkNmz3zKsjY6J74L us7vXYEwIZQk82DJnUOP =YWgP -----END PGP SIGNATURE----- --ReaqsoxgOBHFXBhH-- From sandeen@sandeen.net Tue Sep 16 17:06:19 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 16AFA7F47 for ; Tue, 16 Sep 2014 17:06:19 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 01C3C8F8039 for ; Tue, 16 Sep 2014 15:06:18 -0700 (PDT) X-ASG-Debug-ID: 1410905177-04cb6c5500b53d40001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id QngQhAUHL2leqprA for ; Tue, 16 Sep 2014 15:06:17 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 40D6560F9698 for ; Tue, 16 Sep 2014 17:06:17 -0500 (CDT) Message-ID: <5418B459.1010204@sandeen.net> Date: Tue, 16 Sep 2014 17:06:17 -0500 From: Eric Sandeen MIME-Version: 1.0 To: xfs-oss Subject: Re: [PATCH 2/2 V2] xfs_db: add crc manipulation commands References: <540B4399.4020804@sandeen.net> <5418574A.8040102@sandeen.net> X-ASG-Orig-Subj: Re: [PATCH 2/2 V2] xfs_db: add crc manipulation commands In-Reply-To: <5418574A.8040102@sandeen.net> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410905177 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9558 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/16/14 10:29 AM, Eric Sandeen wrote: > This adds a new "crc" command to xfs_db for CRC-enabled filesystems. > > If a structure has a CRC field, we can validate it, invalidate/corrupt > it, or revalidate/rewrite it: > > xfs_db> sb 0 > xfs_db> crc -v > crc = 0x796c814f (correct) > xfs_db> crc -i > Metadata CRC error detected at block 0x0/0x200 > crc = 0x796c8150 (bad) > xfs_db> crc -r > crc = 0x796c814f (correct) On reflection, do you think these should be more verbose, something like: xfs_db> sb 0 xfs_db> crc -v Validating crc: crc = 0x796c814f (correct) xfs_db> crc -i Invalidating CRC: Metadata CRC error detected at block 0x0/0x200 crc = 0x796c8150 (bad) xfs_db> crc -r Rewriting CRC: crc = 0x796c814f (correct) From david@fromorbit.com Tue Sep 16 17:10:22 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id A31377F4E for ; Tue, 16 Sep 2014 17:10:22 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 61D6D8F8054 for ; Tue, 16 Sep 2014 15:10:22 -0700 (PDT) X-ASG-Debug-ID: 1410905419-04bdf01097adf940001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id SbT3fXMkcEK9JFDD for ; Tue, 16 Sep 2014 15:10:19 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AmM2AFe0GFR5LCtm/2dsb2JhbABggw2BKoIssWsGlhaFawICAQEBgRQXAXmEBAEBBAwmASMjEAgDGAkQAhMPBSUDNIg9vG4YGIVkiU8HFhEChCIFnQmVRoNwKy9nIYFCAQEB Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail07.adl2.internode.on.net with ESMTP; 17 Sep 2014 07:40:19 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XU0wn-0003Cf-Ga; Wed, 17 Sep 2014 08:10:05 +1000 Date: Wed, 17 Sep 2014 08:10:05 +1000 From: Dave Chinner To: weber@zbfmail.de Cc: Xfs Subject: Re: unclean shutdown of usb hdd destroyed xfs partially Message-ID: <20140916221005.GN4322@dastard> X-ASG-Orig-Subj: Re: unclean shutdown of usb hdd destroyed xfs partially References: <3999c95c0dc7ebfdfbb2853a6d13f7dc@zbfmail.de> <082ebd288523ee6155b66debade2a775@zbfmail.de> <20140913220916.GC4267@dastard> <330c89398cb4eef9b7289c1ffef8bcc3@zbfmail.de> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <330c89398cb4eef9b7289c1ffef8bcc3@zbfmail.de> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1410905419 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9558 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header On Tue, Sep 16, 2014 at 11:27:45PM +0200, Marko Weber|8000 wrote: > > > Am 2014-09-14 00:09, schrieb Dave Chinner: > >On Sat, Sep 13, 2014 at 04:36:59PM +0200, Marko Weber|8000 wrote: > >> > >>an output of xfs_repair -v -L /dev/sde1 > >... > >> > >> # xfs_repair -v -L /dev/sde1 > > > >What version? > > first it was 3.1.10 > later like posted 3.2.1 > > > > >>Phase 1 - Superblock finden und überprüfen... > >> - Berichts-Prozess in Abständen von 15 Minutes > >> - Block-Zwischenspeichergröße ist auf 1487792 Einträge gesetzt > >>Phase 2 - ein internes Protokoll benutzen > >> - Null-Protokoll... > >>zero_log: head block 40 tail block 40 > >> - freier Speicher und Inode-Karten des Dateisystems werden > >>gescannt... > >>bad magic numberbad magic numberbad magic number > >.... > >>falscher on-disk-Superblock 12 - falsche Magische Nummer > >>Metadata corruption detected at block > >>0x20bf8e50/0x1000primäre/sekundärer Superblock-12-Konflikt - > >>AG-Superblock-Geometrie-Info hat einen Konflikt mit der > >>Dateisystem-Geometrie > >>flasche magische # 0x0 für agf 12 > >>falsche Version # 0 für agf 12 > >> > >>Metadata corruption detected at block 0x417f1c90/0x1000 > >>falscher on-disk-Superblock 6 - falsche Magische Nummer > >>primäre/sekundärer Superblock-6-Konflikt - > >>AG-Superblock-Geometrie-Info hat einen Konflikt mit der > >>Dateisystem-Geometrie > >>falscher on-disk-Superblock 3 - falsche Magische Nummer > >>ungenutzten Anteil des »sekundär«-Superblocks nullen (AG #6) > >>Metadata corruption detected at block 0x57542610/0x1000 > >>falsche Sequenz # 0 für agf 12 > >>Metadata corruption detected at block > >>0x7813b450/0x1000Speicherzugriffsfehler > > > >I don't read german(?) but that looks like many AG header block > >have been overwritten with zeros (0 magic number, 0 sequence #, 0 > >length, etc) and so even if we can repair the filesystem, I'd > >suggest that you need to verify that the data in every file in the > >filesystem is correct. > > > >Is that as far as xfs_repair got? If so, it would have appeared to > >crash. Can you run the lastest version inside gdb to get a stack > >trace when it dies? Or, alternatively, provide a metadump for one of > >us to look at more closely? > > yes, this is as far xfs_repair got it. > what is ment 'run latest version in gdb?' gnudebugger? how do i do > that? console example needed. > and how do i do the metadump? # gdb /path/to/build/area/repair/xfs_repair .... (gdb) run ..... (gdb) bt Paste the entire output of the gdb session. Best if you can run it with your language settings to output english error messages, too (LANG=C, I think). As for running metadump: 'man xfs_metadump', compress the resultant image and send me a link to where I can download it from. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Tue Sep 16 17:17:55 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 5009D7F47 for ; Tue, 16 Sep 2014 17:17:55 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1ECCC8F8039 for ; Tue, 16 Sep 2014 15:17:54 -0700 (PDT) X-ASG-Debug-ID: 1410905872-04bdf010a0ae00f0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id QopbKKTWDqXuFMiT for ; Tue, 16 Sep 2014 15:17:52 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AuAfANC2GFR5LCtm/2dsb2JhbABggw2BKoIssWsGlhaFawQCAYEUFwF5hAQBAQQ6HCMQCAMOCgklDwUlAyETiD28cBgYhWSJTweESwWdCZVGg3ArL4JKAQEB Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail07.adl2.internode.on.net with ESMTP; 17 Sep 2014 07:47:52 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XU147-0003Eb-02; Wed, 17 Sep 2014 08:17:39 +1000 Date: Wed, 17 Sep 2014 08:17:38 +1000 From: Dave Chinner To: Brian Hemme Cc: xfs@oss.sgi.com Subject: Re: mkfs.xfs fails with raid5 and smaller chunk sizes Message-ID: <20140916221738.GO4322@dastard> X-ASG-Orig-Subj: Re: mkfs.xfs fails with raid5 and smaller chunk sizes References: <5418B39C.2060707@rincon.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5418B39C.2060707@rincon.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1410905872 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9558 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 16, 2014 at 03:03:08PM -0700, Brian Hemme wrote: > Hello all, > > I am having some odd problems with mkfs.xfs when used on a raid 5 > array. The array is built from 6 960GB SSDs all connected to SATA > ports on the MB and created with mdadm. If I use a chunk size any > smaller then 512K mkfs.xfs just hangs forever. It continues to use > CPU and so does the raid array but never completes. If the system > is just left running for an extended length of time the whole OS > eventually locks up. I have tried this on three different systems > with the same results. I have searched all over for someone with > similar issues without success. I am hoping I am just doing > something clearly wrong and you all can set me straight quickly. > > Some specifics: > Arch linux with 3.14.1 kernel > mkfs.xfs version 3.1.11 > mdadm - v3.3 - 3rd September 2013 > > Commands: > > mdadm --create /dev/md0 --chunk=64K --level=5 --raid-devices=6 > /dev/sd[a-f] > > mkfs.xfs /dev/md0 > ** This command fails and locks up > > I have tried specifying the arguments to mkfs.xfs with the same > results. Building a 4 drive array seems to require a chunk size of > 1M or greater to work. Same results if I make a partition on the > array and make the fs there. mkfs.xfs really should only take a couple of seconds to complete. Seeing as you are using SSDs, my first suspicion is that md or the SSDs are having problems with discard. Hence you should first try 'mkfs.xfs -K /dev/md0' and see if that completes quickly. Otherwise, output of 'echo w > sysrq-trigger' from dmesg would be a good start, as would a 'perf top -G -U' snapshot (run for 30s at least a minute after mkfs.xfs starts) to tell us what is burning CPU. Cheers, Dave. -- Dave Chinner david@fromorbit.com From viro@ftp.linux.org.uk Tue Sep 16 17:30:50 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 2923B7F47 for ; Tue, 16 Sep 2014 17:30:50 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id ADF53AC00B for ; Tue, 16 Sep 2014 15:30:49 -0700 (PDT) X-ASG-Debug-ID: 1410906646-04bdf0109aae08f0001-NocioJ Received: from ZenIV.linux.org.uk (zeniv.linux.org.uk [195.92.253.2]) by cuda.sgi.com with ESMTP id PGd4A3PexB7WUYnV (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 16 Sep 2014 15:30:47 -0700 (PDT) X-Barracuda-Envelope-From: viro@ftp.linux.org.uk X-Barracuda-Apparent-Source-IP: 195.92.253.2 Received: from viro by ZenIV.linux.org.uk with local (Exim 4.76 #1 (Red Hat Linux)) id 1XU1Gm-00073Q-55; Tue, 16 Sep 2014 22:30:44 +0000 Date: Tue, 16 Sep 2014 23:30:44 +0100 From: Al Viro To: Dave Chinner Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [BUG, 3.17-rc4] dentry still in use during unmount Message-ID: <20140916223043.GY7996@ZenIV.linux.org.uk> X-ASG-Orig-Subj: Re: [BUG, 3.17-rc4] dentry still in use during unmount References: <20140916215336.GL4322@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140916215336.GL4322@dastard> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: Al Viro X-Barracuda-Connect: zeniv.linux.org.uk[195.92.253.2] X-Barracuda-Start-Time: 1410906647 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=COMMA_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9559 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 COMMA_SUBJECT Subject is like 'Re: FDSDS, this is a subject' On Wed, Sep 17, 2014 at 07:53:36AM +1000, Dave Chinner wrote: > Hi Al, > > One of my xfstest rigs tripped over this last night when running > xfs/301 on a pair of 4G ramdisks during an auto group run: > > BUG: Dentry ffff8803c14fc870{i=0,n=dir} still in use (-127) [unmount of xfs ram1] Umm... -127 == "already got past the beginning of __dentry_kill()". And if it had been seen by d_walk() callback, it must have gotten past the point where __dentry_kill() unlocks that sucker. Very interesting... I don't see how that could happen, TBH - __dentry_kill() is called with parent and victim locked; it sets DCACHE_DENTRY_KILLED and removes the victim from parent's ->d_subdirs before dropping either lock. Moreover, the victim can't have any children at that point - it must have had the last reference held by called of __dentry_kill() and each child would've contributed to refcount. And d_walk() goes through the list of children with parent kept locked. It does unlock the parent after walking one level deeper, but on the way back it * checks that there had been no renames * checks that child isn't marked with DCACHE_DENTRY_KILLED after relocking the parent. In case of anything fishy it restarts the whole thing with renames excluded. If those tests succeed, we are guaranteed that we'll continue walking the parent's list of children with parent locked, AFAICS, not that there could legitimately be anything playing with the dentry tree modifications in parallel with fs shutdown... It might be interesting to slap WARN_ON(dentry->d_flags & DCACHE_DENTRY_KILLED) for dentry and target in __d_move() and for anon in __d_materialise_dentry(), after dentry_lock_for_move() in both functions. And see if it triggers. IOW, whether it's possible for doomed dentry to be readded to someone's ->d_subdirs after it has entered __dentry_kill(). From david@fromorbit.com Tue Sep 16 17:41:13 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 5193B7F47 for ; Tue, 16 Sep 2014 17:41:13 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id C308CAC008 for ; Tue, 16 Sep 2014 15:41:12 -0700 (PDT) X-ASG-Debug-ID: 1410907269-04cbb05487e280e0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id 0mAsAXehOSLjHDwZ for ; Tue, 16 Sep 2014 15:41:10 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AuEfAIS7GFR5LCtm/2dsb2JhbABYCIMNgSqCLLFrBpYWhWsEAgGBExcBeYQEAQEEJxMcIxAIAxgJJQ8FJQMhE4g9vHUYGIVkiHlWB4RLBZ0JlUaDcCsvgkoBAQE Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail07.adl2.internode.on.net with ESMTP; 17 Sep 2014 08:11:09 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XU1Qe-0003IE-87; Wed, 17 Sep 2014 08:40:56 +1000 Date: Wed, 17 Sep 2014 08:40:56 +1000 From: Dave Chinner To: Al Viro Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [BUG, 3.17-rc4] dentry still in use during unmount Message-ID: <20140916224056.GP4322@dastard> X-ASG-Orig-Subj: Re: [BUG, 3.17-rc4] dentry still in use during unmount References: <20140916215336.GL4322@dastard> <20140916223043.GY7996@ZenIV.linux.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140916223043.GY7996@ZenIV.linux.org.uk> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1410907269 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=COMMA_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9559 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 COMMA_SUBJECT Subject is like 'Re: FDSDS, this is a subject' On Tue, Sep 16, 2014 at 11:30:44PM +0100, Al Viro wrote: > On Wed, Sep 17, 2014 at 07:53:36AM +1000, Dave Chinner wrote: > > Hi Al, > > > > One of my xfstest rigs tripped over this last night when running > > xfs/301 on a pair of 4G ramdisks during an auto group run: > > > > BUG: Dentry ffff8803c14fc870{i=0,n=dir} still in use (-127) [unmount of xfs ram1] > > Umm... -127 == "already got past the beginning of __dentry_kill()". And if > it had been seen by d_walk() callback, it must have gotten past the point where > __dentry_kill() unlocks that sucker. > > Very interesting... I don't see how that could happen, TBH - __dentry_kill() > is called with parent and victim locked; it sets DCACHE_DENTRY_KILLED and > removes the victim from parent's ->d_subdirs before dropping either lock. > Moreover, the victim can't have any children at that point - it must have > had the last reference held by called of __dentry_kill() and each child > would've contributed to refcount. > > And d_walk() goes through the list of children with parent kept locked. > It does unlock the parent after walking one level deeper, but on the > way back it > * checks that there had been no renames > * checks that child isn't marked with DCACHE_DENTRY_KILLED > after relocking the parent. In case of anything fishy it restarts the > whole thing with renames excluded. If those tests succeed, we are guaranteed > that we'll continue walking the parent's list of children with parent locked, > AFAICS, not that there could legitimately be anything playing with the > dentry tree modifications in parallel with fs shutdown... > > It might be interesting to slap WARN_ON(dentry->d_flags & DCACHE_DENTRY_KILLED) > for dentry and target in __d_move() and for anon in __d_materialise_dentry(), > after dentry_lock_for_move() in both functions. And see if it triggers. > IOW, whether it's possible for doomed dentry to be readded to someone's > ->d_subdirs after it has entered __dentry_kill(). Ok, I'll add a debug patch to my test kernels that add these and I'll let you know if anything triggers. Cheers, Dave. -- Dave Chinner david@fromorbit.com From dave@fromorbit.com Tue Sep 16 17:46:03 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E7A927F47 for ; Tue, 16 Sep 2014 17:46:02 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 83530AC007 for ; Tue, 16 Sep 2014 15:46:02 -0700 (PDT) X-ASG-Debug-ID: 1410907560-04bdf010a0ae1160001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id fRDugdCvComq4CDT for ; Tue, 16 Sep 2014 15:46:00 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Aj8OAIu8GFR5LCtm/2dsb2JhbABggw2BKrQXBpwHgRIXAXmEMS87GGoDNBuIIpdLpUiFfIQEhUCEXQWyT4FGgiorL4JKAQEB Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail07.adl2.internode.on.net with ESMTP; 17 Sep 2014 08:15:59 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XU1VL-0003JL-9Z for xfs@oss.sgi.com; Wed, 17 Sep 2014 08:45:47 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XU1VL-0002Pq-8R for xfs@oss.sgi.com; Wed, 17 Sep 2014 08:45:47 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH] xfs: flush entire last page of old EOF on truncate up Date: Wed, 17 Sep 2014 08:45:47 +1000 X-ASG-Orig-Subj: [PATCH] xfs: flush entire last page of old EOF on truncate up Message-Id: <1410907547-9253-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1410907560 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9559 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner On a sub-page sized filesystem, truncating a mapped region down leaves us in a world of hurt. We truncate the pagecache, zeroing the newly unused tail, then punch blocks out from under the page. If we then truncate the file back up immediately, we expose that unmapped hole to a dirty page mapped into the user application, and that's where it all goes wrong. In truncating the page cache, we avoid unmapping the tail page of the cache because it still contains valid data. The problem is that it also contains a hole after the truncate, but nobody told the mm subsystem that. Therefore, if the page is dirty before the truncate, we'll never get a .page_mkwrite callout after we extend the file and the application writes data into the hole on the page. Hence when we come to writing that region of the page, it has no blocks and no delayed allocation reservation and hence we toss the data away. This patch adds code to the truncate up case to solve it, by ensuring the partial page at the old EOF is always cleaned after we do any zeroing and move the EOF upwards. We can't actually serialise the page writeback and truncate against page faults (yes, that problem AGAIN) so this is really just a best effort and assumes it is extremely unlikely that someone is concurrently writing to the page at the EOF while extending the file. Signed-off-by: Dave Chinner --- fs/xfs/xfs_iops.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 63aeca8..a726d37 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -853,6 +853,36 @@ xfs_setattr_size( return error; truncate_setsize(inode, newsize); + /* + * The "we can't serialise against page faults" pain gets worse. + * + * If the file is mapped then we have to clean the page at the old EOF + * when extending the file. Extending the file can expose changes the + * underlying page mapping (e.g. from beyond EOF to a hole or + * unwritten), and so on the next attempt to write to that page we need + * to remap it for write. i.e. we need .page_mkwrite() to be called. + * Hence we need to clean the page to clean the pte and so a new write + * fault will be triggered appropriately. + * + * If we do it before we change the inode size, then we can race with a + * page fault that maps the page with exactly the same problem. If we do + * it after we change the file size, then a new page fault can come in + * and allocate space before we've run the rest of the truncate + * transaction. That's kinda grotesque, but it's better than have data + * over a hole, and so that's the lesser evil that has been chosen here. + * + * The real solution, however, is to have some mechanism for locking out + * page faults while a truncate is in progress. + */ + if (newsize > oldsize && mapping_mapped(VFS_I(ip)->i_mapping)) { + error = filemap_write_and_wait_range( + VFS_I(ip)->i_mapping, + round_down(oldsize, PAGE_CACHE_SIZE), + round_up(oldsize, PAGE_CACHE_SIZE) - 1); + if (error) + return error; + } + tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE); error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0); if (error) -- 2.0.0 From bmh@rincon.com Tue Sep 16 17:47:47 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BFD2B7F47 for ; Tue, 16 Sep 2014 17:47:47 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3ECAFAC008 for ; Tue, 16 Sep 2014 15:47:46 -0700 (PDT) X-ASG-Debug-ID: 1410907664-04cb6c54ffb556c0001-NocioJ Received: from autodiscover.rincon.com (smtp.rincon.com [67.128.198.140]) by cuda.sgi.com with ESMTP id PcdrxtJtefnsVqU0 for ; Tue, 16 Sep 2014 15:47:44 -0700 (PDT) X-Barracuda-Envelope-From: bmh@rincon.com X-Barracuda-Apparent-Source-IP: 67.128.198.140 Received: from brhazbriklab3.rinconres.com (172.16.203.59) by autodiscover.rincon.com (172.16.203.53) with Microsoft SMTP Server id 14.3.195.1; Tue, 16 Sep 2014 15:47:43 -0700 Message-ID: <5418BE0F.9040702@rincon.com> Date: Tue, 16 Sep 2014 15:47:43 -0700 From: Brian Hemme User-Agent: Mozilla/5.0 (X11; Linux i686 on x86_64; rv:7.0.1) Gecko/20110929 Thunderbird/7.0.1 MIME-Version: 1.0 To: Dave Chinner CC: Subject: Re: mkfs.xfs fails with raid5 and smaller chunk sizes References: <5418B39C.2060707@rincon.com> <20140916221738.GO4322@dastard> X-ASG-Orig-Subj: Re: mkfs.xfs fails with raid5 and smaller chunk sizes In-Reply-To: <20140916221738.GO4322@dastard> Content-Type: text/plain; charset="ISO-8859-1"; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: smtp.rincon.com[67.128.198.140] X-Barracuda-Start-Time: 1410907664 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9560 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 09/16/2014 03:17 PM, Dave Chinner wrote: > On Tue, Sep 16, 2014 at 03:03:08PM -0700, Brian Hemme wrote: >> Hello all, >> >> I am having some odd problems with mkfs.xfs when used on a raid 5 >> array. The array is built from 6 960GB SSDs all connected to SATA >> ports on the MB and created with mdadm. If I use a chunk size any >> smaller then 512K mkfs.xfs just hangs forever. It continues to use >> CPU and so does the raid array but never completes. If the system >> is just left running for an extended length of time the whole OS >> eventually locks up. I have tried this on three different systems >> with the same results. I have searched all over for someone with >> similar issues without success. I am hoping I am just doing >> something clearly wrong and you all can set me straight quickly. >> >> Some specifics: >> Arch linux with 3.14.1 kernel >> mkfs.xfs version 3.1.11 >> mdadm - v3.3 - 3rd September 2013 >> >> Commands: >>> mdadm --create /dev/md0 --chunk=64K --level=5 --raid-devices=6 >> /dev/sd[a-f] >>> mkfs.xfs /dev/md0 >> ** This command fails and locks up >> >> I have tried specifying the arguments to mkfs.xfs with the same >> results. Building a 4 drive array seems to require a chunk size of >> 1M or greater to work. Same results if I make a partition on the >> array and make the fs there. > mkfs.xfs really should only take a couple of seconds to complete. > Seeing as you are using SSDs, my first suspicion is that md or the > SSDs are having problems with discard. Hence you should first > try 'mkfs.xfs -K /dev/md0' and see if that completes quickly. > > Otherwise, output of 'echo w> sysrq-trigger' from dmesg would be a > good start, as would a 'perf top -G -U' snapshot (run for 30s at > least a minute after mkfs.xfs starts) to tell us what is burning > CPU. > > Cheers, > > Dave. Thanks for the quick response! Adding the -K seemed to do the trick. However, for my education, why is this needed in this case? It seems to work without it for larger chunk sizes or for raid 0 instead of 5. It also worked on our old install with a 3.1.6 kernel. Any why would not using the -K cause enough of a problem that the whole machine hangs? Just trying to understand this enough to make sure I don't run into problems down the road. Thanks again, Brian From david@fromorbit.com Tue Sep 16 18:53:15 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 1D8767F47 for ; Tue, 16 Sep 2014 18:53:15 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0B0F28F8039 for ; Tue, 16 Sep 2014 16:53:11 -0700 (PDT) X-ASG-Debug-ID: 1410911589-04cbb05486e2a9a0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id 1XvInlUuvB4UAzIK for ; Tue, 16 Sep 2014 16:53:09 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: At8fACjNGFR5LCtm/2dsb2JhbABggw2BKoIssWsGlhaFawQCAYESFwF5hAQBAQQ6HCMQCAMYCSUPBSUDIROIPbxxGBiFZIlPB4RLBZ0JjDKJFINwKy+BCB8FgR4BAQE Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail07.adl2.internode.on.net with ESMTP; 17 Sep 2014 09:22:44 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XU2Xs-0003U4-KS; Wed, 17 Sep 2014 09:52:28 +1000 Date: Wed, 17 Sep 2014 09:52:28 +1000 From: Dave Chinner To: Eric Sandeen Cc: xfs-oss Subject: Re: [PATCH 2/2 V2] xfs_db: add crc manipulation commands Message-ID: <20140916235228.GQ4322@dastard> X-ASG-Orig-Subj: Re: [PATCH 2/2 V2] xfs_db: add crc manipulation commands References: <540B4399.4020804@sandeen.net> <5418574A.8040102@sandeen.net> <5418B459.1010204@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5418B459.1010204@sandeen.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1410911589 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9562 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 16, 2014 at 05:06:17PM -0500, Eric Sandeen wrote: > On 9/16/14 10:29 AM, Eric Sandeen wrote: > > This adds a new "crc" command to xfs_db for CRC-enabled filesystems. > > > > If a structure has a CRC field, we can validate it, invalidate/corrupt > > it, or revalidate/rewrite it: > > > > xfs_db> sb 0 > > xfs_db> crc -v > > crc = 0x796c814f (correct) > > xfs_db> crc -i > > Metadata CRC error detected at block 0x0/0x200 > > crc = 0x796c8150 (bad) > > xfs_db> crc -r > > crc = 0x796c814f (correct) > > On reflection, do you think these should be more verbose, something like: > > xfs_db> sb 0 > xfs_db> crc -v > Validating crc: > crc = 0x796c814f (correct) > xfs_db> crc -i > Invalidating CRC: > Metadata CRC error detected at block 0x0/0x200 > crc = 0x796c8150 (bad) > xfs_db> crc -r > Rewriting CRC: > crc = 0x796c814f (correct) Seems like a good idea to me. ;) Cheers, Dave. -- Dave Chinner david@fromorbit.com From sandeen@sandeen.net Tue Sep 16 21:15:27 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 42C1B7F47 for ; Tue, 16 Sep 2014 21:15:27 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1EDCF8F8052 for ; Tue, 16 Sep 2014 19:15:26 -0700 (PDT) X-ASG-Debug-ID: 1410920121-04cb6c54fdb5c5b0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id HRz7WTNbarwp01N9 for ; Tue, 16 Sep 2014 19:15:21 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 42C1C61F892C for ; Tue, 16 Sep 2014 21:15:21 -0500 (CDT) Message-ID: <5418EEB8.9010207@sandeen.net> Date: Tue, 16 Sep 2014 21:15:20 -0500 From: Eric Sandeen MIME-Version: 1.0 To: xfs-oss Subject: [PATCH 2/2 V3] xfs_db: add crc manipulation commands References: <540B4399.4020804@sandeen.net> <5418574A.8040102@sandeen.net> X-ASG-Orig-Subj: [PATCH 2/2 V3] xfs_db: add crc manipulation commands In-Reply-To: <5418574A.8040102@sandeen.net> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1410920121 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9566 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This adds a new "crc" command to xfs_db for CRC-enabled filesystems. If a structure has a CRC field, we can validate it, invalidate/corrupt it, or revalidate/rewrite it: xfs_db> sb 0 xfs_db> crc -v crc = 0x796c814f (correct) xfs_db> crc -i Metadata CRC error detected at block 0x0/0x200 crc = 0x796c8150 (bad) xfs_db> crc -r crc = 0x796c814f (correct) (-i and -r require "expert" write-capable mode) This requires temporarily replacing the write verifier with a dummy which won't recalculate the CRC on the way to disk. It also required me to write a new flist function, which is totally foreign to me, so hopefully done right - but it seems to work here. Signed-off-by: Eric Sandeen --- Note, "-i" and "-r" are shown in help even if not in expert mode, not sure if I should fix that? V2: Fix whitespace damage, clarify write_cur() changes a bit w/ code & comments. V3: Be a bit more verbose with command output I'm not totally sure on this, most xfs_db commands aren't very chatty. Pick the one you like ;) diff --git a/db/Makefile b/db/Makefile index bae6154..f0175cc 100644 --- a/db/Makefile +++ b/db/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_db HFILES = addr.h agf.h agfl.h agi.h attr.h attrshort.h bit.h block.h bmap.h \ - btblock.h bmroot.h check.h command.h convert.h debug.h \ + btblock.h bmroot.h check.h command.h convert.h crc.h debug.h \ dir2.h dir2sf.h dquot.h echo.h faddr.h field.h \ flist.h fprint.h frag.h freesp.h hash.h help.h init.h inode.h input.h \ io.h malloc.h metadump.h output.h print.h quit.h sb.h sig.h strvec.h \ diff --git a/db/command.c b/db/command.c index b7e3165..d44e0a5 100644 --- a/db/command.c +++ b/db/command.c @@ -48,6 +48,7 @@ #include "write.h" #include "malloc.h" #include "dquot.h" +#include "crc.h" cmdinfo_t *cmdtab; int ncmds; @@ -123,6 +124,7 @@ init_commands(void) bmap_init(); check_init(); convert_init(); + crc_init(); debug_init(); echo_init(); frag_init(); diff --git a/db/crc.c b/db/crc.c new file mode 100644 index 0000000..ad46c3f --- /dev/null +++ b/db/crc.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2014 Red Hat, Inc. + * All Rights Reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "addr.h" +#include "command.h" +#include "type.h" +#include "faddr.h" +#include "fprint.h" +#include "field.h" +#include "flist.h" +#include "io.h" +#include "init.h" +#include "output.h" +#include "bit.h" +#include "print.h" + +static int crc_f(int argc, char **argv); +static void crc_help(void); + +static const cmdinfo_t crc_cmd = + { "crc", NULL, crc_f, 0, 1, 0, "[-i|-r|-v]", + N_("manipulate crc values for V5 filesystem structures"), crc_help }; + +void +crc_init(void) +{ + if (xfs_sb_version_hascrc(&mp->m_sb)) + add_command(&crc_cmd); +} + +static void +crc_help(void) +{ + dbprintf(_( +"\n" +" 'crc' validates, invalidates, or recalculates the crc value for\n" +" the current on-disk metadata structures in Version 5 filesystems.\n" +"\n" +" Usage: \"crc [-i|-r|-v]\"\n" +"\n" +)); + +} + +void +xfs_dummy_verify( + struct xfs_buf *bp) +{ + return; +} + +static int +crc_f( + int argc, + char **argv) +{ + const struct xfs_buf_ops *stashed_ops = NULL; + extern char *progname; + const field_t *fields; + const ftattr_t *fa; + flist_t *fl; + int invalidate = 0; + int recalculate = 0; + int validate = 0; + int c; + + if (cur_typ == NULL) { + dbprintf(_("no current type\n")); + return 0; + } + + if (cur_typ->fields == NULL) { + dbprintf(_("current type (%s) is not a structure\n"), + cur_typ->name); + return 0; + } + + if (argc) while ((c = getopt(argc, argv, "irv")) != EOF) { + switch (c) { + case 'i': + invalidate = 1; + break; + case 'r': + recalculate = 1; + break; + case 'v': + validate = 1; + break; + default: + dbprintf(_("bad option for crc command\n")); + return 0; + } + } else + validate = 1; + + if (invalidate + recalculate + validate > 1) { + dbprintf(_("crc command accepts only one option\n")); + return 0; + } + + if ((invalidate || recalculate) && + ((x.isreadonly & LIBXFS_ISREADONLY) || !expert_mode)) { + dbprintf(_("%s not in expert mode, writing disabled\n"), + progname); + return 0; + } + + fields = cur_typ->fields; + + /* if we're a root field type, go down 1 layer to get field list */ + if (fields->name[0] == '\0') { + fa = &ftattrtab[fields->ftyp]; + ASSERT(fa->ftyp == fields->ftyp); + fields = fa->subfld; + } + + /* Search for a CRC field */ + fl = flist_find_ftyp(fields, FLDT_CRC); + if (!fl) { + dbprintf(_("No CRC field found for type %s\n"), cur_typ->name); + return 0; + } + + /* run down the field list and set offsets into the data */ + if (!flist_parse(fields, fl, iocur_top->data, 0)) { + flist_free(fl); + dbprintf(_("parsing error\n")); + return 0; + } + + if (invalidate) { + struct xfs_buf_ops nowrite_ops; + flist_t *sfl; + int bit_length; + int parentoffset; + int crc; + + sfl = fl; + parentoffset = 0; + while (sfl->child) { + parentoffset = sfl->offset; + sfl = sfl->child; + } + ASSERT(sfl->fld->ftyp == FLDT_CRC); + + bit_length = fsize(sfl->fld, iocur_top->data, parentoffset, 0); + bit_length *= fcount(sfl->fld, iocur_top->data, parentoffset); + crc = getbitval(iocur_top->data, sfl->offset, bit_length, BVUNSIGNED); + /* Off by one.. */ + crc = cpu_to_be32(crc + 1); + setbitval(iocur_top->data, sfl->offset, bit_length, &crc); + + /* Temporarily remove write verifier to write a bad CRC */ + stashed_ops = iocur_top->bp->b_ops; + nowrite_ops.verify_read = stashed_ops->verify_read; + nowrite_ops.verify_write = xfs_dummy_verify; + iocur_top->bp->b_ops = &nowrite_ops; + } + + if (invalidate || recalculate) { + if (invalidate) + dbprintf(_("Invalidating CRC:\n")); + else + dbprintf(_("Recalculating CRC:\n")); + + write_cur(); + if (stashed_ops) + iocur_top->bp->b_ops = stashed_ops; + /* re-verify to get proper b_error state */ + iocur_top->bp->b_ops->verify_read(iocur_top->bp); + } else + dbprintf(_("Verifying CRC:\n")); + + /* And show us what we've got! */ + flist_print(fl); + print_flist(fl); + flist_free(fl); + return 0; +} diff --git a/db/crc.h b/db/crc.h new file mode 100644 index 0000000..80ecec3 --- /dev/null +++ b/db/crc.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014 Red Hat, Inc. + * All Rights Reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +struct field; + +extern void crc_init(void); +extern void crc_struct(const field_t *fields, int argc, char **argv); +extern void xfs_dummy_verify(struct xfs_buf *bp); diff --git a/db/flist.c b/db/flist.c index 33f7da7..fa19f70 100644 --- a/db/flist.c +++ b/db/flist.c @@ -411,6 +411,40 @@ flist_split( return v; } +/* + * Given a set of fields, scan for a field of the given type. + * Return an flist leading to the first found field + * of that type. + * Return NULL if no field of the given type is found. + */ +flist_t * +flist_find_ftyp( + const field_t *fields, + fldt_t type) +{ + flist_t *fl; + const field_t *f; + const ftattr_t *fa; + + for (f = fields; f->name; f++) { + fl = flist_make(f->name); + fl->fld = f; + if (f->ftyp == type) + return fl; + fa = &ftattrtab[f->ftyp]; + if (fa->subfld) { + flist_t *nfl; + nfl = flist_find_ftyp(fa->subfld, type); + if (nfl) { + fl->child = nfl; + return fl; + } + } + flist_free(fl); + } + return NULL; +} + static void ftok_free( ftok_t *ft) diff --git a/db/flist.h b/db/flist.h index 5c9fba0..3f4b312 100644 --- a/db/flist.h +++ b/db/flist.h @@ -37,3 +37,4 @@ extern int flist_parse(const struct field *fields, flist_t *fl, void *obj, int startoff); extern void flist_print(flist_t *fl); extern flist_t *flist_scan(char *name); +extern flist_t *flist_find_ftyp(const field_t *fields, fldt_t type); diff --git a/db/io.c b/db/io.c index f7393c5..eb3daa1 100644 --- a/db/io.c +++ b/db/io.c @@ -27,6 +27,7 @@ #include "output.h" #include "init.h" #include "malloc.h" +#include "crc.h" static int pop_f(int argc, char **argv); static void pop_help(void); @@ -459,22 +460,37 @@ write_cur_bbs(void) void write_cur(void) { + int skip_crc = (iocur_top->bp->b_ops->verify_write == xfs_dummy_verify); + if (iocur_sp < 0) { dbprintf(_("nothing to write\n")); return; } - if (iocur_top->ino_buf) { + if (iocur_top->ino_buf && !skip_crc) { libxfs_dinode_calc_crc(mp, iocur_top->data); iocur_top->ino_crc_ok = 1; } - if (iocur_top->dquot_buf) + + if (iocur_top->dquot_buf && !skip_crc) xfs_update_cksum(iocur_top->data, sizeof(struct xfs_dqblk), XFS_DQUOT_CRC_OFF); if (iocur_top->bbmap) write_cur_bbs(); else write_cur_buf(); + + /* If we didn't write the crc automatically, re-check validity */ + if (iocur_top->ino_buf && skip_crc) { + xfs_dinode_t *dip; + xfs_ino_t ino; + + dip = iocur_top->data; + ino = iocur_top->ino; + iocur_top->ino_crc_ok = xfs_verify_cksum((char *)dip, + mp->m_sb.sb_inodesize, + XFS_DINODE_CRC_OFF); + } } void diff --git a/db/write.h b/db/write.h index 31e2665..664ddcc 100644 --- a/db/write.h +++ b/db/write.h @@ -20,5 +20,5 @@ struct field; extern void write_init(void); extern void write_block(const field_t *fields, int argc, char **argv); -extern void write_string(const field_t *fields, int argc, char **argv); extern void write_struct(const field_t *fields, int argc, char **argv); +extern void write_string(const field_t *fields, int argc, char **argv); diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8 index 4d8d4ff..0764832 100644 --- a/man/man8/xfs_db.8 +++ b/man/man8/xfs_db.8 @@ -87,16 +87,14 @@ or .I filename read-only. This option is required if the filesystem is mounted. It is only necessary to omit this flag if a command that changes data -.RB ( write ", " blocktrash ) +.RB ( write ", " blocktrash ", " crc ) is to be used. .TP .B \-x Specifies expert mode. This enables the -.B write -and -.B blocktrash -commands. +.RB ( write ", " blocktrash ", " crc +invalidate/revalidate) commands. .TP .B \-V Prints the version number and exits. @@ -409,6 +407,25 @@ conversions such as .I agb .BR fsblock . .TP +.B crc [\-i|\-r|\-v] +Invalidates, revalidates, or validates the CRC (checksum) +field of the current structure, if it has one. +This command is available only on CRC-enabled filesystems. +With no argument, validation is performed. +Each command will display the resulting CRC value and state. +.RS 1.0i +.TP 0.4i +.B \-i +Invalidate the structure's CRC value (incrementing it by one), +and write it to disk. +.TP +.B \-r +Recalculate the current structure's correct CRC value, and write it to disk. +.TP +.B \-v +Validate and display the current value and state of the structure's CRC. +.RE +.TP .BI "daddr [" d ] Set current address to the daddr (512 byte block) given by .IR d . From malchlen@russiamall.com Tue Sep 16 22:54:50 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.2 required=5.0 tests=HTML_MESSAGE,MIME_HTML_ONLY autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 82DB87F47 for ; Tue, 16 Sep 2014 22:54:50 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6F74F8F8037 for ; Tue, 16 Sep 2014 20:54:47 -0700 (PDT) X-ASG-Debug-ID: 1410926084-04cbb05486e32040001-NocioJ Received: from firecat.asmap.org.ua (firecat.asmap.org.ua [195.47.248.22]) by cuda.sgi.com with ESMTP id ZmZSDhOWwS0HSyPq for ; Tue, 16 Sep 2014 20:54:45 -0700 (PDT) X-Barracuda-Envelope-From: malchlen@russiamall.com X-Barracuda-Apparent-Source-IP: 195.47.248.22 Received: from [194.126.181.18] (helo=Unknown) by firecat.asmap.org.ua with esmtpa (Exim 4.82) (envelope-from ) id 1XU6KA-0004jY-Ul; Wed, 17 Sep 2014 06:54:43 +0300 Message-ID: <2E2B9DCEC51136C5191C55DF5B436418@bequyng> From: To: , , , Subject: =?utf-8?Q?=D0=9A=D0=B0=D0=BA_=D0=BE=D0=B1=D0=B5=D1=81=D0?= =?utf-8?Q?=BF=D0=B5=D1=87=D0=B8=D1=82=D1=8C_=D0=B1=D0=B5?= =?utf-8?Q?=D0=B7=D0=BE=D0=BF=D0=B0=D1=81=D0=BD=D0=BE=D1?= =?utf-8?Q?=81=D1=82=D1=8C=3F?= Date: Wed, 17 Sep 2014 05:54:24 +0200 X-ASG-Orig-Subj: =?utf-8?Q?=D0=9A=D0=B0=D0=BA_=D0=BE=D0=B1=D0=B5=D1=81=D0?= =?utf-8?Q?=BF=D0=B5=D1=87=D0=B8=D1=82=D1=8C_=D0=B1=D0=B5?= =?utf-8?Q?=D0=B7=D0=BE=D0=BF=D0=B0=D1=81=D0=BD=D0=BE=D1?= =?utf-8?Q?=81=D1=82=D1=8C=3F?= MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_020F_01CFD23B.D572D5D0" X-Priority: 3 X-Barracuda-Connect: firecat.asmap.org.ua[195.47.248.22] X-Barracuda-Start-Time: 1410926085 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_TG035a, HTML_MESSAGE, MIME_HTML_ONLY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9568 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 BSF_SC0_TG035a Message contains invalid style definition This is a multi-part message in MIME format. ------=_NextPart_000_020F_01CFD23B.D572D5D0 Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: base64 PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwv L0VOIj4NCjxIVE1MIHhtbG5zOm8gPSAidXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6 b2ZmaWNlIj48SEVBRD4NCjxNRVRBIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD11dGYtOCIg aHR0cC1lcXVpdj1Db250ZW50LVR5cGU+DQo8TUVUQSBuYW1lPUdFTkVSQVRPUiBjb250ZW50PSJN U0hUTUwgMTAuMDAuOTIwMC4xNjg5NyI+DQo8U1RZTEU+PC9TVFlMRT4NCjwvSEVBRD4NCjxCT0RZ IGJnQ29sb3I9I2ZmZmZmZj4NCjxESVY+DQo8RElWPg0KPFAgc3R5bGU9IkxJTkUtSEVJR0hUOiBu b3JtYWw7IE1BUkdJTjogMGNtIDBjbSAwcHQiIGNsYXNzPU1zb05vcm1hbD48Qj48U1BBTiANCnN0 eWxlPSJGT05ULUZBTUlMWTogJ1RpbWVzIE5ldyBSb21hbicsJ3NlcmlmJyI+MjktMzAg0YHQtdC9 0YLRj9Cx0YDRjywgDQrQodCw0L3QutGCLdCf0LXRgtC10YDQsdGD0YDQszxvOnA+PC9vOnA+PC9T UEFOPjwvQj48L1A+DQo8UCBzdHlsZT0iTElORS1IRUlHSFQ6IG5vcm1hbDsgTUFSR0lOOiAwY20g MGNtIDBwdCIgY2xhc3M9TXNvTm9ybWFsPjxCPjxTUEFOIA0Kc3R5bGU9IkZPTlQtRkFNSUxZOiAn VGltZXMgTmV3IFJvbWFuJywnc2VyaWYnIj7QrdCa0J7QndCe0JzQmNCn0JXQodCa0JDQryDQkdCV 0JfQntCf0JDQodCd0J7QodCi0KwgDQrQn9Cg0JXQlNCf0KDQmNCv0KLQmNCvLiDQo9C/0YDQsNCy 0LvQtdC90LjQtSDRjdC60L7QvdC+0LzQuNGH0LXRgdC60LjQvNC4INGA0LjRgdC60LDQvNC4LiDQ mtC+0L3RgtGA0L7Qu9GMINC60L7QvdGC0YDQsNCz0LXQvdGC0L7Qsi4g0JHQvtGA0YzQsdCwINGB IA0K0LrQvtGA0L/QvtGA0LDRgtC40LLQvdGL0Lwg0LzQvtGI0LXQvdC90LjRh9C10YHRgtCy0L7Q vC4g0JDQu9Cz0L7RgNC40YLQvCDQtNC10LnRgdGC0LLQuNC5INC/0YDQuCDQstC90LXQt9Cw0L/Q vdC+0LkgDQrQv9GA0L7QstC10YDQutC1PC9TUEFOPjwvQj48L1A+PC9ESVY+DQo8RElWIHN0eWxl PSJMSU5FLUhFSUdIVDogbm9ybWFsOyBNQVJHSU46IDBjbSAwY20gMHB0IiBjbGFzcz1Nc29Ob3Jt YWw+0L/QvtC00YDQvtCx0L3QtdC1IA0K0LIg0L/RgNC40LrRgNC10L/Qu9C10L3QvdC+0Lwg0YTQ sNC50LvQtS4uLiZuYnNwOyANCjxQPjwvUD48L0RJVj48L0RJVj48L0JPRFk+PC9IVE1MPg0K ------=_NextPart_000_020F_01CFD23B.D572D5D0 Content-Type: application/octet-stream; name="=?utf-8?Q?=D0=B2=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0?= =?utf-8?Q?=B5=2Edocx?=" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="=?utf-8?Q?=D0=B2=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0?= =?utf-8?Q?=B5=2Edocx?=" UEsDBBQABgAIAAAAIQAB2BvYlQEAAPQFAAATAAgCW0NvbnRlbnRfVHlwZXNdLnhtbCCiBAIooAAC AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC0 VDtPwzAQ3pH4D5FXlLgwIISaMvAYAYkiZuNcWkP8kM+U9t9zTtqoVGlTKCyR4vP3Ots3vJrrKpmB R2VNzk6zAUvASFsoM8nZ8/guvWAJBmEKUVkDOVsAsqvR8dFwvHCACaEN5mwagrvkHOUUtMDMOjBU Ka3XItCvn3An5LuYAD8bDM65tCaACWmIHGw0vIFSfFQhuZ3TcuPEmQlLrpt9USpnSkd8XOediDcH 3ZC60I3xUOGGjHCuUlIE6gefmWIjS7rMkRGy3oNT5fCEwm5xFSvfc6wLLHEPdABeFZA8Ch/uhaa0 /NP6ghdWfmjqVLabpsOnLUslocVHNuetBEQ6WV1lbUULZVb+t/rAsKgA/95Fw7un/IsK09uyBElX qr8fGtMYOmsk1rD9ahACNWkfke8XPe1rOi6Zey18wuvTv7lYI+81UtILHIvXCvbo+A+b0VL3mgg0 VYDX39ODfdQ0uyTpZTx665CmlP9F7NWAiOiUnpwDHxS0I6LribWKNBoOzgdxhhZQdGjzemaPvgAA AP//AwBQSwMEFAAGAAgAAAAhAB6RGrfzAAAATgIAAAsACAJfcmVscy8ucmVscyCiBAIooAACAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMkttK A0EMhu8F32HIfTfbCiLS2d5IoXci6wOEmewBdw7MpNq+vaMgulDbXub058tP1puDm9Q7pzwGr2FZ 1aDYm2BH32t4bbeLB1BZyFuagmcNR86waW5v1i88kZShPIwxq6Lis4ZBJD4iZjOwo1yFyL5UupAc SQlTj5HMG/WMq7q+x/RXA5qZptpZDWln70C1x1g2X9YOXTcafgpm79jLiRXIB2Fv2S5iKmxJxnKN ain1LBpsMM8lnZFirAo24Gmi1fVE/1+LjoUsCaEJic/zfHWcA1peD3TZonnHrzsfIVksFn17+0OD sy9oPgEAAP//AwBQSwMEFAAGAAgAAAAhAGED4FZBAQAAwgQAABwACAF3b3JkL19yZWxzL2RvY3Vt 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 Qg8AECcAAEBCDwAQJwAAQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzADIwMTQ6MDU6MjMgMTQ6 NTU6MjMAAAAJAACQBwAEAAAAMAAyAASQAgAUAAAAlgEAAAGRBwAEAAAAAQIDAACgBwAEAAAAMAAx AAGgAwABAAAAAQAAAAKgBAABAAAAPgEAAAOgBAABAAAAdQAAAACjBwABAAAAAgAAAAOkAwABAAAA AAAAAAAAAAAyADAAMQA0ADoAMAA1ADoAMgAzAAAABgADAQMAAQAAAAYAAAAaAQUAAQAAAPoBAAAb AQUAAQAAAAICAAAoAQMAAQAAAAIAAAABAgQAAQAAAAoCAAACAgQAAQAAAPYGAAAAAAAASAAAAAEA AABIAAAAAQAAAP/Y/+0ADEFkb2JlX0NNAAH/7gAOQWRvYmUAZIAAAAAB/9sAhAAMCAgICQgMCQkM EQsKCxEVDwwMDxUYExMVExMYEQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAQ0L Cw0ODRAODhAUDg4OFBQODg4OFBEMDAwMDBERDAwMDAwMEQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM DAwMDAz/wAARCAA7AKADASIAAhEBAxEB/90ABAAK/8QBPwAAAQUBAQEBAQEAAAAAAAAAAwABAgQF BgcICQoLAQABBQEBAQEBAQAAAAAAAAABAAIDBAUGBwgJCgsQAAEEAQMCBAIFBwYIBQMMMwEAAhED BCESMQVBUWETInGBMgYUkaGxQiMkFVLBYjM0coLRQwclklPw4fFjczUWorKDJkSTVGRFwqN0NhfS VeJl8rOEw9N14/NGJ5SkhbSVxNTk9KW1xdXl9VZmdoaWprbG1ub2N0dXZ3eHl6e3x9fn9xEAAgIB AgQEAwQFBgcHBgU1AQACEQMhMRIEQVFhcSITBTKBkRShsUIjwVLR8DMkYuFygpJDUxVjczTxJQYW orKDByY1wtJEk1SjF2RFVTZ0ZeLys4TD03Xj80aUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9ic3 R1dnd4eXp7fH/9oADAMBAAIRAxEAPwD1VJJJJSkkkklKSSSSUpJJMZjTUpKWc9rSATqeB35Df+/J yQBJ0A7qFdTWFzvpPf8AScef6o/dY39xTIBEESDyElLpJKFttdTDZYdrW8n46Af2klM0kOuxzy4O aWFpjxBkbkRJSkkkklKSSSSUpJJJJT//0PVVVf1HFbY6phdfazR1dLS8g/uPcz2VO/417FaVCnFz cFgqxHMvxWCK6LfY9gH5leRW13qVtb9D1qvW/wBLlpBSUX5rz7MXYP8AhrGtPP8AwAyU2zqrna3U Vs8G1ue7/Pdaxv8A4Eo/tRlcjLouxSPznM3s/revj+tWxv8Ax3pKxj5WLktL8a5l7QYLq3B4B+LC UfopEcXJdBOZa2OQxtQB/rb6rP8AopOwGPBD7rzOhi1zP/PRr2/2VaSSsqarenY7Zh9+uuuRcfLv akMHHI0fcQCR/P3fB3+FVpVOlBw6bil53WOqY+x2ur3DfY73e73WOcgpQ6bjgHbZeCe/2i4/dvtc l9hsbPp5l7J8Sx//AJ+rsRMjMox9HkusILmVMBdY6OfTqb73LH6R12978r9rtdhOYWGqm017vePV 2UVUze/0q31Ms9Tf+m9XZ/o63ASo19VOmaOpsH6PKY8+FtU/c6mynb/m2Kndf1H7U318Zt1OIA8+ hZBfa+WVj0r21M31N/wLsn/D0Wf6Nal91VFTrbnbWNiTyZJ2ta1o9z3vcdjGN+m9UumsN9mRk3MF b/XcW1clsMroY+3lvrvpZ+Z/NV2+l/pEgepA/l/dUzxc3HD3V27qMm1291dzSyTA9lb/AOZu9Otr WfoLLPoK8mc1rmlrgHNPIOoVZ2PbSN2GQI/wDyfTPkz6TqP5Pp/ov+BQU2klCqz1K2v2uYXCSx30 gf3XRubuapoKUkkkkpSSSSSn/9H1VJJJJSlXvwMLJO6+hj39nlo3DSPbZ9NqsJJKah6cGmaMi+g+ VnqD5MyhkMb/AGWphV1Rk7ciq0dm2VlrvnbVYG/+AK4kjZU1fXz2D9Jiizn+ZsBOn8nIGM33f8Yq rjjssc99mXjMe4l1UO9MH853qtZZ6LXfyL661qJJA0pqYdvTSXDDsre4n9IWvDnk/S/Sul1m73fn omRh4+SxzbG+5wA9RujxtPqV7bB7v0dg9Rinbj49wi6plggj3tDtDyPcg/s7HAio2UayPTe5oB/4 vd6X9j00tFL04LWWNuutfk3Mn07LdvtmfoMpZTU1212z1PT9XYo24Ljkface51Fhne36VbzDWb7a vbusaxmzdvU/Qymya8kmeBaxrgIHb0vQf/nPSnPbptqs0+ludXJ/qbb9v+ekN1MBX1XeJyKNmsxQ 8H+TH605P9lynauzLGnX+bZWBH/XK7nf9JT9fIBIOM8xwWOYQf8APfWnGU0kh1djC3mWE/ca97Xf 2Utf2qXoobTvIc57rHb7HuiS4NbVMNDWN9lbPoNRUAZuLw6wMMboeCwgfym2bXNU2ZGPYS2u1jyI kNcCdeOEqO6kiSSSClJJJJKf/9L1VJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkJ+Nj2O3 WVMe7xc0E/iipJKa7sHFJBa01wIHpOdX/wCeXMS+z3sk05DvJtoD2j7vTt/zrlYSTvVWv4/sUios sew+o3ZY07XASWyO7HODdzUVJJNU/wD/2f/tEOZQaG90b3Nob3AgMy4wADhCSU0EBAAAAAAAFxwB WgADGyVHHAFaAAMbJUccAgAAAoAAADhCSU0EJQAAAAAAENk4OdNQRRY/rdNBb7PVRrk4QklNBDoA AAAAAK8AAAAQAAAAAQAAAAAAC3ByaW50T3V0cHV0AAAABAAAAABQc3RTYm9vbAEAAAAASW50ZWVu dW0AAAAASW50ZQAAAABJbWcgAAAAD3ByaW50U2l4dGVlbkJpdGJvb2wAAAAAC3ByaW50ZXJOYW1l VEVYVAAAAB0AQwBhAG4AbwBuACAATQBGADQAMAAxADAAIABTAGUAcgBpAGUAcwAgAFUARgBSAEkA SQAgAEwAVAAAADhCSU0EOwAAAAABsgAAABAAAAABAAAAAAAScHJpbnRPdXRwdXRPcHRpb25zAAAA EgAAAABDcHRuYm9vbAAAAAAAQ2xicmJvb2wAAAAAAFJnc01ib29sAAAAAABDcm5DYm9vbAAAAAAA Q250Q2Jvb2wAAAAAAExibHNib29sAAAAAABOZ3R2Ym9vbAAAAAAARW1sRGJvb2wAAAAAAEludHJi b29sAAAAAABCY2tnT2JqYwAAAAEAAAAAAABSR0JDAAAAAwAAAABSZCAgZG91YkBv4AAAAAAAAAAA AEdybiBkb3ViQG/gAAAAAAAAAAAAQmwgIGRvdWJAb+AAAAAAAAAAAABCcmRUVW50RiNSbHQAAAAA AAAAAAAAAABCbGQgVW50RiNSbHQAAAAAAAAAAAAAAABSc2x0VW50RiNQeGxAWQAAAAAAAAAAAAp2 ZWN0b3JEYXRhYm9vbAEAAAAAUGdQc2VudW0AAAAAUGdQcwAAAABQZ1BDAAAAAExlZnRVbnRGI1Js dAAAAAAAAAAAAAAAAFRvcCBVbnRGI1JsdAAAAAAAAAAAAAAAAFNjbCBVbnRGI1ByY0BZAAAAAAAA OEJJTQPtAAAAAAAQAGQAAAABAAIAZAAAAAEAAjhCSU0EJgAAAAAADgAAAAAAAAAAAAA/gAAAOEJJ TQPyAAAAAAAKAAD///////8AADhCSU0EDQAAAAAABAAAAB44QklNBBkAAAAAAAQAAAAeOEJJTQPz AAAAAAAJAAAAAAAAAAABADhCSU0nEAAAAAAACgABAAAAAAAAAAI4QklNA/UAAAAAAEgAL2ZmAAEA bGZmAAYAAAAAAAEAL2ZmAAEAoZmaAAYAAAAAAAEAMgAAAAEAWgAAAAYAAAAAAAEANQAAAAEALQAA AAYAAAAAAAE4QklNA/gAAAAAAHAAAP////////////////////////////8D6AAAAAD///////// ////////////////////A+gAAAAA/////////////////////////////wPoAAAAAP////////// //////////////////8D6AAAOEJJTQQAAAAAAAACAAA4QklNBAIAAAAAAAIAADhCSU0EMAAAAAAA AQEAOEJJTQQtAAAAAAAGAAEAAAACOEJJTQQIAAAAAAAQAAAAAQAAAkAAAAJAAAAAADhCSU0EHgAA AAAABAAAAAA4QklNBBoAAAAAA0MAAAAGAAAAAAAAAAAAAAB1AAABPgAAAAcEQQQwBDIEOAQ9BD4E MgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAABPgAAAHUAAAAAAAAAAAAAAAAAAAAA AQAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAQAAAAAAAG51bGwAAAACAAAABmJvdW5kc09iamMAAAAB AAAAAAAAUmN0MQAAAAQAAAAAVG9wIGxvbmcAAAAAAAAAAExlZnRsb25nAAAAAAAAAABCdG9tbG9u ZwAAAHUAAAAAUmdodGxvbmcAAAE+AAAABnNsaWNlc1ZsTHMAAAABT2JqYwAAAAEAAAAAAAVzbGlj ZQAAABIAAAAHc2xpY2VJRGxvbmcAAAAAAAAAB2dyb3VwSURsb25nAAAAAAAAAAZvcmlnaW5lbnVt AAAADEVTbGljZU9yaWdpbgAAAA1hdXRvR2VuZXJhdGVkAAAAAFR5cGVlbnVtAAAACkVTbGljZVR5 cGUAAAAASW1nIAAAAAZib3VuZHNPYmpjAAAAAQAAAAAAAFJjdDEAAAAEAAAAAFRvcCBsb25nAAAA AAAAAABMZWZ0bG9uZwAAAAAAAAAAQnRvbWxvbmcAAAB1AAAAAFJnaHRsb25nAAABPgAAAAN1cmxU RVhUAAAAAQAAAAAAAG51bGxURVhUAAAAAQAAAAAAAE1zZ2VURVhUAAAAAQAAAAAABmFsdFRhZ1RF WFQAAAABAAAAAAAOY2VsbFRleHRJc0hUTUxib29sAQAAAAhjZWxsVGV4dFRFWFQAAAABAAAAAAAJ aG9yekFsaWduZW51bQAAAA9FU2xpY2VIb3J6QWxpZ24AAAAHZGVmYXVsdAAAAAl2ZXJ0QWxpZ25l bnVtAAAAD0VTbGljZVZlcnRBbGlnbgAAAAdkZWZhdWx0AAAAC2JnQ29sb3JUeXBlZW51bQAAABFF U2xpY2VCR0NvbG9yVHlwZQAAAABOb25lAAAACXRvcE91dHNldGxvbmcAAAAAAAAACmxlZnRPdXRz ZXRsb25nAAAAAAAAAAxib3R0b21PdXRzZXRsb25nAAAAAAAAAAtyaWdodE91dHNldGxvbmcAAAAA ADhCSU0EKAAAAAAADAAAAAI/8AAAAAAAADhCSU0EFAAAAAAABAAAAAI4QklNBAwAAAAABxIAAAAB AAAAoAAAADsAAAHgAABuoAAABvYAGAAB/9j/7QAMQWRvYmVfQ00AAf/uAA5BZG9iZQBkgAAAAAH/ 2wCEAAwICAgJCAwJCQwRCwoLERUPDAwPFRgTExUTExgRDAwMDAwMEQwMDAwMDAwMDAwMDAwMDAwM DAwMDAwMDAwMDAwBDQsLDQ4NEA4OEBQODg4UFA4ODg4UEQwMDAwMEREMDAwMDAwRDAwMDAwMDAwM DAwMDAwMDAwMDAwMDAwMDAwMDP/AABEIADsAoAMBIgACEQEDEQH/3QAEAAr/xAE/AAABBQEBAQEB AQAAAAAAAAADAAECBAUGBwgJCgsBAAEFAQEBAQEBAAAAAAAAAAEAAgMEBQYHCAkKCxAAAQQBAwIE AgUHBggFAwwzAQACEQMEIRIxBUFRYRMicYEyBhSRobFCIyQVUsFiMzRygtFDByWSU/Dh8WNzNRai soMmRJNUZEXCo3Q2F9JV4mXys4TD03Xj80YnlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vY3R1dn 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 ADhCSU0EBgAAAAAABwABAQEAAQEA/+ESbGh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8APD94 cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1w bWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4w LWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4 bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8 cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5j b20veGFwLzEuMC8iIHhtbG5zOmNycz0iaHR0cDovL25zLmFkb2JlLmNvbS9jYW1lcmEtcmF3LXNl dHRpbmdzLzEuMC8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3No b3AvMS4wLyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxu czp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0 dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1sbnM6c3RS ZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpD cmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXA6TW9kaWZ5RGF0ZT0i MjAxNC0wNS0yM1QxNDo1NToyMyswNDowMCIgeG1wOkNyZWF0ZURhdGU9IjAwMDIiIHhtcDpNZXRh ZGF0YURhdGU9IjIwMTQtMDUtMjNUMTQ6NTU6MjMrMDQ6MDAiIGNyczpBbHJlYWR5QXBwbGllZD0i VHJ1ZSIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0Ig SUVDNjE5NjYtMi4xIiBkYzpmb3JtYXQ9ImltYWdlL2pwZWciIHhtcE1NOkluc3RhbmNlSUQ9Inht cC5paWQ6MUJFOUI4QTM2OEUyRTMxMTk0NkVCMTU0M0FGNDJCNkMiIHhtcE1NOkRvY3VtZW50SUQ9 InhtcC5kaWQ6MThFOUI4QTM2OEUyRTMxMTk0NkVCMTU0M0FGNDJCNkMiIHhtcE1NOk9yaWdpbmFs RG9jdW1lbnRJRD0ieG1wLmRpZDoxOEU5QjhBMzY4RTJFMzExOTQ2RUIxNTQzQUY0MkI2QyI+IDx4 bXBNTTpIaXN0b3J5PiA8cmRmOlNlcT4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2 dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjE4RTlCOEEzNjhFMkUzMTE5NDZFQjE1NDNBRjQyQjZDIiBz dEV2dDp3aGVuPSIyMDE0LTA1LTIzVDE0OjU0OjQwKzA0OjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50 PSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPHJkZjps aSBzdEV2dDphY3Rpb249ImNvbnZlcnRlZCIgc3RFdnQ6cGFyYW1ldGVycz0iZnJvbSBpbWFnZS9q cGVnIHRvIGFwcGxpY2F0aW9uL3ZuZC5hZG9iZS5waG90b3Nob3AiLz4gPHJkZjpsaSBzdEV2dDph Y3Rpb249ImRlcml2ZWQiIHN0RXZ0OnBhcmFtZXRlcnM9ImNvbnZlcnRlZCBmcm9tIGltYWdlL2pw ZWcgdG8gYXBwbGljYXRpb24vdm5kLmFkb2JlLnBob3Rvc2hvcCIvPiA8cmRmOmxpIHN0RXZ0OmFj dGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6MTlFOUI4QTM2OEUyRTMxMTk0 NkVCMTU0M0FGNDJCNkMiIHN0RXZ0OndoZW49IjIwMTQtMDUtMjNUMTQ6NTQ6NDArMDQ6MDAiIHN0 RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDUzUgV2luZG93cyIgc3RFdnQ6Y2hh bmdlZD0iLyIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9 InhtcC5paWQ6MUFFOUI4QTM2OEUyRTMxMTk0NkVCMTU0M0FGNDJCNkMiIHN0RXZ0OndoZW49IjIw MTQtMDUtMjNUMTQ6NTU6MjMrMDQ6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rv c2hvcCBDUzUgV2luZG93cyIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlv bj0iY29udmVydGVkIiBzdEV2dDpwYXJhbWV0ZXJzPSJmcm9tIGFwcGxpY2F0aW9uL3ZuZC5hZG9i ZS5waG90b3Nob3AgdG8gaW1hZ2UvanBlZyIvPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0iZGVyaXZl ZCIgc3RFdnQ6cGFyYW1ldGVycz0iY29udmVydGVkIGZyb20gYXBwbGljYXRpb24vdm5kLmFkb2Jl LnBob3Rvc2hvcCB0byBpbWFnZS9qcGVnIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIg c3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDoxQkU5QjhBMzY4RTJFMzExOTQ2RUIxNTQzQUY0MkI2 QyIgc3RFdnQ6d2hlbj0iMjAxNC0wNS0yM1QxNDo1NToyMyswNDowMCIgc3RFdnQ6c29mdHdhcmVB Z2VudD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDwv cmRmOlNlcT4gPC94bXBNTTpIaXN0b3J5PiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFu Y2VJRD0ieG1wLmlpZDoxQUU5QjhBMzY4RTJFMzExOTQ2RUIxNTQzQUY0MkI2QyIgc3RSZWY6ZG9j dW1lbnRJRD0ieG1wLmRpZDoxOEU5QjhBMzY4RTJFMzExOTQ2RUIxNTQzQUY0MkI2QyIgc3RSZWY6 b3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjE4RTlCOEEzNjhFMkUzMTE5NDZFQjE1NDNBRjQy QjZDIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw/eHBhY2tldCBl bmQ9InciPz7/4gxYSUNDX1BST0ZJTEUAAQEAAAxITGlubwIQAABtbnRyUkdCIFhZWiAHzgACAAkA BgAxAABhY3NwTVNGVAAAAABJRUMgc1JHQgAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLUhQICAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFjcHJ0AAABUAAAADNk ZXNjAAABhAAAAGx3dHB0AAAB8AAAABRia3B0AAACBAAAABRyWFlaAAACGAAAABRnWFlaAAACLAAA ABRiWFlaAAACQAAAABRkbW5kAAACVAAAAHBkbWRkAAACxAAAAIh2dWVkAAADTAAAAIZ2aWV3AAAD 1AAAACRsdW1pAAAD+AAAABRtZWFzAAAEDAAAACR0ZWNoAAAEMAAAAAxyVFJDAAAEPAAACAxnVFJD AAAEPAAACAxiVFJDAAAEPAAACAx0ZXh0AAAAAENvcHlyaWdodCAoYykgMTk5OCBIZXdsZXR0LVBh Y2thcmQgQ29tcGFueQAAZGVzYwAAAAAAAAASc1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAABJz UkdCIElFQzYxOTY2LTIuMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAWFlaIAAAAAAAAPNRAAEAAAABFsxYWVogAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAA AABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z2Rlc2MA AAAAAAAAFklFQyBodHRwOi8vd3d3LmllYy5jaAAAAAAAAAAAAAAAFklFQyBodHRwOi8vd3d3Lmll Yy5jaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkZXNjAAAA AAAAAC5JRUMgNjE5NjYtMi4xIERlZmF1bHQgUkdCIGNvbG91ciBzcGFjZSAtIHNSR0IAAAAAAAAA AAAAAC5JRUMgNjE5NjYtMi4xIERlZmF1bHQgUkdCIGNvbG91ciBzcGFjZSAtIHNSR0IAAAAAAAAA AAAAAAAAAAAAAAAAAAAAZGVzYwAAAAAAAAAsUmVmZXJlbmNlIFZpZXdpbmcgQ29uZGl0aW9uIGlu IElFQzYxOTY2LTIuMQAAAAAAAAAAAAAALFJlZmVyZW5jZSBWaWV3aW5nIENvbmRpdGlvbiBpbiBJ RUM2MTk2Ni0yLjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZpZXcAAAAAABOk/gAUXy4AEM8U AAPtzAAEEwsAA1yeAAAAAVhZWiAAAAAAAEwJVgBQAAAAVx/nbWVhcwAAAAAAAAABAAAAAAAAAAAA AAAAAAAAAAAAAo8AAAACc2lnIAAAAABDUlQgY3VydgAAAAAAAAQAAAAABQAKAA8AFAAZAB4AIwAo AC0AMgA3ADsAQABFAEoATwBUAFkAXgBjAGgAbQByAHcAfACBAIYAiwCQAJUAmgCfAKQAqQCuALIA twC8AMEAxgDLANAA1QDbAOAA5QDrAPAA9gD7AQEBBwENARMBGQEfASUBKwEyATgBPgFFAUwBUgFZ AWABZwFuAXUBfAGDAYsBkgGaAaEBqQGxAbkBwQHJAdEB2QHhAekB8gH6AgMCDAIUAh0CJgIvAjgC QQJLAlQCXQJnAnECegKEAo4CmAKiAqwCtgLBAssC1QLgAusC9QMAAwsDFgMhAy0DOANDA08DWgNm A3IDfgOKA5YDogOuA7oDxwPTA+AD7AP5BAYEEwQgBC0EOwRIBFUEYwRxBH4EjASaBKgEtgTEBNME 4QTwBP4FDQUcBSsFOgVJBVgFZwV3BYYFlgWmBbUFxQXVBeUF9gYGBhYGJwY3BkgGWQZqBnsGjAad Bq8GwAbRBuMG9QcHBxkHKwc9B08HYQd0B4YHmQesB78H0gflB/gICwgfCDIIRghaCG4IggiWCKoI vgjSCOcI+wkQCSUJOglPCWQJeQmPCaQJugnPCeUJ+woRCicKPQpUCmoKgQqYCq4KxQrcCvMLCwsi CzkLUQtpC4ALmAuwC8gL4Qv5DBIMKgxDDFwMdQyODKcMwAzZDPMNDQ0mDUANWg10DY4NqQ3DDd4N +A4TDi4OSQ5kDn8Omw62DtIO7g8JDyUPQQ9eD3oPlg+zD88P7BAJECYQQxBhEH4QmxC5ENcQ9RET ETERTxFtEYwRqhHJEegSBxImEkUSZBKEEqMSwxLjEwMTIxNDE2MTgxOkE8UT5RQGFCcUSRRqFIsU rRTOFPAVEhU0FVYVeBWbFb0V4BYDFiYWSRZsFo8WshbWFvoXHRdBF2UXiReuF9IX9xgbGEAYZRiK GK8Y1Rj6GSAZRRlrGZEZtxndGgQaKhpRGncanhrFGuwbFBs7G2MbihuyG9ocAhwqHFIcexyjHMwc 9R0eHUcdcB2ZHcMd7B4WHkAeah6UHr4e6R8THz4faR+UH78f6iAVIEEgbCCYIMQg8CEcIUghdSGh Ic4h+yInIlUigiKvIt0jCiM4I2YjlCPCI/AkHyRNJHwkqyTaJQklOCVoJZclxyX3JicmVyaHJrcm 6CcYJ0kneierJ9woDSg/KHEooijUKQYpOClrKZ0p0CoCKjUqaCqbKs8rAis2K2krnSvRLAUsOSxu LKIs1y0MLUEtdi2rLeEuFi5MLoIuty7uLyQvWi+RL8cv/jA1MGwwpDDbMRIxSjGCMbox8jIqMmMy mzLUMw0zRjN/M7gz8TQrNGU0njTYNRM1TTWHNcI1/TY3NnI2rjbpNyQ3YDecN9c4FDhQOIw4yDkF OUI5fzm8Ofk6Njp0OrI67zstO2s7qjvoPCc8ZTykPOM9Ij1hPaE94D4gPmA+oD7gPyE/YT+iP+JA I0BkQKZA50EpQWpBrEHuQjBCckK1QvdDOkN9Q8BEA0RHRIpEzkUSRVVFmkXeRiJGZ0arRvBHNUd7 R8BIBUhLSJFI10kdSWNJqUnwSjdKfUrESwxLU0uaS+JMKkxyTLpNAk1KTZNN3E4lTm5Ot08AT0lP k0/dUCdQcVC7UQZRUFGbUeZSMVJ8UsdTE1NfU6pT9lRCVI9U21UoVXVVwlYPVlxWqVb3V0RXklfg WC9YfVjLWRpZaVm4WgdaVlqmWvVbRVuVW+VcNVyGXNZdJ114XcleGl5sXr1fD19hX7NgBWBXYKpg /GFPYaJh9WJJYpxi8GNDY5dj62RAZJRk6WU9ZZJl52Y9ZpJm6Gc9Z5Nn6Wg/aJZo7GlDaZpp8WpI ap9q92tPa6dr/2xXbK9tCG1gbbluEm5rbsRvHm94b9FwK3CGcOBxOnGVcfByS3KmcwFzXXO4dBR0 cHTMdSh1hXXhdj52m3b4d1Z3s3gReG54zHkqeYl553pGeqV7BHtje8J8IXyBfOF9QX2hfgF+Yn7C fyN/hH/lgEeAqIEKgWuBzYIwgpKC9INXg7qEHYSAhOOFR4Wrhg6GcobXhzuHn4gEiGmIzokziZmJ /opkisqLMIuWi/yMY4zKjTGNmI3/jmaOzo82j56QBpBukNaRP5GokhGSepLjk02TtpQglIqU9JVf lcmWNJaflwqXdZfgmEyYuJkkmZCZ/JpomtWbQpuvnByciZz3nWSd0p5Anq6fHZ+Ln/qgaaDYoUeh tqImopajBqN2o+akVqTHpTilqaYapoum/adup+CoUqjEqTepqaocqo+rAqt1q+msXKzQrUStuK4t rqGvFq+LsACwdbDqsWCx1rJLssKzOLOutCW0nLUTtYq2AbZ5tvC3aLfguFm40blKucK6O7q1uy67 p7whvJu9Fb2Pvgq+hL7/v3q/9cBwwOzBZ8Hjwl/C28NYw9TEUcTOxUvFyMZGxsPHQce/yD3IvMk6 ybnKOMq3yzbLtsw1zLXNNc21zjbOts83z7jQOdC60TzRvtI/0sHTRNPG1EnUy9VO1dHWVdbY11zX 4Nhk2OjZbNnx2nba+9uA3AXcit0Q3ZbeHN6i3ynfr+A24L3hROHM4lPi2+Nj4+vkc+T85YTmDeaW 5x/nqegy6LzpRunQ6lvq5etw6/vshu0R7ZzuKO6070DvzPBY8OXxcvH/8ozzGfOn9DT0wvVQ9d72 bfb794r4Gfio+Tj5x/pX+uf7d/wH/Jj9Kf26/kv+3P9t////7gAhQWRvYmUAZIAAAAABAwAQAwID BgAAAAAAAAAAAAAAAP/bAIQADAgICAkIDAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwM DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwM DAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM/8IAEQgAdQE+AwEiAAIRAQMRAf/EAMQA AQACAwEBAQAAAAAAAAAAAAAECAECBQMGBwEBAQEBAAAAAAAAAAAAAAAAAAECAxAAAQQCAAUEAwEA AAAAAAAAAQIDBAUAERBAUBIVIDATFGAhMQYRAAIBAQQEBQwPBgcAAAAAAAECAwQAERITITEiIzJS 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 YXBwLnhtbFBLBQYAAAAADgAOAJADAADDlAAAAAA= ------=_NextPart_000_020F_01CFD23B.D572D5D0-- From david@fromorbit.com Wed Sep 17 01:03:09 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 2B79B7F47 for ; Wed, 17 Sep 2014 01:03:09 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id CAB1CAC008 for ; Tue, 16 Sep 2014 23:03:05 -0700 (PDT) X-ASG-Debug-ID: 1410933783-04bdf01097aeea20001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id S0VdHWZbekzbgJ9Z for ; Tue, 16 Sep 2014 23:03:03 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AqkcAC4jGVR5LCtm/2dsb2JhbABggw2BKoIuslgGlhaFawQCAYEXFwF5hAMBAQEDATocIwULCAMOCgklDwUlAyETFoggB700GBiFZIlPB4RLBZ0JlUeDcCsvgkoBAQE Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail07.adl2.internode.on.net with ESMTP; 17 Sep 2014 15:33:02 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XU8KH-0004Ja-64; Wed, 17 Sep 2014 16:02:49 +1000 Date: Wed, 17 Sep 2014 16:02:49 +1000 From: Dave Chinner To: Brian Hemme Cc: xfs@oss.sgi.com Subject: Re: mkfs.xfs fails with raid5 and smaller chunk sizes Message-ID: <20140917060249.GR4322@dastard> X-ASG-Orig-Subj: Re: mkfs.xfs fails with raid5 and smaller chunk sizes References: <5418B39C.2060707@rincon.com> <20140916221738.GO4322@dastard> <5418BE0F.9040702@rincon.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5418BE0F.9040702@rincon.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1410933783 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9571 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 16, 2014 at 03:47:43PM -0700, Brian Hemme wrote: > On 09/16/2014 03:17 PM, Dave Chinner wrote: > >On Tue, Sep 16, 2014 at 03:03:08PM -0700, Brian Hemme wrote: > >>Hello all, > >> > >>I am having some odd problems with mkfs.xfs when used on a raid 5 > >>array. The array is built from 6 960GB SSDs all connected to SATA > >>ports on the MB and created with mdadm. If I use a chunk size any > >>smaller then 512K mkfs.xfs just hangs forever. It continues to use > >>CPU and so does the raid array but never completes. If the system > >>is just left running for an extended length of time the whole OS > >>eventually locks up. I have tried this on three different systems > >>with the same results. I have searched all over for someone with > >>similar issues without success. I am hoping I am just doing > >>something clearly wrong and you all can set me straight quickly. > >> > >>Some specifics: > >> Arch linux with 3.14.1 kernel > >> mkfs.xfs version 3.1.11 > >> mdadm - v3.3 - 3rd September 2013 > >> > >>Commands: > >>>mdadm --create /dev/md0 --chunk=64K --level=5 --raid-devices=6 > >>/dev/sd[a-f] > >>>mkfs.xfs /dev/md0 > >> ** This command fails and locks up > >> > >>I have tried specifying the arguments to mkfs.xfs with the same > >>results. Building a 4 drive array seems to require a chunk size of > >>1M or greater to work. Same results if I make a partition on the > >>array and make the fs there. > >mkfs.xfs really should only take a couple of seconds to complete. > >Seeing as you are using SSDs, my first suspicion is that md or the > >SSDs are having problems with discard. Hence you should first > >try 'mkfs.xfs -K /dev/md0' and see if that completes quickly. > > > >Otherwise, output of 'echo w> sysrq-trigger' from dmesg would be a > >good start, as would a 'perf top -G -U' snapshot (run for 30s at > >least a minute after mkfs.xfs starts) to tell us what is burning > >CPU. > > > >Cheers, > > > >Dave. > > Thanks for the quick response! > > Adding the -K seemed to do the trick. However, for my education, > why is this needed in this case? It seems to work without it for > larger chunk sizes or for raid 0 instead of 5. Discard on RAID 5 can require parity recalculation if the discard sizes are small which means RMW operations. I'd say you probably need to ask the linux-raid list to debug whatever issue you are having with the RAID5 code. > It also worked on > our old install with a 3.1.6 kernel. RAID5 discard support was added in 3.1.7.... > Any why would not using the -K > cause enough of a problem that the whole machine hangs? Just trying > to understand this enough to make sure I don't run into problems > down the road. If you cause the IO subsystem to choke up, the system can hang because it can't clean dirty pages of memory and hence you can get ENOMEM situations that can hang the machine. Again, i'd first talk to the linux-raid folk to find out what is causing the RAID5 to be so slow in this case as it's really nothing to do with XFS at this point... Cheers, Dave. -- Dave Chinner david@fromorbit.com From bfoster@redhat.com Wed Sep 17 08:57:19 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 533547F47 for ; Wed, 17 Sep 2014 08:57:19 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 3F4278F8054 for ; Wed, 17 Sep 2014 06:57:19 -0700 (PDT) X-ASG-Debug-ID: 1410962236-04cbb05486e45750001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id tsvBzMHQra7bnom4 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 17 Sep 2014 06:57:18 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8HDvDrH012272 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 17 Sep 2014 09:57:13 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8HDvCDD028757; Wed, 17 Sep 2014 09:57:12 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id A1751120064; Wed, 17 Sep 2014 09:57:11 -0400 (EDT) Date: Wed, 17 Sep 2014 09:57:11 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: flush entire last page of old EOF on truncate up Message-ID: <20140917135711.GB29222@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs: flush entire last page of old EOF on truncate up References: <1410907547-9253-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1410907547-9253-1-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1410962237 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Sep 17, 2014 at 08:45:47AM +1000, Dave Chinner wrote: > From: Dave Chinner > > On a sub-page sized filesystem, truncating a mapped region down > leaves us in a world of hurt. We truncate the pagecache, zeroing the > newly unused tail, then punch blocks out from under the page. If we > then truncate the file back up immediately, we expose that unmapped > hole to a dirty page mapped into the user application, and that's > where it all goes wrong. > > In truncating the page cache, we avoid unmapping the tail page of > the cache because it still contains valid data. The problem is that > it also contains a hole after the truncate, but nobody told the mm > subsystem that. Therefore, if the page is dirty before the truncate, > we'll never get a .page_mkwrite callout after we extend the file and > the application writes data into the hole on the page. Hence when > we come to writing that region of the page, it has no blocks and no > delayed allocation reservation and hence we toss the data away. > > This patch adds code to the truncate up case to solve it, by > ensuring the partial page at the old EOF is always cleaned after we > do any zeroing and move the EOF upwards. We can't actually serialise > the page writeback and truncate against page faults (yes, that > problem AGAIN) so this is really just a best effort and assumes it > is extremely unlikely that someone is concurrently writing to the > page at the EOF while extending the file. > > Signed-off-by: Dave Chinner > --- > fs/xfs/xfs_iops.c | 30 ++++++++++++++++++++++++++++++ > 1 file changed, 30 insertions(+) > > diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c > index 63aeca8..a726d37 100644 > --- a/fs/xfs/xfs_iops.c > +++ b/fs/xfs/xfs_iops.c > @@ -853,6 +853,36 @@ xfs_setattr_size( > return error; > truncate_setsize(inode, newsize); > > + /* > + * The "we can't serialise against page faults" pain gets worse. > + * > + * If the file is mapped then we have to clean the page at the old EOF > + * when extending the file. Extending the file can expose changes the > + * underlying page mapping (e.g. from beyond EOF to a hole or > + * unwritten), and so on the next attempt to write to that page we need > + * to remap it for write. i.e. we need .page_mkwrite() to be called. > + * Hence we need to clean the page to clean the pte and so a new write > + * fault will be triggered appropriately. > + * > + * If we do it before we change the inode size, then we can race with a > + * page fault that maps the page with exactly the same problem. If we do > + * it after we change the file size, then a new page fault can come in > + * and allocate space before we've run the rest of the truncate > + * transaction. That's kinda grotesque, but it's better than have data > + * over a hole, and so that's the lesser evil that has been chosen here. > + * > + * The real solution, however, is to have some mechanism for locking out > + * page faults while a truncate is in progress. > + */ > + if (newsize > oldsize && mapping_mapped(VFS_I(ip)->i_mapping)) { > + error = filemap_write_and_wait_range( > + VFS_I(ip)->i_mapping, > + round_down(oldsize, PAGE_CACHE_SIZE), > + round_up(oldsize, PAGE_CACHE_SIZE) - 1); > + if (error) > + return error; > + } > + IIUC, clear_page_dirty_for_io() will clean/writeprotect the page on writeback. Hence any future mmap write generates a (soft) fault and allows the mm subsystem to invoke mkwrite(), which in turn allows XFS to handle the block mapping (e.g., allocating delalloc blocks via get_block()) for the mapped write. I was starting to think about whether we could combine this with the previous writeback in xfs_setattr_size(), but the complex nature of the problem, the long comment required and the notion that we might want to fix this "for real" some day suggests the the separate hunk is probably safer. Anyways, if I'm following the above behavior correctly, this looks fine to me: Reviewed-by: Brian Foster > tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE); > error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0); > if (error) > -- > 2.0.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bmh@rincon.com Wed Sep 17 10:07:04 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 01A667F50 for ; Wed, 17 Sep 2014 10:07:04 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 828C5AC002 for ; Wed, 17 Sep 2014 08:07:00 -0700 (PDT) X-ASG-Debug-ID: 1410966417-04cb6c54fdb785c0001-NocioJ Received: from autodiscover.rincon.com (smtp.rincon.com [67.128.198.140]) by cuda.sgi.com with ESMTP id NUCpdVNJCn6VNUCe for ; Wed, 17 Sep 2014 08:06:57 -0700 (PDT) X-Barracuda-Envelope-From: bmh@rincon.com X-Barracuda-Apparent-Source-IP: 67.128.198.140 Received: from brhazbriklab3.rinconres.com (172.16.203.59) by autodiscover.rincon.com (172.16.203.53) with Microsoft SMTP Server id 14.3.195.1; Wed, 17 Sep 2014 08:06:57 -0700 Message-ID: <5419A391.5070203@rincon.com> Date: Wed, 17 Sep 2014 08:06:57 -0700 From: Brian Hemme User-Agent: Mozilla/5.0 (X11; Linux i686 on x86_64; rv:7.0.1) Gecko/20110929 Thunderbird/7.0.1 MIME-Version: 1.0 To: Dave Chinner CC: Subject: Re: mkfs.xfs fails with raid5 and smaller chunk sizes References: <5418B39C.2060707@rincon.com> <20140916221738.GO4322@dastard> <5418BE0F.9040702@rincon.com> <20140917060249.GR4322@dastard> X-ASG-Orig-Subj: Re: mkfs.xfs fails with raid5 and smaller chunk sizes In-Reply-To: <20140917060249.GR4322@dastard> Content-Type: text/plain; charset="ISO-8859-1"; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: smtp.rincon.com[67.128.198.140] X-Barracuda-Start-Time: 1410966417 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9583 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 09/16/2014 11:02 PM, Dave Chinner wrote: > On Tue, Sep 16, 2014 at 03:47:43PM -0700, Brian Hemme wrote: >> On 09/16/2014 03:17 PM, Dave Chinner wrote: >>> On Tue, Sep 16, 2014 at 03:03:08PM -0700, Brian Hemme wrote: >>>> Hello all, >>>> >>>> I am having some odd problems with mkfs.xfs when used on a raid 5 >>>> array. The array is built from 6 960GB SSDs all connected to SATA >>>> ports on the MB and created with mdadm. If I use a chunk size any >>>> smaller then 512K mkfs.xfs just hangs forever. It continues to use >>>> CPU and so does the raid array but never completes. If the system >>>> is just left running for an extended length of time the whole OS >>>> eventually locks up. I have tried this on three different systems >>>> with the same results. I have searched all over for someone with >>>> similar issues without success. I am hoping I am just doing >>>> something clearly wrong and you all can set me straight quickly. >>>> >>>> Some specifics: >>>> Arch linux with 3.14.1 kernel >>>> mkfs.xfs version 3.1.11 >>>> mdadm - v3.3 - 3rd September 2013 >>>> >>>> Commands: >>>>> mdadm --create /dev/md0 --chunk=64K --level=5 --raid-devices=6 >>>> /dev/sd[a-f] >>>>> mkfs.xfs /dev/md0 >>>> ** This command fails and locks up >>>> >>>> I have tried specifying the arguments to mkfs.xfs with the same >>>> results. Building a 4 drive array seems to require a chunk size of >>>> 1M or greater to work. Same results if I make a partition on the >>>> array and make the fs there. >>> mkfs.xfs really should only take a couple of seconds to complete. >>> Seeing as you are using SSDs, my first suspicion is that md or the >>> SSDs are having problems with discard. Hence you should first >>> try 'mkfs.xfs -K /dev/md0' and see if that completes quickly. >>> >>> Otherwise, output of 'echo w> sysrq-trigger' from dmesg would be a >>> good start, as would a 'perf top -G -U' snapshot (run for 30s at >>> least a minute after mkfs.xfs starts) to tell us what is burning >>> CPU. >>> >>> Cheers, >>> >>> Dave. >> Thanks for the quick response! >> >> Adding the -K seemed to do the trick. However, for my education, >> why is this needed in this case? It seems to work without it for >> larger chunk sizes or for raid 0 instead of 5. > Discard on RAID 5 can require parity recalculation if the discard > sizes are small which means RMW operations. I'd say you probably > need to ask the linux-raid list to debug whatever issue you are > having with the RAID5 code. > >> It also worked on >> our old install with a 3.1.6 kernel. > RAID5 discard support was added in 3.1.7.... > >> Any why would not using the -K >> cause enough of a problem that the whole machine hangs? Just trying >> to understand this enough to make sure I don't run into problems >> down the road. > If you cause the IO subsystem to choke up, the system can hang > because it can't clean dirty pages of memory and hence you can get > ENOMEM situations that can hang the machine. Again, i'd first talk > to the linux-raid folk to find out what is causing the RAID5 to be > so slow in this case as it's really nothing to do with XFS at this > point... > > Cheers, > > Dave. Thanks very much Dave. You got me everything I needed. Brian From gwlyq@gmail.ru Wed Sep 17 16:03:38 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 8F1987F53 for ; Wed, 17 Sep 2014 16:03:38 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 787C2304048 for ; Wed, 17 Sep 2014 14:03:38 -0700 (PDT) X-ASG-Debug-ID: 1410987805-04cbb05488e59680001-NocioJ Received: from vps1.iwannaweb.com.au (vps1.iwannaweb.com.au [110.232.114.170]) by cuda.sgi.com with ESMTP id sBexHoXqZ9b3EE12 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 17 Sep 2014 14:03:26 -0700 (PDT) X-Barracuda-Envelope-From: gwlyq@gmail.ru X-Barracuda-Apparent-Source-IP: 110.232.114.170 Received: from 94.41.73.219.dynamic.ufanet.ru ([94.41.73.219]:2415 helo=Unknown) by vps1.iwannaweb.com.au with esmtpa (Exim 4.82) (envelope-from ) id 1XUMNn-0005Q0-NJ for xfs@oss.sgi.com; Thu, 18 Sep 2014 07:03:24 +1000 Message-ID: Reply-To: "350$" From: "350$" To: Subject: =?windows-1251?B?x+Dw4OHu8u7qIDM1MCQg4iDk5e38Li4uW2Jt?= =?windows-1251?B?b2hqcl0=?= Date: Thu, 18 Sep 2014 01:02:53 +0400 X-ASG-Orig-Subj: =?windows-1251?B?x+Dw4OHu8u7qIDM1MCQg4iDk5e38Li4uW2Jt?= =?windows-1251?B?b2hqcl0=?= Organization: 350$ MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_142C_01CFD2DC.46C99D90" X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Windows Live Mail 14.0.8089.726 X-MimeOLE: Produced By Microsoft MimeOLE V14.0.8089.726 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - vps1.iwannaweb.com.au X-AntiAbuse: Original Domain - oss.sgi.com X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - gmail.ru X-Get-Message-Sender-Via: vps1.iwannaweb.com.au: authenticated_id: industrial@hakoaustralia.com.au X-Barracuda-Connect: vps1.iwannaweb.com.au[110.232.114.170] X-Barracuda-Start-Time: 1410987806 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.01 X-Barracuda-Spam-Status: No, SCORE=0.01 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC2_SA022a, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9591 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 0.01 BSF_SC2_SA022a Custom Rule SA022a This is a multi-part message in MIME format. ------=_NextPart_000_142C_01CFD2DC.46C99D90 Content-Type: text/plain; charset="windows-1251" Content-Transfer-Encoding: quoted-printable =C7=E0=F0=E0=E1=EE=F2=EE=EA 350$ =E2 =E4=E5=ED=FC![epwkn]=20 =DD=F2=EE =F0=E5=E0=EB=FC=ED=EE![cubhosov]=20 =D0=E0=E1=EE=F2=E0 =E2 =E8=ED=F2=E5=F0=ED=E5=F2=E5![cnnaojw]=20 =C7=E0=F0=E0=E1=EE=F2=E0=E9 =EF=E5=F0=E2=FB=E5 =E4=E5=ED=FC=E3=E8 =F3=E6=E5= =F1=E5=E3=EE=E4=ED=FF![pwlxjss]=20 =C7=E0=F5=EE=E4=E8...=20 [http://tinyurl.com/qjj3jfl]=20 [kobzvbcf]=20 [gkftllkb]=20 ------=_NextPart_000_142C_01CFD2DC.46C99D90 Content-Type: text/html; charset="windows-1251" Content-Transfer-Encoding: quoted-printable
=C7=E0=F0=E0=E1=EE=F2=EE=EA 350$ =E2 =E4=E5=ED=FC![epwkn]
=DD=F2=EE =F0=E5=E0=EB=FC=ED=EE![cubhosov]
=D0=E0=E1=EE=F2=E0 =E2 =E8=ED=F2=E5=F0= =ED=E5=F2=E5![cnnaojw]
=C7=E0=F0=E0=E1=EE=F2=E0=E9 =EF=E5=F0=E2= =FB=E5 =E4=E5=ED=FC=E3=E8=20 =F3=E6=E5 =F1=E5=E3=EE=E4=ED=FF![pwlxjss]
= =C7=E0=F5=EE=E4=E8...

<= BR>[kobzvbcf]
[gkftllkb]
[kjmlz] ------=_NextPart_000_142C_01CFD2DC.46C99D90-- From david@fromorbit.com Wed Sep 17 16:25:00 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 282B27F55 for ; Wed, 17 Sep 2014 16:25:00 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 07023304048 for ; Wed, 17 Sep 2014 14:24:59 -0700 (PDT) X-ASG-Debug-ID: 1410989094-04cb6c54feb8a2e0001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id tXw2ZlOFGHM3GYaf for ; Wed, 17 Sep 2014 14:24:54 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AjAzAEf7GVR5LCtmPGdsb2JhbABhgw2DWIUHrTgGlhiFagICAQEBgRcXAQYBAQEBODeEAwEBAQMBJxMcIwULCAMOBwMJJQ8FJQMHGhMbiBsHwDMYhXGEDIVXCweESwWPOI1TmTkrL4JKAQEB Received: from ppp121-44-43-102.lns20.syd6.internode.on.net (HELO dastard) ([121.44.43.102]) by ipmail06.adl6.internode.on.net with ESMTP; 18 Sep 2014 06:54:53 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XUMia-0006YS-Cd; Thu, 18 Sep 2014 07:24:52 +1000 Date: Thu, 18 Sep 2014 07:24:52 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: flush entire last page of old EOF on truncate up Message-ID: <20140917212452.GW4322@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs: flush entire last page of old EOF on truncate up References: <1410907547-9253-1-git-send-email-david@fromorbit.com> <20140917135711.GB29222@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140917135711.GB29222@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1410989094 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9592 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Sep 17, 2014 at 09:57:11AM -0400, Brian Foster wrote: > On Wed, Sep 17, 2014 at 08:45:47AM +1000, Dave Chinner wrote: > > From: Dave Chinner > > > > On a sub-page sized filesystem, truncating a mapped region down > > leaves us in a world of hurt. We truncate the pagecache, zeroing the > > newly unused tail, then punch blocks out from under the page. If we > > then truncate the file back up immediately, we expose that unmapped > > hole to a dirty page mapped into the user application, and that's > > where it all goes wrong. > > > > In truncating the page cache, we avoid unmapping the tail page of > > the cache because it still contains valid data. The problem is that > > it also contains a hole after the truncate, but nobody told the mm > > subsystem that. Therefore, if the page is dirty before the truncate, > > we'll never get a .page_mkwrite callout after we extend the file and > > the application writes data into the hole on the page. Hence when > > we come to writing that region of the page, it has no blocks and no > > delayed allocation reservation and hence we toss the data away. > > > > This patch adds code to the truncate up case to solve it, by > > ensuring the partial page at the old EOF is always cleaned after we > > do any zeroing and move the EOF upwards. We can't actually serialise > > the page writeback and truncate against page faults (yes, that > > problem AGAIN) so this is really just a best effort and assumes it > > is extremely unlikely that someone is concurrently writing to the > > page at the EOF while extending the file. > > > > Signed-off-by: Dave Chinner > > --- > > fs/xfs/xfs_iops.c | 30 ++++++++++++++++++++++++++++++ > > 1 file changed, 30 insertions(+) > > > > diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c > > index 63aeca8..a726d37 100644 > > --- a/fs/xfs/xfs_iops.c > > +++ b/fs/xfs/xfs_iops.c > > @@ -853,6 +853,36 @@ xfs_setattr_size( > > return error; > > truncate_setsize(inode, newsize); > > > > + /* > > + * The "we can't serialise against page faults" pain gets worse. > > + * > > + * If the file is mapped then we have to clean the page at the old EOF > > + * when extending the file. Extending the file can expose changes the > > + * underlying page mapping (e.g. from beyond EOF to a hole or > > + * unwritten), and so on the next attempt to write to that page we need > > + * to remap it for write. i.e. we need .page_mkwrite() to be called. > > + * Hence we need to clean the page to clean the pte and so a new write > > + * fault will be triggered appropriately. > > + * > > + * If we do it before we change the inode size, then we can race with a > > + * page fault that maps the page with exactly the same problem. If we do > > + * it after we change the file size, then a new page fault can come in > > + * and allocate space before we've run the rest of the truncate > > + * transaction. That's kinda grotesque, but it's better than have data > > + * over a hole, and so that's the lesser evil that has been chosen here. > > + * > > + * The real solution, however, is to have some mechanism for locking out > > + * page faults while a truncate is in progress. > > + */ > > + if (newsize > oldsize && mapping_mapped(VFS_I(ip)->i_mapping)) { > > + error = filemap_write_and_wait_range( > > + VFS_I(ip)->i_mapping, > > + round_down(oldsize, PAGE_CACHE_SIZE), > > + round_up(oldsize, PAGE_CACHE_SIZE) - 1); > > + if (error) > > + return error; > > + } > > + > > IIUC, clear_page_dirty_for_io() will clean/writeprotect the page on > writeback. Hence any future mmap write generates a (soft) fault and > allows the mm subsystem to invoke mkwrite(), which in turn allows XFS to > handle the block mapping (e.g., allocating delalloc blocks via > get_block()) for the mapped write. That is correct. > I was starting to think about whether we could combine this with the > previous writeback in xfs_setattr_size(), but the complex nature of the > problem, the long comment required and the notion that we might want to > fix this "for real" some day suggests the the separate hunk is probably > safer. I went through several different iterations of flush on truncate down, combine into xfs_zero_eof, flush on truncate up, flush before page cache truncate, flush after, etc. They all worked to solve the problem to some level, but it the deciding factor was that the truncate down/mwrite to tail page within EOF/truncate up case requires the flush to be in the truncate up code for mwrite after truncate up to work correctly. So then it was really a case of working out where to minimise the potential impact of a racing page fault..... > Anyways, if I'm following the above behavior correctly, this > looks fine to me: > > Reviewed-by: Brian Foster Thanks. -Dave. -- Dave Chinner david@fromorbit.com From bounce@client25.emailb.biz Thu Sep 18 01:37:55 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=3.0 required=5.0 tests=BAD_CREDIT,DATE_IN_PAST_12_24, HTML_MESSAGE,NORMAL_HTTP_TO_IP,RCVD_NUMERIC_HELO autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 219F27F4E for ; Thu, 18 Sep 2014 01:37:55 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id E45C5304032 for ; Wed, 17 Sep 2014 23:37:54 -0700 (PDT) X-ASG-Debug-ID: 1411022266-04bdf0109ab2b720001-NocioJ Received: from server25.emailb.biz (server25.emailb.biz [149.210.165.4]) by cuda.sgi.com with ESMTP id gp4qh53oVg7nPA6D (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 17 Sep 2014 23:37:47 -0700 (PDT) X-Barracuda-Envelope-From: bounce@client25.emailb.biz X-Barracuda-Apparent-Source-IP: 149.210.165.4 Received: from localhost ([::1]:39509 helo=149.210.165.4) by server25.emailb.biz with esmtpa (Exim 4.82) (envelope-from ) id 1XUVLc-0000Oc-PY for xfs@oss.sgi.com; Thu, 18 Sep 2014 08:37:44 +0200 To: xfs@oss.sgi.com Subject: Need funds immediately? Message-ID: <40d617ec38e68cb2f7af53d93cadcf64@149.210.165.4> X-ASG-Orig-Subj: Need funds immediately? Date: Wed, 17 Sep 2014 09:31:38 +0000 From: "HDFC Bank" Reply-To: noreply@client25.emailb.biz MIME-Version: 1.0 X-Mailer-LID: 6 List-Unsubscribe: X-Mailer-SID: 48 X-Mailer-Sent-By: 1 Content-Type: multipart/alternative; charset="UTF-8"; boundary="b1_9d8db6e9972c86792a029841ab894097" Content-Transfer-Encoding: 8bit X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - server25.emailb.biz X-AntiAbuse: Original Domain - oss.sgi.com X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - client25.emailb.biz X-Get-Message-Sender-Via: server25.emailb.biz: authenticated_id: client25/from_h X-Barracuda-Connect: server25.emailb.biz[149.210.165.4] X-Barracuda-Start-Time: 1411022267 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 1.34 X-Barracuda-Spam-Status: No, SCORE=1.34 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BAD_CREDIT, BSF_SC5_SA161f, DATE_IN_PAST_12_24, DATE_IN_PAST_12_24_2, HTML_MESSAGE, NORMAL_HTTP_TO_IP X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9605 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.33 BAD_CREDIT BODY: Eliminate Bad Credit 0.01 DATE_IN_PAST_12_24 Date: is 12 to 24 hours before Received: date 0.00 NORMAL_HTTP_TO_IP URI: Uses a dotted-decimal IP address in URL 0.00 HTML_MESSAGE BODY: HTML included in message 0.20 BSF_SC5_SA161f Custom Rule SA161f 0.80 DATE_IN_PAST_12_24_2 DATE_IN_PAST_12_24_2 --b1_9d8db6e9972c86792a029841ab894097 Content-Type: text/plain; format=flowed; charset="UTF-8" Content-Transfer-Encoding: 8bit Your email client cannot read this email. To view it online, please go here: http://149.210.165.4/~client25/display.php?M=1947004&C=17353e1fdaf8141dccfd43ef4c96781e&S=48&L=6&N=7 To stop receiving these emails:http://149.210.165.4/~client25/unsubscribe.php?M=1947004&C=17353e1fdaf8141dccfd43ef4c96781e&L=6&N=48 --b1_9d8db6e9972c86792a029841ab894097 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: 8bit
HDFC Bank
  If you do not wish to receive such mails in future, click here to unsubscribe.
If you are not able to view this mailer properly, please click here
Hdfc hdfc bank
Funds
Personal Loan eligibility
in a minute!
Check now
Benefits
Customised offer for corporate employees
Loan upto Rs 25 lac - Disbursal in 2 days
No minimum credit score requirement
Special offers for working women
Have an existing Personal Loan? Transfer it to us at up to 12.99%* interest rate. Click here
Warm regards,

HDFC Bank

*Terms and conditions apply. Disbursal is subject to submission of documents to validate the credit processing criteria used by HDFC Bank to make the loan offer. Issuance of loan is at the sole discretion of HDFC Bank. If your case was rejected previously, please ignore this mail.
--b1_9d8db6e9972c86792a029841ab894097-- From robin.listas@gmail.com Thu Sep 18 07:46:46 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A573C7F37 for ; Thu, 18 Sep 2014 07:46:46 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 433E0AC002 for ; Thu, 18 Sep 2014 05:46:43 -0700 (PDT) X-ASG-Debug-ID: 1411044397-04bdf0109ab406d0001-NocioJ Received: from mail-we0-f173.google.com (mail-we0-f173.google.com [74.125.82.173]) by cuda.sgi.com with ESMTP id 1ZzCiLz780tRzdDy (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO); Thu, 18 Sep 2014 05:46:38 -0700 (PDT) X-Barracuda-Envelope-From: robin.listas@gmail.com X-Barracuda-Apparent-Source-IP: 74.125.82.173 Received: by mail-we0-f173.google.com with SMTP id t60so855057wes.18 for ; Thu, 18 Sep 2014 05:46:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:date:from:to:cc:subject:message-id:user-agent:mime-version :content-type; bh=7h3UPLXdw49paw1JSAaN4Eex2re51EG1s1mwOCZSanI=; b=VtK7x1jg6veij5Ag00CXlxfrCpBa8Bz6al5JDbu/J3BMSiB9aed0xN/g4ssoX8AN3+ ogRsj2TA0w9DxcRFAsOvyLeAtpLaYb3PMSg8YtVe2N6ZH+X+Jq6mGwhKuoC6MF2LE3yS pr10z4D4V0127Y3iElyPEsZnV7UZ87sM8MshnmxZQQwfBPpUZuIEynkTqRiJLLiTNG10 X39Dq3HltHneWfCEmA87oqFAPUyZsALfb94FgGms/XT2hy22g6p9lpDcvrp9nULlw99h DSrrhOKYyc60z7m4Ble2MbRMrPP/9t6SvXORB3MkUpR+yMrZ22k6h13wN4hTujSl86O9 MKGQ== X-Received: by 10.180.211.208 with SMTP id ne16mr263070wic.71.1411044397171; Thu, 18 Sep 2014 05:46:37 -0700 (PDT) Received: from Telcontar.valinor (177.Red-79-159-63.staticIP.rima-tde.net. [79.159.63.177]) by mx.google.com with ESMTPSA id pn5sm25913659wjc.4.2014.09.18.05.46.36 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 18 Sep 2014 05:46:36 -0700 (PDT) Sender: Carlos Robinson Received: from localhost (localhost [127.0.0.1]) by Telcontar.valinor (Postfix) with ESMTP id E675B61129; Thu, 18 Sep 2014 14:46:33 +0200 (CEST) X-Virus-Scanned: amavisd-new at valinor Received: from Telcontar.valinor ([127.0.0.1]) by localhost (Telcontar.valinor [127.0.0.1]) (amavisd-new, port 10024) with LMTP id JIZSReHHiBkk; Thu, 18 Sep 2014 14:46:33 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by Telcontar.valinor (Postfix) with ESMTP id CA6B460443; Thu, 18 Sep 2014 14:46:32 +0200 (CEST) Date: Thu, 18 Sep 2014 14:46:32 +0200 (CEST) From: "Carlos E. R." X-X-Sender: cer@Telcontar.valinor To: XFS mailing list cc: xfs-owner@oss.sgi.com Subject: What's up with this list? Message-ID: X-ASG-Orig-Subj: What's up with this list? User-Agent: Alpine 2.11 (LSU 23 2013-08-11) MIME-Version: 1.0 Content-Type: MULTIPART/MIXED; BOUNDARY="-1463808511-51534903-1411044392=:6675" X-Barracuda-Connect: mail-we0-f173.google.com[74.125.82.173] X-Barracuda-Start-Time: 1411044398 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9613 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. ---1463808511-51534903-1411044392=:6675 Content-Type: TEXT/PLAIN; format=flowed; charset=UTF-8 Content-Transfer-Encoding: 8BIT -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi, Now an then I get messages like this: ++································· Your membership in the mailing list xfs has been disabled due to excessive bounces The last bounce received from you was dated 18-Sep-2014. You will not get any more messages from this list until you re-enable your membership. You will receive 3 more reminders like this before your membership in the list is deleted. To re-enable your membership, you can simply respond to this message (leaving the Subject: line intact), or visit the confirmation page at ... ·································++- Bounces? I'm subscribed to several mail lists, and this is the only one "complaining". And as I do not know what messages bounced, I can not investigate it. My guess is that those emails were clear and flagrant spam, and as such were rejected by my ISP. The mail list should refuse them on entry and not resend them to the listers. - -- Cheers, Carlos E. R. (from 13.1 x86_64 "Bottle" at Telcontar) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iEYEARECAAYFAlQa1CgACgkQtTMYHG2NR9W0ggCeJAObGhaHx9quXJPCQUggFo// 9PwAnilNJEj3gfi+X+a29MVjo/MDEGvO =CBjB -----END PGP SIGNATURE----- ---1463808511-51534903-1411044392=:6675-- From tdm@sgi.com Thu Sep 18 10:33:56 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE,RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 51DD07F37 for ; Thu, 18 Sep 2014 10:33:56 -0500 (CDT) Received: from estes.americas.sgi.com (estes.americas.sgi.com [128.162.236.10]) by relay2.corp.sgi.com (Postfix) with ESMTP id 22059304043 for ; Thu, 18 Sep 2014 08:33:53 -0700 (PDT) Received: from [128.162.232.11] (porter.americas.sgi.com [128.162.232.11]) by estes.americas.sgi.com (Postfix) with ESMTP id F2DD27002BF9 for ; Thu, 18 Sep 2014 10:33:52 -0500 (CDT) Message-ID: <541AFB60.5030403@sgi.com> Date: Thu, 18 Sep 2014 10:33:52 -0500 From: Troy McCorkell User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.9.1.5) Gecko/20091204 Thunderbird/3.0 MIME-Version: 1.0 To: xfs@oss.sgi.com Subject: Re: What's up with this list? References: In-Reply-To: Content-Type: multipart/alternative; boundary="------------010103060904090701090203" This is a multi-part message in MIME format. --------------010103060904090701090203 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit On 09/18/2014 07:46 AM, Carlos E. R. wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > > > Hi, > > Now an then I get messages like this: > > ++································· > Your membership in the mailing list xfs has been disabled due to > excessive bounces The last bounce received from you was dated > 18-Sep-2014. You will not get any more messages from this list until > you re-enable your membership. You will receive 3 more reminders like > this before your membership in the list is deleted. > > To re-enable your membership, you can simply respond to this message > (leaving the Subject: line intact), or visit the confirmation page at > > ... > > ·································++- > > > Bounces? I'm subscribed to several mail lists, and this is the only > one "complaining". And as I do not know what messages bounced, I can > not investigate it. > > My guess is that those emails were clear and flagrant spam, and as > such were rejected by my ISP. > > The mail list should refuse them on entry and not resend them to the > listers. > > - -- Cheers, > Carlos E. R. > (from 13.1 x86_64 "Bottle" at Telcontar) > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v2.0.22 (GNU/Linux) > > iEYEARECAAYFAlQa1CgACgkQtTMYHG2NR9W0ggCeJAObGhaHx9quXJPCQUggFo// > 9PwAnilNJEj3gfi+X+a29MVjo/MDEGvO > =CBjB > -----END PGP SIGNATURE----- > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs > Carlos, I will forward your email to the SGI IT group. Thanks, Troy McCorkell --------------010103060904090701090203 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit On 09/18/2014 07:46 AM, Carlos E. R. wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1



Hi,

Now an then I get messages like this:

++·································
Your membership in the mailing list xfs has been disabled due to
excessive bounces The last bounce received from you was dated
18-Sep-2014.  You will not get any more messages from this list until
you re-enable your membership.  You will receive 3 more reminders like
this before your membership in the list is deleted.

To re-enable your membership, you can simply respond to this message
(leaving the Subject: line intact), or visit the confirmation page at

...

·································++-


Bounces? I'm subscribed to several mail lists, and this is the only one "complaining". And as I do not know what messages bounced, I can not investigate it.

My guess is that those emails were clear and flagrant spam, and as such were rejected by my ISP.

The mail list should refuse them on entry and not resend them to the listers.

- -- Cheers,
       Carlos E. R.
       (from 13.1 x86_64 "Bottle" at Telcontar)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)

iEYEARECAAYFAlQa1CgACgkQtTMYHG2NR9W0ggCeJAObGhaHx9quXJPCQUggFo//
9PwAnilNJEj3gfi+X+a29MVjo/MDEGvO
=CBjB
-----END PGP SIGNATURE-----
_______________________________________________ xfs mailing list xfs@oss.sgi.com http://oss.sgi.com/mailman/listinfo/xfs
Carlos,

I will forward your email to the SGI IT group.

Thanks,
Troy McCorkell

--------------010103060904090701090203-- From bfoster@redhat.com Thu Sep 18 13:54:25 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6807C7F37 for ; Thu, 18 Sep 2014 13:54:25 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id EB037AC009 for ; Thu, 18 Sep 2014 11:54:24 -0700 (PDT) X-ASG-Debug-ID: 1411066463-04cb6c50e5105c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id vTTVgjjpN9KxCeWW (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 18 Sep 2014 11:54:23 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8IIsM12000664 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Thu, 18 Sep 2014 14:54:22 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8IIsL8i005118 for ; Thu, 18 Sep 2014 14:54:21 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 486EC120064; Thu, 18 Sep 2014 14:54:20 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH] xfs: restore buffer_head unwritten bit on ioend cancel Date: Thu, 18 Sep 2014 14:54:20 -0400 X-ASG-Orig-Subj: [PATCH] xfs: restore buffer_head unwritten bit on ioend cancel Message-Id: <1411066460-23992-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411066463 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xfs_vm_writepage() walks each buffer_head on the page, maps to the block on disk and attaches to a running ioend structure that represents the I/O submission. A new ioend is created when the type of I/O (unwritten, delayed allocation or overwrite) required for a particular buffer_head differs from the previous. If a buffer_head is a delalloc or unwritten buffer, the associated bits are cleared by xfs_map_at_offset() once the buffer_head is added to the ioend. The process of mapping each buffer_head occurs in xfs_map_blocks() and acquires the ilock in blocking or non-blocking mode, depending on the type of writeback in progress. If the lock cannot be acquired for non-blocking writeback, we cancel the ioend, redirty the page and return. Writeback will revisit the page at some later point. Note that we acquire the ilock for each buffer on the page. Therefore during non-blocking writeback, it is possible to add an unwritten buffer to the ioend, clear the unwritten state, fail to acquire the ilock when mapping a subsequent buffer and cancel the ioend. If this occurs, the unwritten status of the buffer sitting in the ioend has been lost. The page will eventually hit writeback again, but xfs_vm_writepage() submits overwrite I/O instead of unwritten I/O and does not perform unwritten extent conversion at I/O completion. This leads to data corruption because unwritten extents are treated as holes on reads and zeroes are returned instead of reading from disk. Modify xfs_cancel_ioend() to restore the buffer unwritten bit for ioends of type XFS_IO_UNWRITTEN. This ensures that unwritten extent conversion occurs once the page is eventually written back. Signed-off-by: Brian Foster --- Hi all, This fixes the problem I've been chasing the past few days with regard to data corruption after hole punch. It turns out the problem isn't directly related to the hole punch after all. I found that the problem still occurs when I remove the truncate_pagecache_range() rounding from xfs_free_file_space(). The difference is data is still sitting in cache and the pages aren't thrown away until reclaimed. E.g., the file corruption is reproducible on subsequent remount. The current method of rounding the truncate throws the pages away such that the corruption is detectable immediately after the hole punch. This is only lightly tested so far with my hacky reproducer. The next step is to turn it into a regression test. xfstests test to follow... Brian fs/xfs/xfs_aops.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 2f50253..f5b2453 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -560,6 +560,13 @@ xfs_cancel_ioend( do { next_bh = bh->b_private; clear_buffer_async_write(bh); + /* + * The unwritten flag is cleared when added to the + * ioend. We're not submitting for I/O so mark the + * buffer unwritten again for next time around. + */ + if (ioend->io_type == XFS_IO_UNWRITTEN) + set_buffer_unwritten(bh); unlock_buffer(bh); } while ((bh = next_bh) != NULL); -- 1.8.3.1 From bpm@sgi.com Thu Sep 18 14:56:50 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D9F157F37 for ; Thu, 18 Sep 2014 14:56:50 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id 991D38F804B; Thu, 18 Sep 2014 12:56:50 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 6493E4266DC; Thu, 18 Sep 2014 14:56:50 -0500 (CDT) Date: Thu, 18 Sep 2014 14:56:50 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) Hi, I'm posting this RFC for Unicode support in XFS on Olaf's behalf, as he is busy with other projects. This is the second revision of the series. The first is available here: http://oss.sgi.com/archives/xfs/2014-09/msg00169.html In response to the initial feedback, the changes in version 2 include: * linux-fsdevel in the To: line, * Updated design notes, * Separation of the fs-independent trie and support code into utf8norm.ko, * A mechanism for loading the normalization module only when necessary. I'll post the whole series for completeness sake. Many on -fsdevel will not be interested in the xfs-specific bits, but it may be helpful to have the full series as an example and for testing purposes. First there is a set of kernel bits, then some libxfs/xfsprogs stuff, and finally a test. (Note: I am not posting the unicode database files due to their large size. There are scripts to download them from unicode.org in the relevant commit headers.) TODO: Store the unicode version number of the filesystem on disk in the super block. Thanks, Ben Here are Olaf's design notes: ----------------------------------------------------------------------------- Unicode/UTF-8 support for XFS So we had a customer request proper unicode support... * What does "supporting unicode" actually mean? >From a text processing point of view, what a filesystem does with filenames is simple: it stores and retrieves them, and compares them for equality. It may reject certain byte sequences as invalid filenames (for example, no filename can contain an ASCII NUL). I've been taking it as a given that when a file is created with a certain byte sequence as its name, then a subsequent directory listing will contain that same byte sequence among the names listed. This leaves comparing names for equality, and in my view this is what "supporting unicode" revolves about. The present state of affairs is that different byte sequences are different filenames. This amounts to tolerating unicode without actually supporting it. To support unicode we have to interpret filenames. What happens when (part of) a filename cannot be interpreted? We can reject the filename, interpret the parts we can, or punt and accept it as an uninterpreted blob. Rejecting ill-formed filenames was my first choice, but I came around on the issue: there are too many ways in which you can end up with having to deal with ill-formed filenames that would leave a user with no recourse but to move whatever they're doing to a different filesystem. Unpacking a tarball with filenames in a different encoding is an example. Partial interpretation of an ill-formed filename just strikes me as the kind of bad idea that most half-houses are. I admit that I have no stronger objection to this than the fact that it makes the code even more complicated and fragile. Which leaves "blob" as the preferred option by default for coping with ill-formed filenames. When comparing well-formed filenames, the question now becomes which byte sequences are considered to be alternative spellings of the same filename. This is where normalization forms come into play, and the unicode standard has quite a bit to say about the subject. If all you're doing is comparison, then choosing NFD over NFC is easy, because the former is easier to calculate than the latter. If you want various spellings of "office" to compare equal, then picking NFKD over NFD for comparison is also an obvious choice. (Hand-picking individual compatibility forms is truly a bad idea.) Ways to spell "office": "o_f_f_i_c_e", "o_f_fi_c_e", and "o_ffi_c_e", using no ligatures, the fi ligature, or the ffi ligature. (Some fool thought it a good idea to add these ligatures to unicode, all we get to decide is how to cope.) The most contentious part is (should be) ignoring the codepoints with the Default_Ignorable_Code_Point property. I've included the list below. My argument, such as it is, is that these code points either have no visible rendering, or in cases like the soft hyphen, are only conditionally visible. The problem with these (as I see it) is that on seeing a filename that might contain them you cannot tell whether they are present. So I propose to ignore them for the purpose of comparing filenames for equality. Finally, case folding. First of all, it is optional. Then the issue is that you either go the language-specific route, or simplify the task by "just" doing a full casefold (C+F, in unicode parlance). Looking around the net I tend to find that if you're going to do casefolding at all, then a language-independent full casefold is preferred because it is the most predictable option. See http://www.w3.org/TR/charmod-norm/ for an example of that kind of reasoning. An additional question is whether case folding should be a fixed (mkfs-time) property of a filesystem or can be enabled and disabled on the fly. When mixing these modes, preferring exact matches is easy. But after case-sensitive creates of files named "README" and "readme", which of these two files will be found by case-insensitive lookups of "Readme", and "ReadMe"? Does the answer differ if the order in which the files were created is reversed? I do not have good answers to those questions, and absent such answers the behavior of a filesystem becomes hard to predict. This may not be a bug according to the design, but it will be experienced as a bug by users. This is why in these patches case folding is a property set at mkfs time. All of these choices can be argued with, but I do believe that the particular combination of choices I made is a defensible one. The code refers to these normalization forms as nfkdi and nfkdicf. * XFS-specific design notes. XFS uses byte strings for filenames, so UTF-8 is the expected format for unicode filenames. This does raise the question what criteria a byte string must meet to be UTF-8. We settled on the following: - Valid unicode code points are 0..0x10FFFF, except that - The surrogates 0xD800..0xDFFF are not valid code points, and - Valid UTF-8 must be a shortest encoding of a valid unicode code point. In addition, U+0 (ASCII NUL, '\0') is used to terminate byte strings (and is itself not part of the string). Moreover strings may be length-limited in addition to being NUL-terminated (there is no such thing as an embedded NUL in a length-limited string). The code uses ("leverages", in corp-speak) the existing XFS infrastructure for case-insensitive filenames. Like the CI code, the name used to create a file is stored on disk, and returned in a lookup. When comparing filenames the normalized forms of the names being compared are generated on the fly from the non-normalized forms stored on disk. If the borgbit (the bit enabling legacy ASCII-based CI in XFS) is set in the superblock, then case folding is added into the mix. This is the nfkdicf normalization form mentioned above. It allows for the creation of case-insensitive filesystems with UTF-8 support. * Implementation notes. Strings are normalized using a trie that stores the relevant information. The trie itself is about 250kB in size, and lives in a separate module. The trie is not checked in: instead we add the source files from the Unicode Character Database and a program that creates the header containing the trie. The key for a lookup in the trie is a UTF-8 sequence. Each valid UTF-8 sequence leads to a leaf. No invalid sequence does. This means that trie lookups can be used to validate UTF-8 sequences, which why there is no specialized code for the same purpose. The trie contains information for the version of unicode in which each code point was defined. This matters because non-normalized strings are stored on disk, and newer versions of unicode may introduce new normalized forms. Ideally, the version of unicode used by the filesystem is stored in the filesystem. The trie also accounts for corrections made in the past to normalizations. This has little value today, because any newly created filesystem would be using unicode version 7.0.0. It is included in order to show, not tell, that such corrections can be handled if they are added in future revisions. The algorithm used to calculate the sequences of bytes for the normalized form of a UTF-8 string is tricky. The core is found in utf8byte(), with an explanation in the preceeding comment. The non-XFS-specific supporting code functions have the prefix 'utf8n' if they handle length-limited strings, and 'utf8' if they handle NUL-terminated strings. ---- # Derived Property: Default_Ignorable_Code_Point # Generated from # Other_Default_Ignorable_Code_Point # + Cf (Format characters) # + Variation_Selector # - White_Space # - FFF9..FFFB (Annotation Characters) # - 0600..0605, 06DD, 070F, 110BD (exceptional Cf characters that should be visible) 00AD ; Default_Ignorable_Code_Point # Cf SOFT HYPHEN 034F ; Default_Ignorable_Code_Point # Mn COMBINING GRAPHEME JOINER 061C ; Default_Ignorable_Code_Point # Cf ARABIC LETTER MARK 115F..1160 ; Default_Ignorable_Code_Point # Lo [2] HANGUL CHOSEONG FILLER..HANGUL JUNGSEONG FILLER 17B4..17B5 ; Default_Ignorable_Code_Point # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA 180B..180D ; Default_Ignorable_Code_Point # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE 180E ; Default_Ignorable_Code_Point # Cf MONGOLIAN VOWEL SEPARATOR 200B..200F ; Default_Ignorable_Code_Point # Cf [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK 202A..202E ; Default_Ignorable_Code_Point # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE 2060..2064 ; Default_Ignorable_Code_Point # Cf [5] WORD JOINER..INVISIBLE PLUS 2065 ; Default_Ignorable_Code_Point # Cn 2066..206F ; Default_Ignorable_Code_Point # Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES 3164 ; Default_Ignorable_Code_Point # Lo HANGUL FILLER FE00..FE0F ; Default_Ignorable_Code_Point # Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 FEFF ; Default_Ignorable_Code_Point # Cf ZERO WIDTH NO-BREAK SPACE FFA0 ; Default_Ignorable_Code_Point # Lo HALFWIDTH HANGUL FILLER FFF0..FFF8 ; Default_Ignorable_Code_Point # Cn [9] .. 1BCA0..1BCA3 ; Default_Ignorable_Code_Point # Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP 1D173..1D17A ; Default_Ignorable_Code_Point # Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE E0000 ; Default_Ignorable_Code_Point # Cn E0001 ; Default_Ignorable_Code_Point # Cf LANGUAGE TAG E0002..E001F ; Default_Ignorable_Code_Point # Cn [30] .. E0020..E007F ; Default_Ignorable_Code_Point # Cf [96] TAG SPACE..CANCEL TAG E0080..E00FF ; Default_Ignorable_Code_Point # Cn [128] .. E0100..E01EF ; Default_Ignorable_Code_Point # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 E01F0..E0FFF ; Default_Ignorable_Code_Point # Cn [3600] .. # Total code points: 4173 ---- From bpm@sgi.com Thu Sep 18 15:08:20 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 5A0407F37 for ; Thu, 18 Sep 2014 15:08:20 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id C035BAC003; Thu, 18 Sep 2014 13:08:16 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 73EAC4266DC; Thu, 18 Sep 2014 15:08:16 -0500 (CDT) Date: Thu, 18 Sep 2014 15:08:16 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 01/10] xfs: return the first match during case-insensitive lookup. Message-ID: <20140918200816.GC4482@sgi.com> References: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918195650.GI19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Change the XFS case-insensitive lookup code to return the first match found, even if it is not an exact match. Whether a filesystem uses case-insensitive lookups is determined by a superblock bit set during filesystem creation. This means that normal use cannot create two files that both match the same filename. Signed-off-by: Olaf Weber --- fs/xfs/libxfs/xfs_dir2_block.c | 17 +++------ fs/xfs/libxfs/xfs_dir2_leaf.c | 37 ++++---------------- fs/xfs/libxfs/xfs_dir2_node.c | 79 ++++++++++++++++-------------------------- fs/xfs/libxfs/xfs_dir2_sf.c | 8 ++--- 4 files changed, 45 insertions(+), 96 deletions(-) diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 9628cec..990bf0c 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -725,28 +725,21 @@ xfs_dir2_block_lookup_int( dep = (xfs_dir2_data_entry_t *) ((char *)hdr + xfs_dir2_dataptr_to_off(args->geo, addr)); /* - * Compare name and if it's an exact match, return the index - * and buffer. If it's the first case-insensitive match, store - * the index and buffer and continue looking for an exact match. + * Compare name and if it's a match, return the + * index and buffer. */ cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); - if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { + if (cmp != XFS_CMP_DIFFERENT) { args->cmpresult = cmp; *bpp = bp; *entno = mid; - if (cmp == XFS_CMP_EXACT) - return 0; + return 0; } } while (++mid < be32_to_cpu(btp->count) && be32_to_cpu(blp[mid].hashval) == hash); ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); - /* - * Here, we can only be doing a lookup (not a rename or replace). - * If a case-insensitive match was found earlier, return success. - */ - if (args->cmpresult == XFS_CMP_CASE) - return 0; + ASSERT(args->cmpresult == XFS_CMP_DIFFERENT); /* * No match, release the buffer and return ENOENT. */ diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index a19174e..3d572ee 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -1226,7 +1226,6 @@ xfs_dir2_leaf_lookup_int( xfs_mount_t *mp; /* filesystem mount point */ xfs_dir2_db_t newdb; /* new data block number */ xfs_trans_t *tp; /* transaction pointer */ - xfs_dir2_db_t cidb = -1; /* case match data block no. */ enum xfs_dacmp cmp; /* name compare result */ struct xfs_dir2_leaf_entry *ents; struct xfs_dir3_icleaf_hdr leafhdr; @@ -1290,46 +1289,22 @@ xfs_dir2_leaf_lookup_int( be32_to_cpu(lep->address))); /* * Compare name and if it's an exact match, return the index - * and buffer. If it's the first case-insensitive match, store - * the index and buffer and continue looking for an exact match. + * and buffer */ cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); - if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { + if (cmp != XFS_CMP_DIFFERENT) { args->cmpresult = cmp; *indexp = index; - /* case exact match: return the current buffer. */ - if (cmp == XFS_CMP_EXACT) { - *dbpp = dbp; - return 0; - } - cidb = curdb; + *dbpp = dbp; + return 0; } } ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); - /* - * Here, we can only be doing a lookup (not a rename or remove). - * If a case-insensitive match was found earlier, re-read the - * appropriate data block if required and return it. - */ - if (args->cmpresult == XFS_CMP_CASE) { - ASSERT(cidb != -1); - if (cidb != curdb) { - xfs_trans_brelse(tp, dbp); - error = xfs_dir3_data_read(tp, dp, - xfs_dir2_db_to_da(args->geo, cidb), - -1, &dbp); - if (error) { - xfs_trans_brelse(tp, lbp); - return error; - } - } - *dbpp = dbp; - return 0; - } + ASSERT(args->cmpresult == XFS_CMP_DIFFERENT); + /* * No match found, return -ENOENT. */ - ASSERT(cidb == -1); if (dbp) xfs_trans_brelse(tp, dbp); xfs_trans_brelse(tp, lbp); diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 2ae6ac2..1778c40 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -679,6 +679,7 @@ xfs_dir2_leafn_lookup_for_entry( xfs_dir2_data_entry_t *dep; /* data block entry */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return value */ + int di = -1; /* data entry index */ int index; /* leaf entry index */ xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */ @@ -709,6 +710,7 @@ xfs_dir2_leafn_lookup_for_entry( if (state->extravalid) { curbp = state->extrablk.bp; curdb = state->extrablk.blkno; + di = state->extrablk.index; } /* * Loop over leaf entries with the right hash value. @@ -734,28 +736,20 @@ xfs_dir2_leafn_lookup_for_entry( */ if (newdb != curdb) { /* - * If we had a block before that we aren't saving - * for a CI name, drop it + * If we had a block, drop it */ - if (curbp && (args->cmpresult == XFS_CMP_DIFFERENT || - curdb != state->extrablk.blkno)) + if (curbp) { xfs_trans_brelse(tp, curbp); + di = -1; + } /* - * If needing the block that is saved with a CI match, - * use it otherwise read in the new data block. + * Read in the new data block. */ - if (args->cmpresult != XFS_CMP_DIFFERENT && - newdb == state->extrablk.blkno) { - ASSERT(state->extravalid); - curbp = state->extrablk.bp; - } else { - error = xfs_dir3_data_read(tp, dp, - xfs_dir2_db_to_da(args->geo, - newdb), + error = xfs_dir3_data_read(tp, dp, + xfs_dir2_db_to_da(args->geo, newdb), -1, &curbp); - if (error) - return error; - } + if (error) + return error; xfs_dir3_data_check(dp, curbp); curdb = newdb; } @@ -766,53 +760,40 @@ xfs_dir2_leafn_lookup_for_entry( xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address))); /* - * Compare the entry and if it's an exact match, return - * EEXIST immediately. If it's the first case-insensitive - * match, store the block & inode number and continue looking. + * Compare the entry and if it's a match, return + * EEXIST immediately. */ cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); - if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { - /* If there is a CI match block, drop it */ - if (args->cmpresult != XFS_CMP_DIFFERENT && - curdb != state->extrablk.blkno) - xfs_trans_brelse(tp, state->extrablk.bp); + if (cmp != XFS_CMP_DIFFERENT) { args->cmpresult = cmp; args->inumber = be64_to_cpu(dep->inumber); args->filetype = dp->d_ops->data_get_ftype(dep); - *indexp = index; - state->extravalid = 1; - state->extrablk.bp = curbp; - state->extrablk.blkno = curdb; - state->extrablk.index = (int)((char *)dep - - (char *)curbp->b_addr); - state->extrablk.magic = XFS_DIR2_DATA_MAGIC; curbp->b_ops = &xfs_dir3_data_buf_ops; xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF); - if (cmp == XFS_CMP_EXACT) - return -EEXIST; + di = (int)((char *)dep - (char *)curbp->b_addr); + error = -EEXIST; + goto out; + } } + /* Didn't find a match */ + error = -ENOENT; ASSERT(index == leafhdr.count || (args->op_flags & XFS_DA_OP_OKNOENT)); +out: if (curbp) { - if (args->cmpresult == XFS_CMP_DIFFERENT) { - /* Giving back last used data block. */ - state->extravalid = 1; - state->extrablk.bp = curbp; - state->extrablk.index = -1; - state->extrablk.blkno = curdb; - state->extrablk.magic = XFS_DIR2_DATA_MAGIC; - curbp->b_ops = &xfs_dir3_data_buf_ops; - xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF); - } else { - /* If the curbp is not the CI match block, drop it */ - if (state->extrablk.bp != curbp) - xfs_trans_brelse(tp, curbp); - } + /* Giving back last used data block. */ + state->extravalid = 1; + state->extrablk.bp = curbp; + state->extrablk.index = di; + state->extrablk.blkno = curdb; + state->extrablk.magic = XFS_DIR2_DATA_MAGIC; + curbp->b_ops = &xfs_dir3_data_buf_ops; + xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF); } else { state->extravalid = 0; } *indexp = index; - return -ENOENT; + return error; } /* diff --git a/fs/xfs/libxfs/xfs_dir2_sf.c b/fs/xfs/libxfs/xfs_dir2_sf.c index 5079e05..e69fdb7 100644 --- a/fs/xfs/libxfs/xfs_dir2_sf.c +++ b/fs/xfs/libxfs/xfs_dir2_sf.c @@ -757,19 +757,19 @@ xfs_dir2_sf_lookup( for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { /* - * Compare name and if it's an exact match, return the inode - * number. If it's the first case-insensitive match, store the - * inode number and continue looking for an exact match. + * Compare name and if it's a match, return the inode + * number. */ cmp = dp->i_mount->m_dirnameops->compname(args, sfep->name, sfep->namelen); - if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { + if (cmp != XFS_CMP_DIFFERENT) { args->cmpresult = cmp; args->inumber = dp->d_ops->sf_get_ino(sfp, sfep); args->filetype = dp->d_ops->sf_get_ftype(sfep); if (cmp == XFS_CMP_EXACT) return -EEXIST; ci_sfep = sfep; + break; } } ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:09:13 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id A241A7F37 for ; Thu, 18 Sep 2014 15:09:13 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id 87D998F8035; Thu, 18 Sep 2014 13:09:10 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 4A3164266DC; Thu, 18 Sep 2014 15:09:10 -0500 (CDT) Date: Thu, 18 Sep 2014 15:09:10 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 02/10] xfs: rename XFS_CMP_CASE to XFS_CMP_MATCH Message-ID: <20140918200910.GD4482@sgi.com> References: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918195650.GI19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Rename XFS_CMP_CASE to XFS_CMP_MATCH. With unicode filenames and normalization, different strings will match on other criteria than case insensitivity. Signed-off-by: Olaf Weber --- fs/xfs/libxfs/xfs_da_btree.h | 2 +- fs/xfs/libxfs/xfs_dir2.c | 9 ++++++--- fs/xfs/libxfs/xfs_dir2_node.c | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index 6e153e3..9ebcc23 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -52,7 +52,7 @@ struct xfs_da_geometry { enum xfs_dacmp { XFS_CMP_DIFFERENT, /* names are completely different */ XFS_CMP_EXACT, /* names are exactly the same */ - XFS_CMP_CASE /* names are same but differ in case */ + XFS_CMP_MATCH /* names are same but differ in encoding */ }; /* diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 6cef221..32e769b 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -74,7 +74,7 @@ xfs_ascii_ci_compname( continue; if (tolower(args->name[i]) != tolower(name[i])) return XFS_CMP_DIFFERENT; - result = XFS_CMP_CASE; + result = XFS_CMP_MATCH; } return result; @@ -315,8 +315,11 @@ xfs_dir_cilookup_result( { if (args->cmpresult == XFS_CMP_DIFFERENT) return -ENOENT; - if (args->cmpresult != XFS_CMP_CASE || - !(args->op_flags & XFS_DA_OP_CILOOKUP)) + if (args->cmpresult == XFS_CMP_EXACT) + return -EEXIST; + ASSERT(args->cmpresult == XFS_CMP_MATCH); + /* Only dup the found name if XFS_DA_OP_CILOOKUP is set. */ + if (!(args->op_flags & XFS_DA_OP_CILOOKUP)) return -EEXIST; args->value = kmem_alloc(len, KM_NOFS | KM_MAYFAIL); diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 1778c40..9d46e8d 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -2023,7 +2023,7 @@ xfs_dir2_node_lookup( error = xfs_da3_node_lookup_int(state, &rval); if (error) rval = error; - else if (rval == -ENOENT && args->cmpresult == XFS_CMP_CASE) { + else if (rval == -ENOENT && args->cmpresult == XFS_CMP_MATCH) { /* If a CI match, dup the actual name and return -EEXIST */ xfs_dir2_data_entry_t *dep; -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:09:58 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6FF227F37 for ; Thu, 18 Sep 2014 15:09:58 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id E58A9AC003; Thu, 18 Sep 2014 13:09:57 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id A6A794266DC; Thu, 18 Sep 2014 15:09:57 -0500 (CDT) Date: Thu, 18 Sep 2014 15:09:57 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 03/13] libxfs: add xfs_nameops.normhash Message-ID: <20140918200957.GE4482@sgi.com> References: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918195650.GI19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Add a normhash callout to the xfs_nameops. This callout takes an xfs_da_args structure as its argument, and calculates a hash value over the name. It may in the process create a normalized form of the name, and assign that to the norm/normlen fields in the xfs_da_args structure. Changes: The pointer in kmem_free() was type converted to suppress compiler warnings. Signed-off-by: Olaf Weber --- include/xfs_da_btree.h | 5 ++++- libxfs/xfs_da_btree.c | 9 ++++++++ libxfs/xfs_dir2.c | 56 +++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/include/xfs_da_btree.h b/include/xfs_da_btree.h index 3d9f9dd..06b50bf 100644 --- a/include/xfs_da_btree.h +++ b/include/xfs_da_btree.h @@ -42,7 +42,9 @@ enum xfs_dacmp { */ typedef struct xfs_da_args { const __uint8_t *name; /* string (maybe not NULL terminated) */ - int namelen; /* length of string (maybe no NULL) */ + const __uint8_t *norm; /* normalized name (may be NULL) */ + int namelen; /* length of string (maybe no NULL) */ + int normlen; /* length of normalized name */ __uint8_t filetype; /* filetype of inode for directories */ __uint8_t *value; /* set of bytes (maybe contain NULLs) */ int valuelen; /* length of value */ @@ -131,6 +133,7 @@ typedef struct xfs_da_state { */ struct xfs_nameops { xfs_dahash_t (*hashname)(struct xfs_name *); + int (*normhash)(struct xfs_da_args *); enum xfs_dacmp (*compname)(struct xfs_da_args *, const unsigned char *, int); }; diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c index b731b54..eb97317 100644 --- a/libxfs/xfs_da_btree.c +++ b/libxfs/xfs_da_btree.c @@ -2000,8 +2000,17 @@ xfs_default_hashname( return xfs_da_hashname(name->name, name->len); } +STATIC int +xfs_da_normhash( + struct xfs_da_args *args) +{ + args->hashval = xfs_da_hashname(args->name, args->namelen); + return 0; +} + const struct xfs_nameops xfs_default_nameops = { .hashname = xfs_default_hashname, + .normhash = xfs_da_normhash, .compname = xfs_da_compname }; diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index 57e98a3..e52d082 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -54,6 +54,21 @@ xfs_ascii_ci_hashname( return hash; } +STATIC int +xfs_ascii_ci_normhash( + struct xfs_da_args *args) +{ + xfs_dahash_t hash; + int i; + + for (i = 0, hash = 0; i < args->namelen; i++) + hash = tolower(args->name[i]) ^ rol32(hash, 7); + + args->hashval = hash; + return 0; +} + + STATIC enum xfs_dacmp xfs_ascii_ci_compname( struct xfs_da_args *args, @@ -80,6 +95,7 @@ xfs_ascii_ci_compname( static struct xfs_nameops xfs_ascii_ci_nameops = { .hashname = xfs_ascii_ci_hashname, + .normhash = xfs_ascii_ci_normhash, .compname = xfs_ascii_ci_compname, }; @@ -211,7 +227,6 @@ xfs_dir_createname( args.name = name->name; args.namelen = name->len; args.filetype = name->type; - args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = inum; args.dp = dp; args.firstblock = first; @@ -220,19 +235,24 @@ xfs_dir_createname( args.whichfork = XFS_DATA_FORK; args.trans = tp; args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; + if ((rval = dp->i_mount->m_dirnameops->normhash(&args))) + return rval; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_addname(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_block_addname(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_leaf_addname(&args); else rval = xfs_dir2_node_addname(&args); +out_free: + if (args.norm) + kmem_free((void *)args.norm); return rval; } @@ -289,22 +309,23 @@ xfs_dir_lookup( args.name = name->name; args.namelen = name->len; args.filetype = name->type; - args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.dp = dp; args.whichfork = XFS_DATA_FORK; args.trans = tp; args.op_flags = XFS_DA_OP_OKNOENT; if (ci_name) args.op_flags |= XFS_DA_OP_CILOOKUP; + if ((rval = dp->i_mount->m_dirnameops->normhash(&args))) + return rval; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_lookup(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_block_lookup(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_leaf_lookup(&args); else @@ -318,6 +339,9 @@ xfs_dir_lookup( ci_name->len = args.valuelen; } } +out_free: + if (args.norm) + kmem_free((void *)args.norm); return rval; } @@ -345,7 +369,6 @@ xfs_dir_removename( args.name = name->name; args.namelen = name->len; args.filetype = name->type; - args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = ino; args.dp = dp; args.firstblock = first; @@ -353,19 +376,24 @@ xfs_dir_removename( args.total = total; args.whichfork = XFS_DATA_FORK; args.trans = tp; + if ((rval = dp->i_mount->m_dirnameops->normhash(&args))) + return rval; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_removename(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_block_removename(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_leaf_removename(&args); else rval = xfs_dir2_node_removename(&args); +out_free: + if (args.norm) + kmem_free((void *)args.norm); return rval; } @@ -395,7 +423,6 @@ xfs_dir_replace( args.name = name->name; args.namelen = name->len; args.filetype = name->type; - args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = inum; args.dp = dp; args.firstblock = first; @@ -403,19 +430,24 @@ xfs_dir_replace( args.total = total; args.whichfork = XFS_DATA_FORK; args.trans = tp; + if ((rval = dp->i_mount->m_dirnameops->normhash(&args))) + return rval; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_replace(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_block_replace(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_leaf_replace(&args); else rval = xfs_dir2_node_replace(&args); +out_free: + if (args.norm) + kmem_free((void *)args.norm); return rval; } -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:10:41 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 0BBC87F37 for ; Thu, 18 Sep 2014 15:10:41 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7EFEBAC002; Thu, 18 Sep 2014 13:10:40 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 2BE9F4266DC; Thu, 18 Sep 2014 15:10:40 -0500 (CDT) Date: Thu, 18 Sep 2014 15:10:40 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 04/10] xfs: change interface of xfs_nameops.normhash Message-ID: <20140918201040.GF4482@sgi.com> References: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918195650.GI19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber With the introduction of the xfs_nameops.normhash callout, all uses of the hashname callout now occur in places where an xfs_name structure must be explicitly created just to match the parameter passing convention of this callout. Change the arguments to a const unsigned char * and int instead. Signed-off-by: Olaf Weber --- fs/xfs/libxfs/xfs_da_btree.c | 9 +-------- fs/xfs/libxfs/xfs_da_btree.h | 2 +- fs/xfs/libxfs/xfs_dir2.c | 7 ++++--- fs/xfs/libxfs/xfs_dir2_block.c | 2 +- fs/xfs/libxfs/xfs_dir2_data.c | 3 ++- 5 files changed, 9 insertions(+), 14 deletions(-) diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 07a3acf..a0608ca 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -1983,13 +1983,6 @@ xfs_da_compname( XFS_CMP_EXACT : XFS_CMP_DIFFERENT; } -static xfs_dahash_t -xfs_default_hashname( - struct xfs_name *name) -{ - return xfs_da_hashname(name->name, name->len); -} - STATIC int xfs_da_normhash( struct xfs_da_args *args) @@ -1999,7 +1992,7 @@ xfs_da_normhash( } const struct xfs_nameops xfs_default_nameops = { - .hashname = xfs_default_hashname, + .hashname = xfs_da_hashname, .normhash = xfs_da_normhash, .compname = xfs_da_compname }; diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index 6cdafee..4d6b36f 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -151,7 +151,7 @@ typedef struct xfs_da_state { * Name ops for directory and/or attr name operations */ struct xfs_nameops { - xfs_dahash_t (*hashname)(struct xfs_name *); + xfs_dahash_t (*hashname)(const unsigned char *, int); int (*normhash)(struct xfs_da_args *); enum xfs_dacmp (*compname)(struct xfs_da_args *, const unsigned char *, int); diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 55733a6..84e5ca9 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -45,13 +45,14 @@ struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2, XFS_DIR3_FT_DIR }; */ STATIC xfs_dahash_t xfs_ascii_ci_hashname( - struct xfs_name *name) + const unsigned char *name, + int len) { xfs_dahash_t hash; int i; - for (i = 0, hash = 0; i < name->len; i++) - hash = tolower(name->name[i]) ^ rol32(hash, 7); + for (i = 0, hash = 0; i < len; i++) + hash = tolower(name[i]) ^ rol32(hash, 7); return hash; } diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 990bf0c..f93c141 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -1231,7 +1231,7 @@ xfs_dir2_sf_to_block( name.name = sfep->name; name.len = sfep->namelen; blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops-> - hashname(&name)); + hashname(sfep->name, sfep->namelen)); blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr( (char *)dep - (char *)hdr)); offset = (int)((char *)(tagp + 1) - (char *)hdr); diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index fdd803f..28c35cf 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -179,7 +179,8 @@ __xfs_dir3_data_check( ((char *)dep - (char *)hdr)); name.name = dep->name; name.len = dep->namelen; - hash = mp->m_dirnameops->hashname(&name); + hash = mp->m_dirnameops->hashname(dep->name, + dep->namelen); for (i = 0; i < be32_to_cpu(btp->count); i++) { if (be32_to_cpu(lep[i].address) == addr && be32_to_cpu(lep[i].hashval) == hash) -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:11:28 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 245087F37 for ; Thu, 18 Sep 2014 15:11:28 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id 83510AC002; Thu, 18 Sep 2014 13:11:27 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 35F9D4266DC; Thu, 18 Sep 2014 15:11:27 -0500 (CDT) Date: Thu, 18 Sep 2014 15:11:27 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 05/10] xfs: add a superblock feature bit to indicate UTF-8 support. Message-ID: <20140918201127.GG4482@sgi.com> References: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918195650.GI19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber When UTF-8 support is enabled, the xfs_dir_ci_inode_operations must be installed. Add xfs_sb_version_hasci(), which tests both the borgbit and the utf8bit, and returns true if at least one of them is set. Replace calls to xfs_sb_version_hasasciici() as needed. Signed-off-by: Olaf Weber --- fs/xfs/libxfs/xfs_sb.h | 24 +++++++++++++++++++++++- fs/xfs/xfs_fs.h | 1 + fs/xfs/xfs_fsops.c | 4 +++- fs/xfs/xfs_iops.c | 4 ++-- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h index 2e73970..525eacb 100644 --- a/fs/xfs/libxfs/xfs_sb.h +++ b/fs/xfs/libxfs/xfs_sb.h @@ -70,6 +70,7 @@ struct xfs_trans; #define XFS_SB_VERSION2_RESERVED4BIT 0x00000004 #define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ #define XFS_SB_VERSION2_PARENTBIT 0x00000010 /* parent pointers */ +#define XFS_SB_VERSION2_UTF8BIT 0x00000020 /* utf8 names */ #define XFS_SB_VERSION2_PROJID32BIT 0x00000080 /* 32 bit project id */ #define XFS_SB_VERSION2_CRCBIT 0x00000100 /* metadata CRCs */ #define XFS_SB_VERSION2_FTYPE 0x00000200 /* inode type in dir */ @@ -77,6 +78,7 @@ struct xfs_trans; #define XFS_SB_VERSION2_OKBITS \ (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \ XFS_SB_VERSION2_ATTR2BIT | \ + XFS_SB_VERSION2_UTF8BIT | \ XFS_SB_VERSION2_PROJID32BIT | \ XFS_SB_VERSION2_FTYPE) @@ -509,8 +511,10 @@ xfs_sb_has_ro_compat_feature( } #define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ +#define XFS_SB_FEAT_INCOMPAT_UTF8 (1 << 1) /* utf-8 name support */ #define XFS_SB_FEAT_INCOMPAT_ALL \ - (XFS_SB_FEAT_INCOMPAT_FTYPE) + (XFS_SB_FEAT_INCOMPAT_FTYPE | \ + XFS_SB_FEAT_INCOMPAT_UTF8) #define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool @@ -558,6 +562,24 @@ static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp) (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_FINOBT); } +static inline int xfs_sb_version_hasutf8(xfs_sb_t *sbp) +{ + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 && + xfs_sb_has_incompat_feature(sbp, XFS_SB_FEAT_INCOMPAT_UTF8)) || + (xfs_sb_version_hasmorebits(sbp) && + (sbp->sb_features2 & XFS_SB_VERSION2_UTF8BIT)); +} + +/* + * Special case: there are a number of places where we need to test + * both the borgbit and the utf8bit, and take the same action if + * either of those is set. + */ +static inline int xfs_sb_version_hasci(xfs_sb_t *sbp) +{ + return xfs_sb_version_hasasciici(sbp) || xfs_sb_version_hasutf8(sbp); +} + /* * end of superblock version macros */ diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index 18dc721..e845d75 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h @@ -239,6 +239,7 @@ typedef struct xfs_fsop_resblks { #define XFS_FSOP_GEOM_FLAGS_V5SB 0x8000 /* version 5 superblock */ #define XFS_FSOP_GEOM_FLAGS_FTYPE 0x10000 /* inode directory types */ #define XFS_FSOP_GEOM_FLAGS_FINOBT 0x20000 /* free inode btree */ +#define XFS_FSOP_GEOM_FLAGS_UTF8 0x40000 /* utf8 filenames */ /* * Minimum and maximum sizes need for growth checks. diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index f91de1e..1a83eef 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -103,7 +103,9 @@ xfs_fs_geometry( (xfs_sb_version_hasftype(&mp->m_sb) ? XFS_FSOP_GEOM_FLAGS_FTYPE : 0) | (xfs_sb_version_hasfinobt(&mp->m_sb) ? - XFS_FSOP_GEOM_FLAGS_FINOBT : 0); + XFS_FSOP_GEOM_FLAGS_FINOBT : 0) | + (xfs_sb_version_hasutf8(&mp->m_sb) ? + XFS_FSOP_GEOM_FLAGS_UTF8 : 0); geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ? mp->m_sb.sb_logsectsize : BBSIZE; geo->rtsectsize = mp->m_sb.sb_blocksize; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 7212949..cea3d64 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -335,9 +335,9 @@ xfs_vn_unlink( /* * With unlink, the VFS makes the dentry "negative": no inode, * but still hashed. This is incompatible with case-insensitive - * mode, so invalidate (unhash) the dentry in CI-mode. + * or utf8 mode, so invalidate (unhash) the dentry in CI-mode. */ - if (xfs_sb_version_hasasciici(&XFS_M(dir->i_sb)->m_sb)) + if (xfs_sb_version_hasci(&XFS_M(dir->i_sb)->m_sb)) d_invalidate(dentry); return 0; } -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:13:36 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 4E2797F37 for ; Thu, 18 Sep 2014 15:13:36 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1D8B6304032; Thu, 18 Sep 2014 13:13:33 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id DC61C4266DC; Thu, 18 Sep 2014 15:13:32 -0500 (CDT) Date: Thu, 18 Sep 2014 15:13:32 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 03/10] xfs: add xfs_nameops.normhash Message-ID: <20140918201332.GH4482@sgi.com> References: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918195650.GI19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Add a normhash callout to the xfs_nameops. This callout takes an xfs_da_args structure as its argument, and calculates a hash value over the name. It may in the process create a normalized form of the name, and assign that to the norm/normlen fields in the xfs_da_args structure. Signed-off-by: Olaf Weber --- fs/xfs/libxfs/xfs_da_btree.c | 9 +++++++++ fs/xfs/libxfs/xfs_da_btree.h | 3 +++ fs/xfs/libxfs/xfs_dir2.c | 42 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 2c42ae2..07a3acf 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -1990,8 +1990,17 @@ xfs_default_hashname( return xfs_da_hashname(name->name, name->len); } +STATIC int +xfs_da_normhash( + struct xfs_da_args *args) +{ + args->hashval = xfs_da_hashname(args->name, args->namelen); + return 0; +} + const struct xfs_nameops xfs_default_nameops = { .hashname = xfs_default_hashname, + .normhash = xfs_da_normhash, .compname = xfs_da_compname }; diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index 9ebcc23..6cdafee 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -61,7 +61,9 @@ enum xfs_dacmp { typedef struct xfs_da_args { struct xfs_da_geometry *geo; /* da block geometry */ const __uint8_t *name; /* string (maybe not NULL terminated) */ + const __uint8_t *norm; /* normalized name (may be NULL) */ int namelen; /* length of string (maybe no NULL) */ + int normlen; /* length of normalized name */ __uint8_t filetype; /* filetype of inode for directories */ __uint8_t *value; /* set of bytes (maybe contain NULLs) */ int valuelen; /* length of value */ @@ -150,6 +152,7 @@ typedef struct xfs_da_state { */ struct xfs_nameops { xfs_dahash_t (*hashname)(struct xfs_name *); + int (*normhash)(struct xfs_da_args *); enum xfs_dacmp (*compname)(struct xfs_da_args *, const unsigned char *, int); }; diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 32e769b..55733a6 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -56,6 +56,21 @@ xfs_ascii_ci_hashname( return hash; } +STATIC int +xfs_ascii_ci_normhash( + struct xfs_da_args *args) +{ + xfs_dahash_t hash; + int i; + + for (i = 0, hash = 0; i < args->namelen; i++) + hash = tolower(args->name[i]) ^ rol32(hash, 7); + + args->hashval = hash; + return 0; +} + + STATIC enum xfs_dacmp xfs_ascii_ci_compname( struct xfs_da_args *args, @@ -82,6 +97,7 @@ xfs_ascii_ci_compname( static struct xfs_nameops xfs_ascii_ci_nameops = { .hashname = xfs_ascii_ci_hashname, + .normhash = xfs_ascii_ci_normhash, .compname = xfs_ascii_ci_compname, }; @@ -267,7 +283,6 @@ xfs_dir_createname( args->name = name->name; args->namelen = name->len; args->filetype = name->type; - args->hashval = dp->i_mount->m_dirnameops->hashname(name); args->inumber = inum; args->dp = dp; args->firstblock = first; @@ -276,6 +291,8 @@ xfs_dir_createname( args->whichfork = XFS_DATA_FORK; args->trans = tp; args->op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; + if ((rval = dp->i_mount->m_dirnameops->normhash(args))) + goto out_free; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_addname(args); @@ -299,6 +316,8 @@ xfs_dir_createname( rval = xfs_dir2_node_addname(args); out_free: + if (args->norm) + kmem_free(args->norm); kmem_free(args); return rval; } @@ -365,13 +384,14 @@ xfs_dir_lookup( args->name = name->name; args->namelen = name->len; args->filetype = name->type; - args->hashval = dp->i_mount->m_dirnameops->hashname(name); args->dp = dp; args->whichfork = XFS_DATA_FORK; args->trans = tp; args->op_flags = XFS_DA_OP_OKNOENT; if (ci_name) args->op_flags |= XFS_DA_OP_CILOOKUP; + if ((rval = dp->i_mount->m_dirnameops->normhash(args))) + goto out_free; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_lookup(args); @@ -405,6 +425,9 @@ out_check_rval: } } out_free: + if (args->norm) + kmem_free(args->norm); + kmem_free(args); return rval; } @@ -437,7 +460,6 @@ xfs_dir_removename( args->name = name->name; args->namelen = name->len; args->filetype = name->type; - args->hashval = dp->i_mount->m_dirnameops->hashname(name); args->inumber = ino; args->dp = dp; args->firstblock = first; @@ -445,6 +467,8 @@ xfs_dir_removename( args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; + if ((rval = dp->i_mount->m_dirnameops->normhash(args))) + goto out_free; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_removename(args); @@ -467,6 +491,8 @@ xfs_dir_removename( else rval = xfs_dir2_node_removename(args); out_free: + if (args->norm) + kmem_free(args->norm); kmem_free(args); return rval; } @@ -502,7 +528,6 @@ xfs_dir_replace( args->name = name->name; args->namelen = name->len; args->filetype = name->type; - args->hashval = dp->i_mount->m_dirnameops->hashname(name); args->inumber = inum; args->dp = dp; args->firstblock = first; @@ -510,6 +535,8 @@ xfs_dir_replace( args->total = total; args->whichfork = XFS_DATA_FORK; args->trans = tp; + if ((rval = dp->i_mount->m_dirnameops->normhash(args))) + goto out_free; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_replace(args); @@ -532,6 +559,8 @@ xfs_dir_replace( else rval = xfs_dir2_node_replace(args); out_free: + if (args->norm) + kmem_free(args->norm); kmem_free(args); return rval; } @@ -564,12 +593,13 @@ xfs_dir_canenter( args->name = name->name; args->namelen = name->len; args->filetype = name->type; - args->hashval = dp->i_mount->m_dirnameops->hashname(name); args->dp = dp; args->whichfork = XFS_DATA_FORK; args->trans = tp; args->op_flags = XFS_DA_OP_JUSTCHECK | XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; + if ((rval = dp->i_mount->m_dirnameops->normhash(args))) + goto out_free; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) { rval = xfs_dir2_sf_addname(args); @@ -592,6 +622,8 @@ xfs_dir_canenter( else rval = xfs_dir2_node_addname(args); out_free: + if (args->norm) + kmem_free(args->norm); kmem_free(args); return rval; } -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:14:41 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 2225F7F37 for ; Thu, 18 Sep 2014 15:14:41 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay2.corp.sgi.com (Postfix) with ESMTP id 05FFB304039; Thu, 18 Sep 2014 13:14:41 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id CACEF4266DC; Thu, 18 Sep 2014 15:14:40 -0500 (CDT) Date: Thu, 18 Sep 2014 15:14:40 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 06/10] xfs: add unicode character database files Message-ID: <20140918201440.GI4482@sgi.com> References: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918195650.GI19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Add files from the Unicode Character Database, version 7.0.0, to the source. A helper program that generates a trie used for normalization from these files is part of a separate commit. Signed-off-by: Olaf Weber --- [v2: Removed large unicode files prior to posting. Get them as below. -bpm] [v3: Moved files to ucd8norm directory. -bpm] cd fs/xfs/utf8norm/ucd wget http://www.unicode.org/Public/7.0.0/ucd/CaseFolding.txt wget http://www.unicode.org/Public/7.0.0/ucd/DerivedAge.txt wget http://www.unicode.org/Public/7.0.0/ucd/extracted/DerivedCombiningClass.txt wget http://www.unicode.org/Public/7.0.0/ucd/DerivedCoreProperties.txt wget http://www.unicode.org/Public/7.0.0/ucd/NormalizationCorrections.txt wget http://www.unicode.org/Public/7.0.0/ucd/NormalizationTest.txt wget http://www.unicode.org/Public/7.0.0/ucd/UnicodeData.txt for e in *.txt do base=`basename $e .txt` mv $e $base-7.0.0.txt done --- fs/xfs/utf8norm/ucd/README | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 fs/xfs/utf8norm/ucd/README diff --git a/fs/xfs/utf8norm/ucd/README b/fs/xfs/utf8norm/ucd/README new file mode 100644 index 0000000..d713e66 --- /dev/null +++ b/fs/xfs/utf8norm/ucd/README @@ -0,0 +1,33 @@ +The files in this directory are part of the Unicode Character Database +for version 7.0.0 of the Unicode standard. + +The full set of files can be found here: + + http://www.unicode.org/Public/7.0.0/ucd/ + +The latest released version of the UCD can be found here: + + http://www.unicode.org/Public/UCD/latest/ + +The files in this directory are identical, except that they have been +renamed with a suffix indicating the unicode version. + +Individual source links: + + http://www.unicode.org/Public/7.0.0/ucd/CaseFolding.txt + http://www.unicode.org/Public/7.0.0/ucd/DerivedAge.txt + http://www.unicode.org/Public/7.0.0/ucd/extracted/DerivedCombiningClass.txt + http://www.unicode.org/Public/7.0.0/ucd/DerivedCoreProperties.txt + http://www.unicode.org/Public/7.0.0/ucd/NormalizationCorrections.txt + http://www.unicode.org/Public/7.0.0/ucd/NormalizationTest.txt + http://www.unicode.org/Public/7.0.0/ucd/UnicodeData.txt + +md5sums + + 9a92b2bfe56c6719def926bab524fefd CaseFolding-7.0.0.txt + 07b8b1027eb824cf0835314e94f23d2e DerivedAge-7.0.0.txt + 90c3340b16821e2f2153acdbe6fc6180 DerivedCombiningClass-7.0.0.txt + c41c0601f808116f623de47110ed4f93 DerivedCoreProperties-7.0.0.txt + 522720ddfc150d8e63a2518634829bce NormalizationCorrections-7.0.0.txt + 1f35175eba4a2ad795db489f789ae352 NormalizationTest-7.0.0.txt + c8355655731d75e6a3de8c20d7e601ba UnicodeData-7.0.0.txt -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:15:20 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD, T_FILL_THIS_FORM_SHORT autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 1B0BC7F37 for ; Thu, 18 Sep 2014 15:15:20 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay2.corp.sgi.com (Postfix) with ESMTP id BFFA5304032; Thu, 18 Sep 2014 13:15:19 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 103D94266DC; Thu, 18 Sep 2014 15:15:19 -0500 (CDT) Date: Thu, 18 Sep 2014 15:15:19 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 07/10] xfs: add trie generator and supporting code for UTF-8. Message-ID: <20140918201518.GJ4482@sgi.com> References: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918195650.GI19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber mkutf8data.c is the source for a program that generates utf8data.h, which contains the trie that utf8norm.c uses. The trie is generated from the Unicode 7.0.0 data files. The format of the utf8data[] table is described in utf8norm.c. Supporting functions for UTF-8 normalization are in utf8norm.c with the header utf8norm.h. Two normalization forms are supported: nfkdi and nfkdicf. nfkdi: - Apply unicode normalization form NFKD. - Remove any Default_Ignorable_Code_Point. nfkdicf: - Apply unicode normalization form NFKD. - Remove any Default_Ignorable_Code_Point. - Apply a full casefold (C + F). For the purposes of the code, a string is valid UTF-8 if: - The values encoded are 0x1..0x10FFFF. - The surrogate codepoints 0xD800..0xDFFFF are not encoded. - The shortest possible encoding is used for all values. The supporting functions work on null-terminated strings (utf8 prefix) and on length-limited strings (utf8n prefix). Signed-off-by: Olaf Weber --- [v2: the trie is now separated into utf8norm.ko; utf8version is now a function and exported; introduced CONFIG_XFS_UTF8. -bpm] --- fs/xfs/Kconfig | 8 + fs/xfs/Makefile | 2 +- fs/xfs/utf8norm/Makefile | 37 + fs/xfs/utf8norm/mkutf8data.c | 3239 ++++++++++++++++++++++++++++++++++++++++++ fs/xfs/utf8norm/utf8norm.c | 649 +++++++++ fs/xfs/utf8norm/utf8norm.h | 116 ++ 6 files changed, 4050 insertions(+), 1 deletion(-) create mode 100644 fs/xfs/utf8norm/Makefile create mode 100644 fs/xfs/utf8norm/mkutf8data.c create mode 100644 fs/xfs/utf8norm/utf8norm.c create mode 100644 fs/xfs/utf8norm/utf8norm.h diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig index 5d47b4d..a847857 100644 --- a/fs/xfs/Kconfig +++ b/fs/xfs/Kconfig @@ -95,3 +95,11 @@ config XFS_DEBUG not useful unless you are debugging a particular problem. Say N unless you are an XFS developer, or you play one on TV. + +config XFS_UTF8 + bool "XFS UTF-8 support" + depends on XFS_FS + help + Say Y here to enable utf8 normalization support in XFS. You + will be able to mount and use filesystems created with the + utf8 mkfs.xfs option. diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index d617999..6d000d3 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -21,7 +21,7 @@ ccflags-y += -I$(src)/libxfs ccflags-$(CONFIG_XFS_DEBUG) += -g -obj-$(CONFIG_XFS_FS) += xfs.o +obj-$(CONFIG_XFS_FS) += xfs.o utf8norm/ # this one should be compiled first, as the tracing macros can easily blow up xfs-y += xfs_trace.o diff --git a/fs/xfs/utf8norm/Makefile b/fs/xfs/utf8norm/Makefile new file mode 100644 index 0000000..f83f9b9 --- /dev/null +++ b/fs/xfs/utf8norm/Makefile @@ -0,0 +1,37 @@ +# +# Copyright (c) 2014 SGI. +# All rights reserved. +# +# This program 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. +# +# This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +ifeq ($(CONFIG_XFS_UTF8),y) +obj-m += utf8norm.o +endif + +hostprogs-y := mkutf8data +$(obj)/utf8norm.o: $(obj)/utf8data.h +$(obj)/utf8data.h: $(src)/ucd/*.txt +$(obj)/utf8data.h: $(obj)/mkutf8data FORCE + $(call if_changed,mkutf8data) +quiet_cmd_mkutf8data = MKUTF8DATA $@ + cmd_mkutf8data = $(obj)/mkutf8data \ + -a $(src)/ucd/DerivedAge-7.0.0.txt \ + -c $(src)/ucd/DerivedCombiningClass-7.0.0.txt \ + -p $(src)/ucd/DerivedCoreProperties-7.0.0.txt \ + -d $(src)/ucd/UnicodeData-7.0.0.txt \ + -f $(src)/ucd/CaseFolding-7.0.0.txt \ + -n $(src)/ucd/NormalizationCorrections-7.0.0.txt \ + -t $(src)/ucd/NormalizationTest-7.0.0.txt \ + -o $@ diff --git a/fs/xfs/utf8norm/mkutf8data.c b/fs/xfs/utf8norm/mkutf8data.c new file mode 100644 index 0000000..1d6ec02 --- /dev/null +++ b/fs/xfs/utf8norm/mkutf8data.c @@ -0,0 +1,3239 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Generator for a compact trie for unicode normalization */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Default names of the in- and output files. */ + +#define AGE_NAME "DerivedAge.txt" +#define CCC_NAME "DerivedCombiningClass.txt" +#define PROP_NAME "DerivedCoreProperties.txt" +#define DATA_NAME "UnicodeData.txt" +#define FOLD_NAME "CaseFolding.txt" +#define NORM_NAME "NormalizationCorrections.txt" +#define TEST_NAME "NormalizationTest.txt" +#define UTF8_NAME "utf8data.h" + +const char *age_name = AGE_NAME; +const char *ccc_name = CCC_NAME; +const char *prop_name = PROP_NAME; +const char *data_name = DATA_NAME; +const char *fold_name = FOLD_NAME; +const char *norm_name = NORM_NAME; +const char *test_name = TEST_NAME; +const char *utf8_name = UTF8_NAME; + +int verbose = 0; + +/* An arbitrary line size limit on input lines. */ + +#define LINESIZE 1024 +char line[LINESIZE]; +char buf0[LINESIZE]; +char buf1[LINESIZE]; +char buf2[LINESIZE]; +char buf3[LINESIZE]; + +const char *argv0; + +/* ------------------------------------------------------------------ */ + +/* + * Unicode version numbers consist of three parts: major, minor, and a + * revision. These numbers are packed into an unsigned int to obtain + * a single version number. + * + * To save space in the generated trie, the unicode version is not + * stored directly, instead we calculate a generation number from the + * unicode versions seen in the DerivedAge file, and use that as an + * index into a table of unicode versions. + */ +#define UNICODE_MAJ_SHIFT (16) +#define UNICODE_MIN_SHIFT (8) + +#define UNICODE_MAJ_MAX ((unsigned short)-1) +#define UNICODE_MIN_MAX ((unsigned char)-1) +#define UNICODE_REV_MAX ((unsigned char)-1) + +#define UNICODE_AGE(MAJ,MIN,REV) \ + (((unsigned int)(MAJ) << UNICODE_MAJ_SHIFT) | \ + ((unsigned int)(MIN) << UNICODE_MIN_SHIFT) | \ + ((unsigned int)(REV))) + +unsigned int *ages; +int ages_count; + +unsigned int unicode_maxage; + +static int +age_valid(unsigned int major, unsigned int minor, unsigned int revision) +{ + if (major > UNICODE_MAJ_MAX) + return 0; + if (minor > UNICODE_MIN_MAX) + return 0; + if (revision > UNICODE_REV_MAX) + return 0; + return 1; +} + +/* ------------------------------------------------------------------ */ + +/* + * utf8trie_t + * + * A compact binary tree, used to decode UTF-8 characters. + * + * Internal nodes are one byte for the node itself, and up to three + * bytes for an offset into the tree. The first byte contains the + * following information: + * NEXTBYTE - flag - advance to next byte if set + * BITNUM - 3 bit field - the bit number to tested + * OFFLEN - 2 bit field - number of bytes in the offset + * if offlen == 0 (non-branching node) + * RIGHTPATH - 1 bit field - set if the following node is for the + * right-hand path (tested bit is set) + * TRIENODE - 1 bit field - set if the following node is an internal + * node, otherwise it is a leaf node + * if offlen != 0 (branching node) + * LEFTNODE - 1 bit field - set if the left-hand node is internal + * RIGHTNODE - 1 bit field - set if the right-hand node is internal + * + * Due to the way utf8 works, there cannot be branching nodes with + * NEXTBYTE set, and moreover those nodes always have a righthand + * descendant. + */ +typedef unsigned char utf8trie_t; +#define BITNUM 0x07 +#define NEXTBYTE 0x08 +#define OFFLEN 0x30 +#define OFFLEN_SHIFT 4 +#define RIGHTPATH 0x40 +#define TRIENODE 0x80 +#define RIGHTNODE 0x40 +#define LEFTNODE 0x80 + +/* + * utf8leaf_t + * + * The leaves of the trie are embedded in the trie, and so the same + * underlying datatype, unsigned char. + * + * leaf[0]: The unicode version, stored as a generation number that is + * an index into utf8agetab[]. With this we can filter code + * points based on the unicode version in which they were + * defined. The CCC of a non-defined code point is 0. + * leaf[1]: Canonical Combining Class. During normalization, we need + * to do a stable sort into ascending order of all characters + * with a non-zero CCC that occur between two characters with + * a CCC of 0, or at the begin or end of a string. + * The unicode standard guarantees that all CCC values are + * between 0 and 254 inclusive, which leaves 255 available as + * a special value. + * Code points with CCC 0 are known as stoppers. + * leaf[2]: Decomposition. If leaf[1] == 255, then leaf[2] is the + * start of a NUL-terminated string that is the decomposition + * of the character. + * The CCC of a decomposable character is the same as the CCC + * of the first character of its decomposition. + * Some characters decompose as the empty string: these are + * characters with the Default_Ignorable_Code_Point property. + * These do affect normalization, as they all have CCC 0. + * + * The decompositions in the trie have been fully expanded. + * + * Casefolding, if applicable, is also done using decompositions. + */ +typedef unsigned char utf8leaf_t; + +#define LEAF_GEN(LEAF) ((LEAF)[0]) +#define LEAF_CCC(LEAF) ((LEAF)[1]) +#define LEAF_STR(LEAF) ((const char*)((LEAF) + 2)) + +#define MAXGEN (255) + +#define MINCCC (0) +#define MAXCCC (254) +#define STOPPER (0) +#define DECOMPOSE (255) + +struct tree; +static utf8leaf_t *utf8nlookup(struct tree *, const char *, size_t); +static utf8leaf_t *utf8lookup(struct tree *, const char *); + +unsigned char *utf8data; +size_t utf8data_size; + +utf8trie_t *nfkdi; +utf8trie_t *nfkdicf; + +/* ------------------------------------------------------------------ */ + +/* + * UTF8 valid ranges. + * + * The UTF-8 encoding spreads the bits of a 32bit word over several + * bytes. This table gives the ranges that can be held and how they'd + * be represented. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000000 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000000 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * There is an additional requirement on UTF-8, in that only the + * shortest representation of a 32bit value is to be used. A decoder + * must not decode sequences that do not satisfy this requirement. + * Thus the allowed ranges have a lower bound. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000080 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000800 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00010000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00200000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x04000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Actual unicode characters are limited to the range 0x0 - 0x10FFFF, + * 17 planes of 65536 values. This limits the sequences actually seen + * even more, to just the following. + * + * 0 - 0x7f: 0 0x7f + * 0x80 - 0x7ff: 0xc2 0x80 0xdf 0xbf + * 0x800 - 0xffff: 0xe0 0xa0 0x80 0xef 0xbf 0xbf + * 0x10000 - 0x10ffff: 0xf0 0x90 0x80 0x80 0xf4 0x8f 0xbf 0xbf + * + * Even within those ranges not all values are allowed: the surrogates + * 0xd800 - 0xdfff should never be seen. + * + * Note that the longest sequence seen with valid usage is 4 bytes, + * the same a single UTF-32 character. This makes the UTF-8 + * representation of Unicode strictly smaller than UTF-32. + * + * The shortest sequence requirement was introduced by: + * Corrigendum #1: UTF-8 Shortest Form + * It can be found here: + * http://www.unicode.org/versions/corrigendum1.html + * + */ + +#define UTF8_2_BITS 0xC0 +#define UTF8_3_BITS 0xE0 +#define UTF8_4_BITS 0xF0 +#define UTF8_N_BITS 0x80 +#define UTF8_2_MASK 0xE0 +#define UTF8_3_MASK 0xF0 +#define UTF8_4_MASK 0xF8 +#define UTF8_N_MASK 0xC0 +#define UTF8_V_MASK 0x3F +#define UTF8_V_SHIFT 6 + +static int +utf8key(unsigned int key, char keyval[]) +{ + int keylen; + + if (key < 0x80) { + keyval[0] = key; + keylen = 1; + } else if (key < 0x800) { + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_2_BITS; + keylen = 2; + } else if (key < 0x10000) { + keyval[2] = key & UTF8_V_MASK; + keyval[2] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_3_BITS; + keylen = 3; + } else if (key < 0x110000) { + keyval[3] = key & UTF8_V_MASK; + keyval[3] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[2] = key & UTF8_V_MASK; + keyval[2] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_4_BITS; + keylen = 4; + } else { + printf("%#x: illegal key\n", key); + keylen = 0; + } + return keylen; +} + +static unsigned int +utf8code(const char *str) +{ + const unsigned char *s = (const unsigned char*)str; + unsigned int unichar = 0; + + if (*s < 0x80) { + unichar = *s; + } else if (*s < UTF8_3_BITS) { + unichar = *s++ & 0x1F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } else if (*s < UTF8_4_BITS) { + unichar = *s++ & 0x0F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } else { + unichar = *s++ & 0x0F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } + return unichar; +} + +static int +utf32valid(unsigned int unichar) +{ + return unichar < 0x110000; +} + +#define NODE 1 +#define LEAF 0 + +struct tree { + void *root; + int childnode; + const char *type; + unsigned int maxage; + struct tree *next; + int (*leaf_equal)(void *, void *); + void (*leaf_print)(void *, int); + int (*leaf_mark)(void *); + int (*leaf_size)(void *); + int *(*leaf_index)(struct tree *, void *); + unsigned char *(*leaf_emit)(void *, unsigned char *); + int leafindex[0x110000]; + int index; +}; + +struct node { + int index; + int offset; + int mark; + int size; + struct node *parent; + void *left; + void *right; + unsigned char bitnum; + unsigned char nextbyte; + unsigned char leftnode; + unsigned char rightnode; + unsigned int keybits; + unsigned int keymask; +}; + +/* + * Example lookup function for a tree. + */ +static void * +lookup(struct tree *tree, const char *key) +{ + struct node *node; + void *leaf = NULL; + + node = tree->root; + while (!leaf && node) { + if (node->nextbyte) + key++; + if (*key & (1 << (node->bitnum & 7))) { + /* Right leg */ + if (node->rightnode == NODE) { + node = node->right; + } else if (node->rightnode == LEAF) { + leaf = node->right; + } else { + node = NULL; + } + } else { + /* Left leg */ + if (node->leftnode == NODE) { + node = node->left; + } else if (node->leftnode == LEAF) { + leaf = node->left; + } else { + node = NULL; + } + } + } + + return leaf; +} + +/* + * A simple non-recursive tree walker: keep track of visits to the + * left and right branches in the leftmask and rightmask. + */ +static void +tree_walk(struct tree *tree) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int indent = 1; + int nodes, singletons, leaves; + + nodes = singletons = leaves = 0; + + printf("%s_%x root %p\n", tree->type, tree->maxage, tree->root); + if (tree->childnode == LEAF) { + assert(tree->root); + tree->leaf_print(tree->root, indent); + leaves = 1; + } else { + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + printf("%*snode @ %p bitnum %d nextbyte %d" + " left %p right %p mask %x bits %x\n", + indent, "", node, + node->bitnum, node->nextbyte, + node->left, node->right, + node->keymask, node->keybits); + nodes += 1; + if (!(node->left && node->right)) + singletons += 1; + + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + tree->leaf_print(node->left, + indent+1); + leaves += 1; + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + tree->leaf_print(node->right, + indent+1); + leaves += 1; + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } + } + printf("nodes %d leaves %d singletons %d\n", + nodes, leaves, singletons); +} + +/* + * Allocate an initialize a new internal node. + */ +static struct node * +alloc_node(struct node *parent) +{ + struct node *node; + int bitnum; + + node = malloc(sizeof(*node)); + node->left = node->right = NULL; + node->parent = parent; + node->leftnode = NODE; + node->rightnode = NODE; + node->keybits = 0; + node->keymask = 0; + node->mark = 0; + node->index = 0; + node->offset = -1; + node->size = 4; + + if (node->parent) { + bitnum = parent->bitnum; + if ((bitnum & 7) == 0) { + node->bitnum = bitnum + 7 + 8; + node->nextbyte = 1; + } else { + node->bitnum = bitnum - 1; + node->nextbyte = 0; + } + } else { + node->bitnum = 7; + node->nextbyte = 0; + } + + return node; +} + +/* + * Insert a new leaf into the tree, and collapse any subtrees that are + * fully populated and end in identical leaves. A nextbyte tagged + * internal node will not be removed to preserve the tree's integrity. + * Note that due to the structure of utf8, no nextbyte tagged node + * will be a candidate for removal. + */ +static int +insert(struct tree *tree, char *key, int keylen, void *leaf) +{ + struct node *node; + struct node *parent; + void **cursor; + int keybits; + + assert(keylen >= 1 && keylen <= 4); + + node = NULL; + cursor = &tree->root; + keybits = 8 * keylen; + + /* Insert, creating path along the way. */ + while (keybits) { + if (!*cursor) + *cursor = alloc_node(node); + node = *cursor; + if (node->nextbyte) + key++; + if (*key & (1 << (node->bitnum & 7))) + cursor = &node->right; + else + cursor = &node->left; + keybits--; + } + *cursor = leaf; + + /* Merge subtrees if possible. */ + while (node) { + if (*key & (1 << (node->bitnum & 7))) + node->rightnode = LEAF; + else + node->leftnode = LEAF; + if (node->nextbyte) + break; + if (node->leftnode == NODE || node->rightnode == NODE) + break; + assert(node->left); + assert(node->right); + /* Compare */ + if (! tree->leaf_equal(node->left, node->right)) + break; + /* Keep left, drop right leaf. */ + leaf = node->left; + /* Check in parent */ + parent = node->parent; + if (!parent) { + /* root of tree! */ + tree->root = leaf; + tree->childnode = LEAF; + } else if (parent->left == node) { + parent->left = leaf; + parent->leftnode = LEAF; + if (parent->right) { + parent->keymask = 0; + parent->keybits = 0; + } else { + parent->keymask |= (1 << node->bitnum); + } + } else if (parent->right == node) { + parent->right = leaf; + parent->rightnode = LEAF; + if (parent->left) { + parent->keymask = 0; + parent->keybits = 0; + } else { + parent->keymask |= (1 << node->bitnum); + parent->keybits |= (1 << node->bitnum); + } + } else { + /* internal tree error */ + assert(0); + } + free(node); + node = parent; + } + + /* Propagate keymasks up along singleton chains. */ + while (node) { + parent = node->parent; + if (!parent) + break; + /* Nix the mask for parents with two children. */ + if (node->keymask == 0) { + parent->keymask = 0; + parent->keybits = 0; + } else if (parent->left && parent->right) { + parent->keymask = 0; + parent->keybits = 0; + } else { + assert((parent->keymask & node->keymask) == 0); + parent->keymask |= node->keymask; + parent->keymask |= (1 << parent->bitnum); + parent->keybits |= node->keybits; + if (parent->right) + parent->keybits |= (1 << parent->bitnum); + } + node = parent; + } + + return 0; +} + +/* + * Prune internal nodes. + * + * Fully populated subtrees that end at the same leaf have already + * been collapsed. There are still internal nodes that have for both + * their left and right branches a sequence of singletons that make + * identical choices and end in identical leaves. The keymask and + * keybits collected in the nodes describe the choices made in these + * singleton chains. When they are identical for the left and right + * branch of a node, and the two leaves comare identical, the node in + * question can be removed. + * + * Note that nodes with the nextbyte tag set will not be removed by + * this to ensure tree integrity. Note as well that the structure of + * utf8 ensures that these nodes would not have been candidates for + * removal in any case. + */ +static void +prune(struct tree *tree) +{ + struct node *node; + struct node *left; + struct node *right; + struct node *parent; + void *leftleaf; + void *rightleaf; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int count; + + if (verbose > 0) + printf("Pruning %s_%x\n", tree->type, tree->maxage); + + count = 0; + if (tree->childnode == LEAF) + return; + if (!tree->root) + return; + + leftmask = rightmask = 0; + node = tree->root; + while (node) { + if (node->nextbyte) + goto advance; + if (node->leftnode == LEAF) + goto advance; + if (node->rightnode == LEAF) + goto advance; + if (!node->left) + goto advance; + if (!node->right) + goto advance; + left = node->left; + right = node->right; + if (left->keymask == 0) + goto advance; + if (right->keymask == 0) + goto advance; + if (left->keymask != right->keymask) + goto advance; + if (left->keybits != right->keybits) + goto advance; + leftleaf = NULL; + while (!leftleaf) { + assert(left->left || left->right); + if (left->leftnode == LEAF) + leftleaf = left->left; + else if (left->rightnode == LEAF) + leftleaf = left->right; + else if (left->left) + left = left->left; + else if (left->right) + left = left->right; + else + assert(0); + } + rightleaf = NULL; + while (!rightleaf) { + assert(right->left || right->right); + if (right->leftnode == LEAF) + rightleaf = right->left; + else if (right->rightnode == LEAF) + rightleaf = right->right; + else if (right->left) + right = right->left; + else if (right->right) + right = right->right; + else + assert(0); + } + if (! tree->leaf_equal(leftleaf, rightleaf)) + goto advance; + /* + * This node has identical singleton-only subtrees. + * Remove it. + */ + parent = node->parent; + left = node->left; + right = node->right; + if (parent->left == node) + parent->left = left; + else if (parent->right == node) + parent->right = left; + else + assert(0); + left->parent = parent; + left->keymask |= (1 << node->bitnum); + node->left = NULL; + while (node) { + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + if (node->leftnode == NODE && node->left) { + left = node->left; + free(node); + count++; + node = left; + } else if (node->rightnode == NODE && node->right) { + right = node->right; + free(node); + count++; + node = right; + } else { + node = NULL; + } + } + /* Propagate keymasks up along singleton chains. */ + node = parent; + /* Force re-check */ + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + for (;;) { + if (node->left && node->right) + break; + if (node->left) { + left = node->left; + node->keymask |= left->keymask; + node->keybits |= left->keybits; + } + if (node->right) { + right = node->right; + node->keymask |= right->keymask; + node->keybits |= right->keybits; + } + node->keymask |= (1 << node->bitnum); + node = node->parent; + /* Force re-check */ + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + } + advance: + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0 && + node->leftnode == NODE && + node->left) { + leftmask |= bitmask; + node = node->left; + } else if ((rightmask & bitmask) == 0 && + node->rightnode == NODE && + node->right) { + rightmask |= bitmask; + node = node->right; + } else { + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } + } + if (verbose > 0) + printf("Pruned %d nodes\n", count); +} + +/* + * Mark the nodes in the tree that lead to leaves that must be + * emitted. + */ +static void +mark_nodes(struct tree *tree) +{ + struct node *node; + struct node *n; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int marked; + + marked = 0; + if (verbose > 0) + printf("Marking %s_%x\n", tree->type, tree->maxage); + if (tree->childnode == LEAF) + goto done; + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + if (tree->leaf_mark(node->left)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->left) { + assert(node->leftnode == NODE); + node = node->left; + continue; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + if (tree->leaf_mark(node->right)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->right) { + assert(node->rightnode==NODE); + node = node->right; + continue; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } + + /* second pass: left siblings and singletons */ + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + if (tree->leaf_mark(node->left)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->left) { + assert(node->leftnode == NODE); + node = node->left; + if (!node->mark && node->parent->mark) { + marked++; + node->mark = 1; + } + continue; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + if (tree->leaf_mark(node->right)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->right) { + assert(node->rightnode==NODE); + node = node->right; + if (!node->mark && node->parent->mark && + !node->parent->left) { + marked++; + node->mark = 1; + } + continue; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } +done: + if (verbose > 0) + printf("Marked %d nodes\n", marked); +} + +/* + * Compute the index of each node and leaf, which is the offset in the + * emitted trie. These value must be pre-computed because relative + * offsets between nodes are used to navigate the tree. + */ +static int +index_nodes(struct tree *tree, int index) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int count; + int indent; + + /* Align to a cache line (or half a cache line?). */ + while (index % 64) + index++; + tree->index = index; + indent = 1; + count = 0; + + if (verbose > 0) + printf("Indexing %s_%x: %d", tree->type, tree->maxage, index); + if (tree->childnode == LEAF) { + index += tree->leaf_size(tree->root); + goto done; + } + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + count++; + if (node->index != index) + node->index = index; + index += node->size; +skip: + while (node) { + bitmask = 1 << node->bitnum; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + *tree->leaf_index(tree, node->left) = + index; + index += tree->leaf_size(node->left); + count++; + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + *tree->leaf_index(tree, node->right) = index; + index += tree->leaf_size(node->right); + count++; + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +done: + /* Round up to a multiple of 16 */ + while (index % 16) + index++; + if (verbose > 0) + printf("Final index %d\n", index); + return index; +} + +/* + * Compute the size of nodes and leaves. We start by assuming that + * each node needs to store a three-byte offset. The indexes of the + * nodes are calculated based on that, and then this function is + * called to see if the sizes of some nodes can be reduced. This is + * repeated until no more changes are seen. + */ +static int +size_nodes(struct tree *tree) +{ + struct tree *next; + struct node *node; + struct node *right; + struct node *n; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + unsigned int pathbits; + unsigned int pathmask; + int changed; + int offset; + int size; + int indent; + + indent = 1; + changed = 0; + size = 0; + + if (verbose > 0) + printf("Sizing %s_%x", tree->type, tree->maxage); + if (tree->childnode == LEAF) + goto done; + + assert(tree->childnode == NODE); + pathbits = 0; + pathmask = 0; + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + offset = 0; + if (!node->left || !node->right) { + size = 1; + } else { + if (node->rightnode == NODE) { + right = node->right; + next = tree->next; + while (!right->mark) { + assert(next); + n = next->root; + while (n->bitnum != node->bitnum) { + if (pathbits & (1<bitnum)) + n = n->right; + else + n = n->left; + } + n = n->right; + assert(right->bitnum == n->bitnum); + right = n; + next = next->next; + } + offset = right->index - node->index; + } else { + offset = *tree->leaf_index(tree, node->right); + offset -= node->index; + } + assert(offset >= 0); + assert(offset <= 0xffffff); + if (offset <= 0xff) { + size = 2; + } else if (offset <= 0xffff) { + size = 3; + } else { /* offset <= 0xffffff */ + size = 4; + } + } + if (node->size != size || node->offset != offset) { + node->size = size; + node->offset = offset; + changed++; + } +skip: + while (node) { + bitmask = 1 << node->bitnum; + pathmask |= bitmask; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + pathbits |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + pathmask &= ~bitmask; + pathbits &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +done: + if (verbose > 0) + printf("Found %d changes\n", changed); + return changed; +} + +/* + * Emit a trie for the given tree into the data array. + */ +static void +emit(struct tree *tree, unsigned char *data) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int offlen; + int offset; + int index; + int indent; + unsigned char byte; + + index = tree->index; + data += index; + indent = 1; + if (verbose > 0) + printf("Emitting %s_%x\n", tree->type, tree->maxage); + if (tree->childnode == LEAF) { + assert(tree->root); + tree->leaf_emit(tree->root, data); + return; + } + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + assert(node->offset != -1); + assert(node->index == index); + + byte = 0; + if (node->nextbyte) + byte |= NEXTBYTE; + byte |= (node->bitnum & BITNUM); + if (node->left && node->right) { + if (node->leftnode == NODE) + byte |= LEFTNODE; + if (node->rightnode == NODE) + byte |= RIGHTNODE; + if (node->offset <= 0xff) + offlen = 1; + else if (node->offset <= 0xffff) + offlen = 2; + else + offlen = 3; + offset = node->offset; + byte |= offlen << OFFLEN_SHIFT; + *data++ = byte; + index++; + while (offlen--) { + *data++ = offset & 0xff; + index++; + offset >>= 8; + } + } else if (node->left) { + if (node->leftnode == NODE) + byte |= TRIENODE; + *data++ = byte; + index++; + } else if (node->right) { + byte |= RIGHTNODE; + if (node->rightnode == NODE) + byte |= TRIENODE; + *data++ = byte; + index++; + } else { + assert(0); + } +skip: + while (node) { + bitmask = 1 << node->bitnum; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + data = tree->leaf_emit(node->left, + data); + index += tree->leaf_size(node->left); + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + data = tree->leaf_emit(node->right, + data); + index += tree->leaf_size(node->right); + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +} + +/* ------------------------------------------------------------------ */ + +/* + * Unicode data. + * + * We need to keep track of the Canonical Combining Class, the Age, + * and decompositions for a code point. + * + * For the Age, we store the index into the ages table. Effectively + * this is a generation number that the table maps to a unicode + * version. + * + * The correction field is used to indicate that this entry is in the + * corrections array, which contains decompositions that were + * corrected in later revisions. The value of the correction field is + * the Unicode version in which the mapping was corrected. + */ +struct unicode_data { + unsigned int code; + int ccc; + int gen; + int correction; + unsigned int *utf32nfkdi; + unsigned int *utf32nfkdicf; + char *utf8nfkdi; + char *utf8nfkdicf; +}; + +struct unicode_data unicode_data[0x110000]; +struct unicode_data *corrections; +int corrections_count; + +struct tree *nfkdi_tree; +struct tree *nfkdicf_tree; + +struct tree *trees; +int trees_count; + +/* + * Check the corrections array to see if this entry was corrected at + * some point. + */ +static struct unicode_data * +corrections_lookup(struct unicode_data *u) +{ + int i; + + for (i = 0; i != corrections_count; i++) + if (u->code == corrections[i].code) + return &corrections[i]; + return u; +} + +static int +nfkdi_equal(void *l, void *r) +{ + struct unicode_data *left = l; + struct unicode_data *right = r; + + if (left->gen != right->gen) + return 0; + if (left->ccc != right->ccc) + return 0; + if (left->utf8nfkdi && right->utf8nfkdi && + strcmp(left->utf8nfkdi, right->utf8nfkdi) == 0) + return 1; + if (left->utf8nfkdi || right->utf8nfkdi) + return 0; + return 1; +} + +static int +nfkdicf_equal(void *l, void *r) +{ + struct unicode_data *left = l; + struct unicode_data *right = r; + + if (left->gen != right->gen) + return 0; + if (left->ccc != right->ccc) + return 0; + if (left->utf8nfkdicf && right->utf8nfkdicf && + strcmp(left->utf8nfkdicf, right->utf8nfkdicf) == 0) + return 1; + if (left->utf8nfkdicf && right->utf8nfkdicf) + return 0; + if (left->utf8nfkdicf || right->utf8nfkdicf) + return 0; + if (left->utf8nfkdi && right->utf8nfkdi && + strcmp(left->utf8nfkdi, right->utf8nfkdi) == 0) + return 1; + if (left->utf8nfkdi || right->utf8nfkdi) + return 0; + return 1; +} + +static void +nfkdi_print(void *l, int indent) +{ + struct unicode_data *leaf = l; + + printf("%*sleaf @ %p code %X ccc %d gen %d", indent, "", leaf, + leaf->code, leaf->ccc, leaf->gen); + if (leaf->utf8nfkdi) + printf(" nfkdi \"%s\"", (const char*)leaf->utf8nfkdi); + printf("\n"); +} + +static void +nfkdicf_print(void *l, int indent) +{ + struct unicode_data *leaf = l; + + printf("%*sleaf @ %p code %X ccc %d gen %d", indent, "", leaf, + leaf->code, leaf->ccc, leaf->gen); + if (leaf->utf8nfkdicf) + printf(" nfkdicf \"%s\"", (const char*)leaf->utf8nfkdicf); + else if (leaf->utf8nfkdi) + printf(" nfkdi \"%s\"", (const char*)leaf->utf8nfkdi); + printf("\n"); +} + +static int +nfkdi_mark(void *l) +{ + return 1; +} + +static int +nfkdicf_mark(void *l) +{ + struct unicode_data *leaf = l; + + if (leaf->utf8nfkdicf) + return 1; + return 0; +} + +static int +correction_mark(void *l) +{ + struct unicode_data *leaf = l; + + return leaf->correction; +} + +static int +nfkdi_size(void *l) +{ + struct unicode_data *leaf = l; + + int size = 2; + if (leaf->utf8nfkdi) + size += strlen(leaf->utf8nfkdi) + 1; + return size; +} + +static int +nfkdicf_size(void *l) +{ + struct unicode_data *leaf = l; + + int size = 2; + if (leaf->utf8nfkdicf) + size += strlen(leaf->utf8nfkdicf) + 1; + else if (leaf->utf8nfkdi) + size += strlen(leaf->utf8nfkdi) + 1; + return size; +} + +static int * +nfkdi_index(struct tree *tree, void *l) +{ + struct unicode_data *leaf = l; + + return &tree->leafindex[leaf->code]; +} + +static int * +nfkdicf_index(struct tree *tree, void *l) +{ + struct unicode_data *leaf = l; + + return &tree->leafindex[leaf->code]; +} + +static unsigned char * +nfkdi_emit(void *l, unsigned char *data) +{ + struct unicode_data *leaf = l; + unsigned char *s; + + *data++ = leaf->gen; + if (leaf->utf8nfkdi) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdi; + while ((*data++ = *s++) != 0) + ; + } else { + *data++ = leaf->ccc; + } + return data; +} + +static unsigned char * +nfkdicf_emit(void *l, unsigned char *data) +{ + struct unicode_data *leaf = l; + unsigned char *s; + + *data++ = leaf->gen; + if (leaf->utf8nfkdicf) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdicf; + while ((*data++ = *s++) != 0) + ; + } else if (leaf->utf8nfkdi) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdi; + while ((*data++ = *s++) != 0) + ; + } else { + *data++ = leaf->ccc; + } + return data; +} + +static void +utf8_create(struct unicode_data *data) +{ + char utf[18*4+1]; + char *u; + unsigned int *um; + int i; + + u = utf; + um = data->utf32nfkdi; + if (um) { + for (i = 0; um[i]; i++) + u += utf8key(um[i], u); + *u = '\0'; + data->utf8nfkdi = strdup((char*)utf); + } + u = utf; + um = data->utf32nfkdicf; + if (um) { + for (i = 0; um[i]; i++) + u += utf8key(um[i], u); + *u = '\0'; + if (!data->utf8nfkdi || strcmp(data->utf8nfkdi, (char*)utf)) + data->utf8nfkdicf = strdup((char*)utf); + } +} + +static void +utf8_init(void) +{ + unsigned int unichar; + int i; + + for (unichar = 0; unichar != 0x110000; unichar++) + utf8_create(&unicode_data[unichar]); + + for (i = 0; i != corrections_count; i++) + utf8_create(&corrections[i]); +} + +static void +trees_init(void) +{ + struct unicode_data *data; + unsigned int maxage; + unsigned int nextage; + int count; + int i; + int j; + + /* Count the number of different ages. */ + count = 0; + nextage = (unsigned int)-1; + do { + maxage = nextage; + nextage = 0; + for (i = 0; i <= corrections_count; i++) { + data = &corrections[i]; + if (nextage < data->correction && + data->correction < maxage) + nextage = data->correction; + } + count++; + } while (nextage); + + /* Two trees per age: nfkdi and nfkdicf */ + trees_count = count * 2; + trees = calloc(trees_count, sizeof(struct tree)); + + /* Assign ages to the trees. */ + count = trees_count; + nextage = (unsigned int)-1; + do { + maxage = nextage; + trees[--count].maxage = maxage; + trees[--count].maxage = maxage; + nextage = 0; + for (i = 0; i <= corrections_count; i++) { + data = &corrections[i]; + if (nextage < data->correction && + data->correction < maxage) + nextage = data->correction; + } + } while (nextage); + + /* The ages assigned above are off by one. */ + for (i = 0; i != trees_count; i++) { + j = 0; + while (ages[j] < trees[i].maxage) + j++; + trees[i].maxage = ages[j-1]; + } + + /* Set up the forwarding between trees. */ + trees[trees_count-2].next = &trees[trees_count-1]; + trees[trees_count-1].leaf_mark = nfkdi_mark; + trees[trees_count-2].leaf_mark = nfkdicf_mark; + for (i = 0; i != trees_count-2; i += 2) { + trees[i].next = &trees[trees_count-2]; + trees[i].leaf_mark = correction_mark; + trees[i+1].next = &trees[trees_count-1]; + trees[i+1].leaf_mark = correction_mark; + } + + /* Assign the callouts. */ + for (i = 0; i != trees_count; i += 2) { + trees[i].type = "nfkdicf"; + trees[i].leaf_equal = nfkdicf_equal; + trees[i].leaf_print = nfkdicf_print; + trees[i].leaf_size = nfkdicf_size; + trees[i].leaf_index = nfkdicf_index; + trees[i].leaf_emit = nfkdicf_emit; + + trees[i+1].type = "nfkdi"; + trees[i+1].leaf_equal = nfkdi_equal; + trees[i+1].leaf_print = nfkdi_print; + trees[i+1].leaf_size = nfkdi_size; + trees[i+1].leaf_index = nfkdi_index; + trees[i+1].leaf_emit = nfkdi_emit; + } + + /* Finish init. */ + for (i = 0; i != trees_count; i++) + trees[i].childnode = NODE; +} + +static void +trees_populate(void) +{ + struct unicode_data *data; + unsigned int unichar; + char keyval[4]; + int keylen; + int i; + + for (i = 0; i != trees_count; i++) { + if (verbose > 0) { + printf("Populating %s_%x\n", + trees[i].type, trees[i].maxage); + } + for (unichar = 0; unichar != 0x110000; unichar++) { + if (unicode_data[unichar].gen < 0) + continue; + keylen = utf8key(unichar, keyval); + data = corrections_lookup(&unicode_data[unichar]); + if (data->correction <= trees[i].maxage) + data = &unicode_data[unichar]; + insert(&trees[i], keyval, keylen, data); + } + } +} + +static void +trees_reduce(void) +{ + int i; + int size; + int changed; + + for (i = 0; i != trees_count; i++) + prune(&trees[i]); + for (i = 0; i != trees_count; i++) + mark_nodes(&trees[i]); + do { + size = 0; + for (i = 0; i != trees_count; i++) + size = index_nodes(&trees[i], size); + changed = 0; + for (i = 0; i != trees_count; i++) + changed += size_nodes(&trees[i]); + } while (changed); + + utf8data = calloc(size, 1); + utf8data_size = size; + for (i = 0; i != trees_count; i++) + emit(&trees[i], utf8data); + + if (verbose > 0) { + for (i = 0; i != trees_count; i++) { + printf("%s_%x idx %d\n", + trees[i].type, trees[i].maxage, trees[i].index); + } + } + + nfkdi = utf8data + trees[trees_count-1].index; + nfkdicf = utf8data + trees[trees_count-2].index; + + nfkdi_tree = &trees[trees_count-1]; + nfkdicf_tree = &trees[trees_count-2]; +} + +static void +verify(struct tree *tree) +{ + struct unicode_data *data; + utf8leaf_t *leaf; + unsigned int unichar; + char key[4]; + int report; + int nocf; + + if (verbose > 0) + printf("Verifying %s_%x\n", tree->type, tree->maxage); + nocf = strcmp(tree->type, "nfkdicf"); + + for (unichar = 0; unichar != 0x110000; unichar++) { + report = 0; + data = corrections_lookup(&unicode_data[unichar]); + if (data->correction <= tree->maxage) + data = &unicode_data[unichar]; + utf8key(unichar, key); + leaf = utf8lookup(tree, key); + if (!leaf) { + if (data->gen != -1) + report++; + if (unichar < 0xd800 || unichar > 0xdfff) + report++; + } else { + if (unichar >= 0xd800 && unichar <= 0xdfff) + report++; + if (data->gen == -1) + report++; + if (data->gen != LEAF_GEN(leaf)) + report++; + if (LEAF_CCC(leaf) == DECOMPOSE) { + if (nocf) { + if (!data->utf8nfkdi) { + report++; + } else if (strcmp(data->utf8nfkdi, + LEAF_STR(leaf))) { + report++; + } + } else { + if (!data->utf8nfkdicf && + !data->utf8nfkdi) { + report++; + } else if (data->utf8nfkdicf) { + if (strcmp(data->utf8nfkdicf, + LEAF_STR(leaf))) + report++; + } else if (strcmp(data->utf8nfkdi, + LEAF_STR(leaf))) { + report++; + } + } + } else if (data->ccc != LEAF_CCC(leaf)) { + report++; + } + } + if (report) { + printf("%X code %X gen %d ccc %d" + " nfdki -> \"%s\"", + unichar, data->code, data->gen, + data->ccc, + data->utf8nfkdi); + if (leaf) { + printf(" age %d ccc %d" + " nfdki -> \"%s\"\n", + LEAF_GEN(leaf), + LEAF_CCC(leaf), + LEAF_CCC(leaf) == DECOMPOSE ? + LEAF_STR(leaf) : ""); + } + printf("\n"); + } + } +} + +static void +trees_verify(void) +{ + int i; + + for (i = 0; i != trees_count; i++) + verify(&trees[i]); +} + +/* ------------------------------------------------------------------ */ + +static void +help(void) +{ + printf("Usage: %s [options]\n", argv0); + printf("\n"); + printf("This program creates an a data trie used for parsing and\n"); + printf("normalization of UTF-8 strings. The trie is derived from\n"); + printf("a set of input files from the Unicode character database\n"); + printf("found at: http://www.unicode.org/Public/UCD/latest/ucd/\n"); + printf("\n"); + printf("The generated tree supports two normalization forms:\n"); + printf("\n"); + printf("\tnfkdi:\n"); + printf("\t- Apply unicode normalization form NFKD.\n"); + printf("\t- Remove any Default_Ignorable_Code_Point.\n"); + printf("\n"); + printf("\tnfkdicf:\n"); + printf("\t- Apply unicode normalization form NFKD.\n"); + printf("\t- Remove any Default_Ignorable_Code_Point.\n"); + printf("\t- Apply a full casefold (C + F).\n"); + printf("\n"); + printf("These forms were chosen as being most useful when dealing\n"); + printf("with file names: NFKD catches most cases where characters\n"); + printf("should be considered equivalent. The ignorables are mostly\n"); + printf("invisible, making names hard to type.\n"); + printf("\n"); + printf("The options to specify the files to be used are listed\n"); + printf("below with their default values, which are the names used\n"); + printf("by version 7.0.0 of the Unicode Character Database.\n"); + printf("\n"); + printf("The input files:\n"); + printf("\t-a %s\n", AGE_NAME); + printf("\t-c %s\n", CCC_NAME); + printf("\t-p %s\n", PROP_NAME); + printf("\t-d %s\n", DATA_NAME); + printf("\t-f %s\n", FOLD_NAME); + printf("\t-n %s\n", NORM_NAME); + printf("\n"); + printf("Additionally, the generated tables are tested using:\n"); + printf("\t-t %s\n", TEST_NAME); + printf("\n"); + printf("Finally, the output file:\n"); + printf("\t-o %s\n", UTF8_NAME); + printf("\n"); +} + +static void +usage(void) +{ + help(); + exit(1); +} + +static void +open_fail(const char *name, int error) +{ + printf("Error %d opening %s: %s\n", error, name, strerror(error)); + exit(1); +} + +static void +file_fail(const char *filename) +{ + printf("Error parsing %s\n", filename); + exit(1); +} + +static void +line_fail(const char *filename, const char *line) +{ + printf("Error parsing %s:%s\n", filename, line); + exit(1); +} + +/* ------------------------------------------------------------------ */ + +static void +print_utf32(unsigned int *utf32str) +{ + int i; + + for (i = 0; utf32str[i]; i++) + printf(" %X", utf32str[i]); +} + +static void +print_utf32nfkdi(unsigned int unichar) +{ + printf(" %X ->", unichar); + print_utf32(unicode_data[unichar].utf32nfkdi); + printf("\n"); +} + +static void +print_utf32nfkdicf(unsigned int unichar) +{ + printf(" %X ->", unichar); + print_utf32(unicode_data[unichar].utf32nfkdicf); + printf("\n"); +} + +/* ------------------------------------------------------------------ */ + +static void +age_init(void) +{ + FILE *file; + unsigned int first; + unsigned int last; + unsigned int unichar; + unsigned int major; + unsigned int minor; + unsigned int revision; + int gen; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", age_name); + + file = fopen(age_name, "r"); + if (!file) + open_fail(age_name, errno); + count = 0; + + gen = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "# Age=V%d_%d_%d", + &major, &minor, &revision); + if (ret == 3) { + ages_count++; + if (verbose > 1) + printf(" Age V%d_%d_%d\n", + major, minor, revision); + if (!age_valid(major, minor, revision)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "# Age=V%d_%d", &major, &minor); + if (ret == 2) { + ages_count++; + if (verbose > 1) + printf(" Age V%d_%d\n", major, minor); + if (!age_valid(major, minor, 0)) + line_fail(age_name, line); + continue; + } + } + + /* We must have found something above. */ + if (verbose > 1) + printf("%d age entries\n", ages_count); + if (ages_count == 0 || ages_count > MAXGEN) + file_fail(age_name); + + /* There is a 0 entry. */ + ages_count++; + ages = calloc(ages_count + 1, sizeof(*ages)); + /* And a guard entry. */ + ages[ages_count] = (unsigned int)-1; + + rewind(file); + count = 0; + gen = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "# Age=V%d_%d_%d", + &major, &minor, &revision); + if (ret == 3) { + ages[++gen] = + UNICODE_AGE(major, minor, revision); + if (verbose > 1) + printf(" Age V%d_%d_%d = gen %d\n", + major, minor, revision, gen); + if (!age_valid(major, minor, revision)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "# Age=V%d_%d", &major, &minor); + if (ret == 2) { + ages[++gen] = UNICODE_AGE(major, minor, 0); + if (verbose > 1) + printf(" Age V%d_%d = %d\n", + major, minor, gen); + if (!age_valid(major, minor, 0)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "%X..%X ; %d.%d #", + &first, &last, &major, &minor); + if (ret == 4) { + for (unichar = first; unichar <= last; unichar++) + unicode_data[unichar].gen = gen; + count += 1 + last - first; + if (verbose > 1) + printf(" %X..%X gen %d\n", first, last, gen); + if (!utf32valid(first) || !utf32valid(last)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "%X ; %d.%d #", &unichar, &major, &minor); + if (ret == 3) { + unicode_data[unichar].gen = gen; + count++; + if (verbose > 1) + printf(" %X gen %d\n", unichar, gen); + if (!utf32valid(unichar)) + line_fail(age_name, line); + continue; + } + } + unicode_maxage = ages[gen]; + fclose(file); + + /* Nix surrogate block */ + if (verbose > 1) + printf(" Removing surrogate block D800..DFFF\n"); + for (unichar = 0xd800; unichar <= 0xdfff; unichar++) + unicode_data[unichar].gen = -1; + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(age_name); +} + +static void +ccc_init(void) +{ + FILE *file; + unsigned int first; + unsigned int last; + unsigned int unichar; + unsigned int value; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", ccc_name); + + file = fopen(ccc_name, "r"); + if (!file) + open_fail(ccc_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X..%X ; %d #", &first, &last, &value); + if (ret == 3) { + for (unichar = first; unichar <= last; unichar++) { + unicode_data[unichar].ccc = value; + count++; + } + if (verbose > 1) + printf(" %X..%X ccc %d\n", first, last, value); + if (!utf32valid(first) || !utf32valid(last)) + line_fail(ccc_name, line); + continue; + } + ret = sscanf(line, "%X ; %d #", &unichar, &value); + if (ret == 2) { + unicode_data[unichar].ccc = value; + count++; + if (verbose > 1) + printf(" %X ccc %d\n", unichar, value); + if (!utf32valid(unichar)) + line_fail(ccc_name, line); + continue; + } + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(ccc_name); +} + +static void +nfkdi_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char *s; + unsigned int *um; + int count; + int i; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", data_name); + file = fopen(data_name, "r"); + if (!file) + open_fail(data_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%*[^;];%*[^;];%*[^;];%*[^;];%[^;];", + &unichar, buf0); + if (ret != 2) + continue; + if (!utf32valid(unichar)) + line_fail(data_name, line); + + s = buf0; + /* skip over */ + if (*s == '<') + while (*s++ != ' ') + ; + /* decode the decomposition into UTF-32 */ + i = 0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(data_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + + if (verbose > 1) + print_utf32nfkdi(unichar); + count++; + } + fclose(file); + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(data_name); +} + +static void +nfkdicf_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char status; + char *s; + unsigned int *um; + int i; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", fold_name); + file = fopen(fold_name, "r"); + if (!file) + open_fail(fold_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X; %c; %[^;];", &unichar, &status, buf0); + if (ret != 3) + continue; + if (!utf32valid(unichar)) + line_fail(fold_name, line); + /* Use the C+F casefold. */ + if (status != 'C' && status != 'F') + continue; + s = buf0; + if (*s == '<') + while (*s++ != ' ') + ; + i = 0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(fold_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + + if (verbose > 1) + print_utf32nfkdicf(unichar); + count++; + } + fclose(file); + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(fold_name); +} + +static void +ignore_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int first; + unsigned int last; + unsigned int *um; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", prop_name); + file = fopen(prop_name, "r"); + if (!file) + open_fail(prop_name, errno); + assert(file); + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X..%X ; %s # ", &first, &last, buf0); + if (ret == 3) { + if (strcmp(buf0, "Default_Ignorable_Code_Point")) + continue; + if (!utf32valid(first) || !utf32valid(last)) + line_fail(prop_name, line); + for (unichar = first; unichar <= last; unichar++) { + free(unicode_data[unichar].utf32nfkdi); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdi = um; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdicf = um; + count++; + } + if (verbose > 1) + printf(" %X..%X Default_Ignorable_Code_Point\n", + first, last); + continue; + } + ret = sscanf(line, "%X ; %s # ", &unichar, buf0); + if (ret == 2) { + if (strcmp(buf0, "Default_Ignorable_Code_Point")) + continue; + if (!utf32valid(unichar)) + line_fail(prop_name, line); + free(unicode_data[unichar].utf32nfkdi); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdi = um; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdicf = um; + if (verbose > 1) + printf(" %X Default_Ignorable_Code_Point\n", + unichar); + count++; + continue; + } + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(prop_name); +} + +static void +corrections_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int major; + unsigned int minor; + unsigned int revision; + unsigned int age; + unsigned int *um; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char *s; + int i; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", norm_name); + file = fopen(norm_name, "r"); + if (!file) + open_fail(norm_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%[^;];%[^;];%d.%d.%d #", + &unichar, buf0, buf1, + &major, &minor, &revision); + if (ret != 6) + continue; + if (!utf32valid(unichar) || !age_valid(major, minor, revision)) + line_fail(norm_name, line); + count++; + } + corrections = calloc(count, sizeof(struct unicode_data)); + corrections_count = count; + rewind(file); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%[^;];%[^;];%d.%d.%d #", + &unichar, buf0, buf1, + &major, &minor, &revision); + if (ret != 6) + continue; + if (!utf32valid(unichar) || !age_valid(major, minor, revision)) + line_fail(norm_name, line); + corrections[count] = unicode_data[unichar]; + assert(corrections[count].code == unichar); + age = UNICODE_AGE(major, minor, revision); + corrections[count].correction = age; + + i = 0; + s = buf0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(norm_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + corrections[count].utf32nfkdi = um; + + if (verbose > 1) + printf(" %X -> %s -> %s V%d_%d_%d\n", + unichar, buf0, buf1, major, minor, revision); + count++; + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(norm_name); +} + +/* ------------------------------------------------------------------ */ + +/* + * Hangul decomposition (algorithm from Section 3.12 of Unicode 6.3.0) + * + * AC00;;Lo;0;L;;;;;N;;;;; + * D7A3;;Lo;0;L;;;;;N;;;;; + * + * SBase = 0xAC00 + * LBase = 0x1100 + * VBase = 0x1161 + * TBase = 0x11A7 + * LCount = 19 + * VCount = 21 + * TCount = 28 + * NCount = 588 (VCount * TCount) + * SCount = 11172 (LCount * NCount) + * + * Decomposition: + * SIndex = s - SBase + * + * LV (Canonical/Full) + * LIndex = SIndex / NCount + * VIndex = (Sindex % NCount) / TCount + * LPart = LBase + LIndex + * VPart = VBase + VIndex + * + * LVT (Canonical) + * LVIndex = (SIndex / TCount) * TCount + * TIndex = (Sindex % TCount + * LVPart = LBase + LVIndex + * TPart = TBase + TIndex + * + * LVT (Full) + * LIndex = SIndex / NCount + * VIndex = (Sindex % NCount) / TCount + * TIndex = (Sindex % TCount + * LPart = LBase + LIndex + * VPart = VBase + VIndex + * if (TIndex == 0) { + * d = + * } else { + * TPart = TBase + TIndex + * d = + * } + * + */ + +static void +hangul_decompose(void) +{ + unsigned int sb = 0xAC00; + unsigned int lb = 0x1100; + unsigned int vb = 0x1161; + unsigned int tb = 0x11a7; + /* unsigned int lc = 19; */ + unsigned int vc = 21; + unsigned int tc = 28; + unsigned int nc = (vc * tc); + /* unsigned int sc = (lc * nc); */ + unsigned int unichar; + unsigned int mapping[4]; + unsigned int *um; + int count; + int i; + + if (verbose > 0) + printf("Decomposing hangul\n"); + /* Hangul */ + count = 0; + for (unichar = 0xAC00; unichar <= 0xD7A3; unichar++) { + unsigned int si = unichar - sb; + unsigned int li = si / nc; + unsigned int vi = (si % nc) / tc; + unsigned int ti = si % tc; + + i = 0; + mapping[i++] = lb + li; + mapping[i++] = vb + vi; + if (ti) + mapping[i++] = tb + ti; + mapping[i++] = 0; + + assert(!unicode_data[unichar].utf32nfkdi); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + + assert(!unicode_data[unichar].utf32nfkdicf); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + + if (verbose > 1) + print_utf32nfkdi(unichar); + + count++; + } + if (verbose > 0) + printf("Created %d entries\n", count); +} + +static void +nfkdi_decompose(void) +{ + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + unsigned int *um; + unsigned int *dc; + int count; + int i; + int j; + int ret; + + if (verbose > 0) + printf("Decomposing nfkdi\n"); + + count = 0; + for (unichar = 0; unichar != 0x110000; unichar++) { + if (!unicode_data[unichar].utf32nfkdi) + continue; + for (;;) { + ret = 1; + i = 0; + um = unicode_data[unichar].utf32nfkdi; + while (*um) { + dc = unicode_data[*um].utf32nfkdi; + if (dc) { + for (j = 0; dc[j]; j++) + mapping[i++] = dc[j]; + ret = 0; + } else { + mapping[i++] = *um; + } + um++; + } + mapping[i++] = 0; + if (ret) + break; + free(unicode_data[unichar].utf32nfkdi); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + } + /* Add this decomposition to nfkdicf if there is no entry. */ + if (!unicode_data[unichar].utf32nfkdicf) { + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + } + if (verbose > 1) + print_utf32nfkdi(unichar); + count++; + } + if (verbose > 0) + printf("Processed %d entries\n", count); +} + +static void +nfkdicf_decompose(void) +{ + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + unsigned int *um; + unsigned int *dc; + int count; + int i; + int j; + int ret; + + if (verbose > 0) + printf("Decomposing nfkdicf\n"); + count = 0; + for (unichar = 0; unichar != 0x110000; unichar++) { + if (!unicode_data[unichar].utf32nfkdicf) + continue; + for (;;) { + ret = 1; + i = 0; + um = unicode_data[unichar].utf32nfkdicf; + while (*um) { + dc = unicode_data[*um].utf32nfkdicf; + if (dc) { + for (j = 0; dc[j]; j++) + mapping[i++] = dc[j]; + ret = 0; + } else { + mapping[i++] = *um; + } + um++; + } + mapping[i++] = 0; + if (ret) + break; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + } + if (verbose > 1) + print_utf32nfkdicf(unichar); + count++; + } + if (verbose > 0) + printf("Processed %d entries\n", count); +} + +/* ------------------------------------------------------------------ */ + +int utf8agemax(struct tree *, const char *); +int utf8nagemax(struct tree *, const char *, size_t); +int utf8agemin(struct tree *, const char *); +int utf8nagemin(struct tree *, const char *, size_t); +ssize_t utf8len(struct tree *, const char *); +ssize_t utf8nlen(struct tree *, const char *, size_t); +struct utf8cursor; +int utf8cursor(struct utf8cursor *, struct tree *, const char *); +int utf8ncursor(struct utf8cursor *, struct tree *, const char *, size_t); +int utf8byte(struct utf8cursor *); + +/* + * Use trie to scan s, touching at most len bytes. + * Returns the leaf if one exists, NULL otherwise. + * + * A non-NULL return guarantees that the UTF-8 sequence starting at s + * is well-formed and corresponds to a known unicode code point. The + * shorthand for this will be "is valid UTF-8 unicode". + */ +static utf8leaf_t * +utf8nlookup(struct tree *tree, const char *s, size_t len) +{ + utf8trie_t *trie = utf8data + tree->index; + int offlen; + int offset; + int mask; + int node; + + if (!tree) + return NULL; + if (len == 0) + return NULL; + node = 1; + while (node) { + offlen = (*trie & OFFLEN) >> OFFLEN_SHIFT; + if (*trie & NEXTBYTE) { + if (--len == 0) + return NULL; + s++; + } + mask = 1 << (*trie & BITNUM); + if (*s & mask) { + /* Right leg */ + if (offlen) { + /* Right node at offset of trie */ + node = (*trie & RIGHTNODE); + offset = trie[offlen]; + while (--offlen) { + offset <<= 8; + offset |= trie[offlen]; + } + trie += offset; + } else if (*trie & RIGHTPATH) { + /* Right node after this node */ + node = (*trie & TRIENODE); + trie++; + } else { + /* No right node. */ + node = 0; + trie = NULL; + } + } else { + /* Left leg */ + if (offlen) { + /* Left node after this node. */ + node = (*trie & LEFTNODE); + trie += offlen + 1; + } else if (*trie & RIGHTPATH) { + /* No left node. */ + node = 0; + trie = NULL; + } else { + /* Left node after this node */ + node = (*trie & TRIENODE); + trie++; + } + } + } + return trie; +} + +/* + * Use trie to scan s. + * Returns the leaf if one exists, NULL otherwise. + * + * Forwards to trie_nlookup(). + */ +static utf8leaf_t * +utf8lookup(struct tree *tree, const char *s) +{ + return utf8nlookup(tree, s, (size_t)-1); +} + +/* + * Return the number of bytes used by the current UTF-8 sequence. + * Assumes the input points to the first byte of a valid UTF-8 + * sequence. + */ +static inline int +utf8clen(const char *s) +{ + unsigned char c = *s; + return 1 + (c >= 0xC0) + (c >= 0xE0) + (c >= 0xF0); +} + +/* + * Maximum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if only non-assigned code points are used. + */ +int +utf8agemax(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age > age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Minimum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if non-assigned code points are used. + */ +int +utf8agemin(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + int age = tree->maxage; + int leaf_age; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age < age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemax(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age > age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemin(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int leaf_age; + int age = tree->maxage; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age < age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Length of the normalization of s. + * Return -1 if s is not valid UTF-8 unicode. + * + * A string of Default_Ignorable_Code_Point has length 0. + */ +ssize_t +utf8len(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + if (ages[LEAF_GEN(leaf)] > tree->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Length of the normalization of s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +ssize_t +utf8nlen(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + if (ages[LEAF_GEN(leaf)] > tree->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + len -= utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Cursor structure used by the normalizer. + */ +struct utf8cursor { + struct tree *tree; + const char *s; + const char *p; + const char *ss; + const char *sp; + unsigned int len; + unsigned int slen; + short int ccc; + short int nccc; + unsigned int unichar; +}; + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * s : string. + * len : length of s. + * u8c : pointer to cursor. + * trie : utf8trie_t to use for normalization. + * + * Returns -1 on error, 0 on success. + */ +int +utf8ncursor( + struct utf8cursor *u8c, + struct tree *tree, + const char *s, + size_t len) +{ + if (!tree) + return -1; + if (!s) + return -1; + u8c->tree = tree; + u8c->s = s; + u8c->p = NULL; + u8c->ss = NULL; + u8c->sp = NULL; + u8c->len = len; + u8c->slen = 0; + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->unichar = 0; + /* Check we didn't clobber the maximum length. */ + if (u8c->len != len) + return -1; + /* The first byte of s may not be an utf8 continuation. */ + if (len > 0 && (*s & 0xC0) == 0x80) + return -1; + return 0; +} + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * s : NUL-terminated string. + * u8c : pointer to cursor. + * trie : utf8trie_t to use for normalization. + * + * Returns -1 on error, 0 on success. + */ +int +utf8cursor( + struct utf8cursor *u8c, + struct tree *tree, + const char *s) +{ + return utf8ncursor(u8c, tree, s, (unsigned int)-1); +} + +/* + * Get one byte from the normalized form of the string described by u8c. + * + * Returns the byte cast to an unsigned char on succes, and -1 on failure. + * + * The cursor keeps track of the location in the string in u8c->s. + * When a character is decomposed, the current location is stored in + * u8c->p, and u8c->s is set to the start of the decomposition. Note + * that bytes from a decomposition do not count against u8c->len. + * + * Characters are emitted if they match the current CCC in u8c->ccc. + * Hitting end-of-string while u8c->ccc == STOPPER means we're done, + * and the function returns 0 in that case. + * + * Sorting by CCC is done by repeatedly scanning the string. The + * values of u8c->s and u8c->p are stored in u8c->ss and u8c->sp at + * the start of the scan. The first pass finds the lowest CCC to be + * emitted and stores it in u8c->nccc, the second pass emits the + * characters with this CCC and finds the next lowest CCC. This limits + * the number of passes to 1 + the number of different CCCs in the + * sequence being scanned. + * + * Therefore: + * u8c->p != NULL -> a decomposition is being scanned. + * u8c->ss != NULL -> this is a repeating scan. + * u8c->ccc == -1 -> this is the first scan of a repeating scan. + */ +int +utf8byte(struct utf8cursor *u8c) +{ + utf8leaf_t *leaf; + int ccc; + + for (;;) { + /* Check for the end of a decomposed character. */ + if (u8c->p && *u8c->s == '\0') { + u8c->s = u8c->p; + u8c->p = NULL; + } + + /* Check for end-of-string. */ + if (!u8c->p && (u8c->len == 0 || *u8c->s == '\0')) { + /* There is no next byte. */ + if (u8c->ccc == STOPPER) + return 0; + /* End-of-string during a scan counts as a stopper. */ + ccc = STOPPER; + goto ccc_mismatch; + } else if ((*u8c->s & 0xC0) == 0x80) { + /* This is a continuation of the current character. */ + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Look up the data for the current character. */ + if (u8c->p) + leaf = utf8lookup(u8c->tree, u8c->s); + else + leaf = utf8nlookup(u8c->tree, u8c->s, u8c->len); + + /* No leaf found implies that the input is a binary blob. */ + if (!leaf) + return -1; + + /* Characters that are too new have CCC 0. */ + if (ages[LEAF_GEN(leaf)] > u8c->tree->maxage) { + ccc = STOPPER; + } else if ((ccc = LEAF_CCC(leaf)) == DECOMPOSE) { + u8c->len -= utf8clen(u8c->s); + u8c->p = u8c->s + utf8clen(u8c->s); + u8c->s = LEAF_STR(leaf); + /* Empty decomposition implies CCC 0. */ + if (*u8c->s == '\0') { + if (u8c->ccc == STOPPER) + continue; + ccc = STOPPER; + goto ccc_mismatch; + } + leaf = utf8lookup(u8c->tree, u8c->s); + ccc = LEAF_CCC(leaf); + } + u8c->unichar = utf8code(u8c->s); + + /* + * If this is not a stopper, then see if it updates + * the next canonical class to be emitted. + */ + if (ccc != STOPPER && u8c->ccc < ccc && ccc < u8c->nccc) + u8c->nccc = ccc; + + /* + * Return the current byte if this is the current + * combining class. + */ + if (ccc == u8c->ccc) { + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Current combining class mismatch. */ + ccc_mismatch: + if (u8c->nccc == STOPPER) { + /* + * Scan forward for the first canonical class + * to be emitted. Save the position from + * which to restart. + */ + assert(u8c->ccc == STOPPER); + u8c->ccc = MINCCC - 1; + u8c->nccc = ccc; + u8c->sp = u8c->p; + u8c->ss = u8c->s; + u8c->slen = u8c->len; + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (ccc != STOPPER) { + /* Not a stopper, and not the ccc we're emitting. */ + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (u8c->nccc != MAXCCC + 1) { + /* At a stopper, restart for next ccc. */ + u8c->ccc = u8c->nccc; + u8c->nccc = MAXCCC + 1; + u8c->s = u8c->ss; + u8c->p = u8c->sp; + u8c->len = u8c->slen; + } else { + /* All done, proceed from here. */ + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->sp = NULL; + u8c->ss = NULL; + u8c->slen = 0; + } + } +} + +/* ------------------------------------------------------------------ */ + +static int +normalize_line(struct tree *tree) +{ + char *s; + char *t; + int c; + struct utf8cursor u8c; + + /* First test: null-terminated string. */ + s = buf2; + t = buf3; + if (utf8cursor(&u8c, tree, s)) + return -1; + while ((c = utf8byte(&u8c)) > 0) + if (c != (unsigned char)*t++) + return -1; + if (c < 0) + return -1; + if (*t != 0) + return -1; + + /* Second test: length-limited string. */ + s = buf2; + /* Replace NUL with a value that will cause an error if seen. */ + s[strlen(s) + 1] = -1; + t = buf3; + if (utf8cursor(&u8c, tree, s)) + return -1; + while ((c = utf8byte(&u8c)) > 0) + if (c != (unsigned char)*t++) + return -1; + if (c < 0) + return -1; + if (*t != 0) + return -1; + + return 0; +} + +static void +normalization_test(void) +{ + FILE *file; + unsigned int unichar; + struct unicode_data *data; + char *s; + char *t; + int ret; + int ignorables; + int tests = 0; + int failures = 0; + + if (verbose > 0) + printf("Parsing %s\n", test_name); + /* Step one, read data from file. */ + file = fopen(test_name, "r"); + if (!file) + open_fail(test_name, errno); + + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%[^;];%*[^;];%*[^;];%*[^;];%[^;];", + buf0, buf1); + if (ret != 2 || *line == '#') + continue; + s = buf0; + t = buf2; + while (*s) { + unichar = strtoul(s, &s, 16); + t += utf8key(unichar, t); + } + *t = '\0'; + + ignorables = 0; + s = buf1; + t = buf3; + while (*s) { + unichar = strtoul(s, &s, 16); + data = &unicode_data[unichar]; + if (data->utf8nfkdi && !*data->utf8nfkdi) + ignorables = 1; + else + t += utf8key(unichar, t); + } + *t = '\0'; + + tests++; + if (normalize_line(nfkdi_tree) < 0) { + printf("\nline %s -> %s", buf0, buf1); + if (ignorables) + printf(" (ignorables removed)"); + printf(" failure\n"); + failures++; + } + } + fclose(file); + if (verbose > 0) + printf("Ran %d tests with %d failures\n", tests, failures); + if (failures) + file_fail(test_name); +} + +/* ------------------------------------------------------------------ */ + +static void +write_file(void) +{ + FILE *file; + int i; + int j; + int t; + int gen; + + if (verbose > 0) + printf("Writing %s\n", utf8_name); + file = fopen(utf8_name, "w"); + if (!file) + open_fail(utf8_name, errno); + + fprintf(file, "/* This file is generated code, do not edit. */\n"); + fprintf(file, "#ifndef __INCLUDED_FROM_UTF8NORM_C__\n"); + fprintf(file, "#error Only xfs_utf8.c may include this file.\n"); + fprintf(file, "#endif\n"); + fprintf(file, "\n"); + fprintf(file, "static const unsigned int utf8vers = %#x;\n", + unicode_maxage); + fprintf(file, "\n"); + fprintf(file, "static const unsigned int utf8agetab[] = {\n"); + for (i = 0; i != ages_count; i++) + fprintf(file, "\t%#x%s\n", ages[i], + ages[i] == unicode_maxage ? "" : ","); + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const struct utf8data utf8nfkdicfdata[] = {\n"); + t = 0; + for (gen = 0; gen < ages_count; gen++) { + fprintf(file, "\t{ %#x, %d }%s\n", + ages[gen], trees[t].index, + ages[gen] == unicode_maxage ? "" : ","); + if (trees[t].maxage == ages[gen]) + t += 2; + } + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const struct utf8data utf8nfkdidata[] = {\n"); + t = 1; + for (gen = 0; gen < ages_count; gen++) { + fprintf(file, "\t{ %#x, %d }%s\n", + ages[gen], trees[t].index, + ages[gen] == unicode_maxage ? "" : ","); + if (trees[t].maxage == ages[gen]) + t += 2; + } + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const unsigned char utf8data[%zd] = {\n", + utf8data_size); + t = 0; + for (i = 0; i != utf8data_size; i += 16) { + if (i == trees[t].index) { + fprintf(file, "\t/* %s_%x */\n", + trees[t].type, trees[t].maxage); + if (t < trees_count-1) + t++; + } + fprintf(file, "\t"); + for (j = i; j != i + 16; j++) + fprintf(file, "0x%.2x%s", utf8data[j], + (j < utf8data_size -1 ? "," : "")); + fprintf(file, "\n"); + } + fprintf(file, "};\n"); + fclose(file); +} + +/* ------------------------------------------------------------------ */ + +int +main(int argc, char *argv[]) +{ + unsigned int unichar; + int opt; + + argv0 = argv[0]; + + while ((opt = getopt(argc, argv, "a:c:d:f:hn:o:p:t:v")) != -1) { + switch (opt) { + case 'a': + age_name = optarg; + break; + case 'c': + ccc_name = optarg; + break; + case 'd': + data_name = optarg; + break; + case 'f': + fold_name = optarg; + break; + case 'n': + norm_name = optarg; + break; + case 'o': + utf8_name = optarg; + break; + case 'p': + prop_name = optarg; + break; + case 't': + test_name = optarg; + break; + case 'v': + verbose++; + break; + case 'h': + help(); + exit(0); + default: + usage(); + } + } + + if (verbose > 1) + help(); + for (unichar = 0; unichar != 0x110000; unichar++) + unicode_data[unichar].code = unichar; + age_init(); + ccc_init(); + nfkdi_init(); + nfkdicf_init(); + ignore_init(); + corrections_init(); + hangul_decompose(); + nfkdi_decompose(); + nfkdicf_decompose(); + utf8_init(); + trees_init(); + trees_populate(); + trees_reduce(); + trees_verify(); + /* Prevent "unused function" warning. */ + (void)lookup(nfkdi_tree, " "); + if (verbose > 2) + tree_walk(nfkdi_tree); + if (verbose > 2) + tree_walk(nfkdicf_tree); + normalization_test(); + write_file(); + + return 0; +} diff --git a/fs/xfs/utf8norm/utf8norm.c b/fs/xfs/utf8norm/utf8norm.c new file mode 100644 index 0000000..995c4df --- /dev/null +++ b/fs/xfs/utf8norm/utf8norm.c @@ -0,0 +1,649 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "utf8norm.h" + +struct utf8data { + unsigned int maxage; + unsigned int offset; +}; + +#define __INCLUDED_FROM_UTF8NORM_C__ +#include "utf8data.h" +#undef __INCLUDED_FROM_UTF8NORM_C__ + +const unsigned int utf8version(void) +{ + return utf8vers; +} +EXPORT_SYMBOL(utf8version); + +/* + * UTF-8 valid ranges. + * + * The UTF-8 encoding spreads the bits of a 32bit word over several + * bytes. This table gives the ranges that can be held and how they'd + * be represented. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000000 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000000 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * There is an additional requirement on UTF-8, in that only the + * shortest representation of a 32bit value is to be used. A decoder + * must not decode sequences that do not satisfy this requirement. + * Thus the allowed ranges have a lower bound. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000080 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000800 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00010000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00200000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x04000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Actual unicode characters are limited to the range 0x0 - 0x10FFFF, + * 17 planes of 65536 values. This limits the sequences actually seen + * even more, to just the following. + * + * 0 - 0x7F: 0 - 0x7F + * 0x80 - 0x7FF: 0xC2 0x80 - 0xDF 0xBF + * 0x800 - 0xFFFF: 0xE0 0xA0 0x80 - 0xEF 0xBF 0xBF + * 0x10000 - 0x10FFFF: 0xF0 0x90 0x80 0x80 - 0xF4 0x8F 0xBF 0xBF + * + * Within those ranges the surrogates 0xD800 - 0xDFFF are not allowed. + * + * Note that the longest sequence seen with valid usage is 4 bytes, + * the same a single UTF-32 character. This makes the UTF-8 + * representation of Unicode strictly smaller than UTF-32. + * + * The shortest sequence requirement was introduced by: + * Corrigendum #1: UTF-8 Shortest Form + * It can be found here: + * http://www.unicode.org/versions/corrigendum1.html + * + */ + +/* + * Return the number of bytes used by the current UTF-8 sequence. + * Assumes the input points to the first byte of a valid UTF-8 + * sequence. + */ +static inline int +utf8clen(const char *s) +{ + unsigned char c = *s; + return 1 + (c >= 0xC0) + (c >= 0xE0) + (c >= 0xF0); +} + +/* + * utf8trie_t + * + * A compact binary tree, used to decode UTF-8 characters. + * + * Internal nodes are one byte for the node itself, and up to three + * bytes for an offset into the tree. The first byte contains the + * following information: + * NEXTBYTE - flag - advance to next byte if set + * BITNUM - 3 bit field - the bit number to tested + * OFFLEN - 2 bit field - number of bytes in the offset + * if offlen == 0 (non-branching node) + * RIGHTPATH - 1 bit field - set if the following node is for the + * right-hand path (tested bit is set) + * TRIENODE - 1 bit field - set if the following node is an internal + * node, otherwise it is a leaf node + * if offlen != 0 (branching node) + * LEFTNODE - 1 bit field - set if the left-hand node is internal + * RIGHTNODE - 1 bit field - set if the right-hand node is internal + * + * Due to the way utf8 works, there cannot be branching nodes with + * NEXTBYTE set, and moreover those nodes always have a righthand + * descendant. + */ +typedef const unsigned char utf8trie_t; +#define BITNUM 0x07 +#define NEXTBYTE 0x08 +#define OFFLEN 0x30 +#define OFFLEN_SHIFT 4 +#define RIGHTPATH 0x40 +#define TRIENODE 0x80 +#define RIGHTNODE 0x40 +#define LEFTNODE 0x80 + +/* + * utf8leaf_t + * + * The leaves of the trie are embedded in the trie, and so the same + * underlying datatype: unsigned char. + * + * leaf[0]: The unicode version, stored as a generation number that is + * an index into utf8agetab[]. With this we can filter code + * points based on the unicode version in which they were + * defined. The CCC of a non-defined code point is 0. + * leaf[1]: Canonical Combining Class. During normalization, we need + * to do a stable sort into ascending order of all characters + * with a non-zero CCC that occur between two characters with + * a CCC of 0, or at the begin or end of a string. + * The unicode standard guarantees that all CCC values are + * between 0 and 254 inclusive, which leaves 255 available as + * a special value. + * Code points with CCC 0 are known as stoppers. + * leaf[2]: Decomposition. If leaf[1] == 255, then leaf[2] is the + * start of a NUL-terminated string that is the decomposition + * of the character. + * The CCC of a decomposable character is the same as the CCC + * of the first character of its decomposition. + * Some characters decompose as the empty string: these are + * characters with the Default_Ignorable_Code_Point property. + * These do affect normalization, as they all have CCC 0. + * + * The decompositions in the trie have been fully expanded. + * + * Casefolding, if applicable, is also done using decompositions. + * + * The trie is constructed in such a way that leaves exist for all + * UTF-8 sequences that match the criteria from the "UTF-8 valid + * ranges" comment above, and only for those sequences. Therefore a + * lookup in the trie can be used to validate the UTF-8 input. + */ +typedef const unsigned char utf8leaf_t; + +#define LEAF_GEN(LEAF) ((LEAF)[0]) +#define LEAF_CCC(LEAF) ((LEAF)[1]) +#define LEAF_STR(LEAF) ((const char*)((LEAF) + 2)) + +#define MINCCC (0) +#define MAXCCC (254) +#define STOPPER (0) +#define DECOMPOSE (255) + +/* + * Use trie to scan s, touching at most len bytes. + * Returns the leaf if one exists, NULL otherwise. + * + * A non-NULL return guarantees that the UTF-8 sequence starting at s + * is well-formed and corresponds to a known unicode code point. The + * shorthand for this will be "is valid UTF-8 unicode". + */ +static utf8leaf_t * +utf8nlookup(utf8data_t data, const char *s, size_t len) +{ + utf8trie_t *trie = utf8data + data->offset; + int offlen; + int offset; + int mask; + int node; + + if (!data) + return NULL; + if (len == 0) + return NULL; + node = 1; + while (node) { + offlen = (*trie & OFFLEN) >> OFFLEN_SHIFT; + if (*trie & NEXTBYTE) { + if (--len == 0) + return NULL; + s++; + } + mask = 1 << (*trie & BITNUM); + if (*s & mask) { + /* Right leg */ + if (offlen) { + /* Right node at offset of trie */ + node = (*trie & RIGHTNODE); + offset = trie[offlen]; + while (--offlen) { + offset <<= 8; + offset |= trie[offlen]; + } + trie += offset; + } else if (*trie & RIGHTPATH) { + /* Right node after this node */ + node = (*trie & TRIENODE); + trie++; + } else { + /* No right node. */ + node = 0; + trie = NULL; + } + } else { + /* Left leg */ + if (offlen) { + /* Left node after this node. */ + node = (*trie & LEFTNODE); + trie += offlen + 1; + } else if (*trie & RIGHTPATH) { + /* No left node. */ + node = 0; + trie = NULL; + } else { + /* Left node after this node */ + node = (*trie & TRIENODE); + trie++; + } + } + } + return trie; +} + +/* + * Use trie to scan s. + * Returns the leaf if one exists, NULL otherwise. + * + * Forwards to utf8nlookup(). + */ +static utf8leaf_t * +utf8lookup(utf8data_t data, const char *s) +{ + return utf8nlookup(data, s, (size_t)-1); +} + +/* + * Maximum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if only non-assigned code points are used. + */ +int +utf8agemax(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!data) + return -1; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age > age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} +EXPORT_SYMBOL(utf8agemax); + +/* + * Minimum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if non-assigned code points are used. + */ +int +utf8agemin(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + int age; + int leaf_age; + + if (!data) + return -1; + age = data->maxage; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age < age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} +EXPORT_SYMBOL(utf8agemin); + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemax(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!data) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age > age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} +EXPORT_SYMBOL(utf8nagemax); + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemin(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int leaf_age; + int age; + + if (!data) + return -1; + age = data->maxage; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age < age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} +EXPORT_SYMBOL(utf8nagemin); + +/* + * Length of the normalization of s. + * Return -1 if s is not valid UTF-8 unicode. + * + * A string of Default_Ignorable_Code_Point has length 0. + */ +ssize_t +utf8len(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!data) + return -1; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + if (utf8agetab[LEAF_GEN(leaf)] > data->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + s += utf8clen(s); + } + return ret; +} +EXPORT_SYMBOL(utf8len); + +/* + * Length of the normalization of s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +ssize_t +utf8nlen(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!data) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + if (utf8agetab[LEAF_GEN(leaf)] > data->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + len -= utf8clen(s); + s += utf8clen(s); + } + return ret; +} +EXPORT_SYMBOL(utf8nlen); + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * u8c : pointer to cursor. + * data : utf8data_t to use for normalization. + * s : string. + * len : length of s. + * + * Returns -1 on error, 0 on success. + */ +int +utf8ncursor( + struct utf8cursor *u8c, + utf8data_t data, + const char *s, + size_t len) +{ + if (!data) + return -1; + if (!s) + return -1; + u8c->data = data; + u8c->s = s; + u8c->p = NULL; + u8c->ss = NULL; + u8c->sp = NULL; + u8c->len = len; + u8c->slen = 0; + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + /* Check we didn't clobber the maximum length. */ + if (u8c->len != len) + return -1; + /* The first byte of s may not be an utf8 continuation. */ + if (len > 0 && (*s & 0xC0) == 0x80) + return -1; + return 0; +} +EXPORT_SYMBOL(utf8ncursor); + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * u8c : pointer to cursor. + * data : utf8data_t to use for normalization. + * s : NUL-terminated string. + * + * Returns -1 on error, 0 on success. + */ +int +utf8cursor( + struct utf8cursor *u8c, + utf8data_t data, + const char *s) +{ + return utf8ncursor(u8c, data, s, (unsigned int)-1); +} +EXPORT_SYMBOL(utf8cursor); + +/* + * Get one byte from the normalized form of the string described by u8c. + * + * Returns the byte cast to an unsigned char on succes, and -1 on failure. + * + * The cursor keeps track of the location in the string in u8c->s. + * When a character is decomposed, the current location is stored in + * u8c->p, and u8c->s is set to the start of the decomposition. Note + * that bytes from a decomposition do not count against u8c->len. + * + * Characters are emitted if they match the current CCC in u8c->ccc. + * Hitting end-of-string while u8c->ccc == STOPPER means we're done, + * and the function returns 0 in that case. + * + * Sorting by CCC is done by repeatedly scanning the string. The + * values of u8c->s and u8c->p are stored in u8c->ss and u8c->sp at + * the start of the scan. The first pass finds the lowest CCC to be + * emitted and stores it in u8c->nccc, the second pass emits the + * characters with this CCC and finds the next lowest CCC. This limits + * the number of passes to 1 + the number of different CCCs in the + * sequence being scanned. + * + * Therefore: + * u8c->p != NULL -> a decomposition is being scanned. + * u8c->ss != NULL -> this is a repeating scan. + * u8c->ccc == -1 -> this is the first scan of a repeating scan. + */ +int +utf8byte(struct utf8cursor *u8c) +{ + utf8leaf_t *leaf; + int ccc; + + for (;;) { + /* Check for the end of a decomposed character. */ + if (u8c->p && *u8c->s == '\0') { + u8c->s = u8c->p; + u8c->p = NULL; + } + + /* Check for end-of-string. */ + if (!u8c->p && (u8c->len == 0 || *u8c->s == '\0')) { + /* There is no next byte. */ + if (u8c->ccc == STOPPER) + return 0; + /* End-of-string during a scan counts as a stopper. */ + ccc = STOPPER; + goto ccc_mismatch; + } else if ((*u8c->s & 0xC0) == 0x80) { + /* This is a continuation of the current character. */ + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Look up the data for the current character. */ + if (u8c->p) + leaf = utf8lookup(u8c->data, u8c->s); + else + leaf = utf8nlookup(u8c->data, u8c->s, u8c->len); + + /* No leaf found implies that the input is a binary blob. */ + if (!leaf) + return -1; + + /* Characters that are too new have CCC 0. */ + if (utf8agetab[LEAF_GEN(leaf)] > u8c->data->maxage) { + ccc = STOPPER; + } else if ((ccc = LEAF_CCC(leaf)) == DECOMPOSE) { + u8c->len -= utf8clen(u8c->s); + u8c->p = u8c->s + utf8clen(u8c->s); + u8c->s = LEAF_STR(leaf); + /* Empty decomposition implies CCC 0. */ + if (*u8c->s == '\0') { + if (u8c->ccc == STOPPER) + continue; + ccc = STOPPER; + goto ccc_mismatch; + } + leaf = utf8lookup(u8c->data, u8c->s); + ccc = LEAF_CCC(leaf); + } + + /* + * If this is not a stopper, then see if it updates + * the next canonical class to be emitted. + */ + if (ccc != STOPPER && u8c->ccc < ccc && ccc < u8c->nccc) + u8c->nccc = ccc; + + /* + * Return the current byte if this is the current + * combining class. + */ + if (ccc == u8c->ccc) { + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Current combining class mismatch. */ + ccc_mismatch: + if (u8c->nccc == STOPPER) { + /* + * Scan forward for the first canonical class + * to be emitted. Save the position from + * which to restart. + */ + u8c->ccc = MINCCC - 1; + u8c->nccc = ccc; + u8c->sp = u8c->p; + u8c->ss = u8c->s; + u8c->slen = u8c->len; + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (ccc != STOPPER) { + /* Not a stopper, and not the ccc we're emitting. */ + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (u8c->nccc != MAXCCC + 1) { + /* At a stopper, restart for next ccc. */ + u8c->ccc = u8c->nccc; + u8c->nccc = MAXCCC + 1; + u8c->s = u8c->ss; + u8c->p = u8c->sp; + u8c->len = u8c->slen; + } else { + /* All done, proceed from here. */ + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->sp = NULL; + u8c->ss = NULL; + u8c->slen = 0; + } + } +} +EXPORT_SYMBOL(utf8byte); + +const struct utf8data * +utf8nfkdi(unsigned int maxage) +{ + int i = sizeof(utf8nfkdidata)/sizeof(utf8nfkdidata[0]) - 1; + + while (maxage < utf8nfkdidata[i].maxage) + i--; + if (maxage > utf8nfkdidata[i].maxage) + return NULL; + return &utf8nfkdidata[i]; +} +EXPORT_SYMBOL(utf8nfkdi); + +const struct utf8data * +utf8nfkdicf(unsigned int maxage) +{ + int i = sizeof(utf8nfkdicfdata)/sizeof(utf8nfkdicfdata[0]) - 1; + + while (maxage < utf8nfkdicfdata[i].maxage) + i--; + if (maxage > utf8nfkdicfdata[i].maxage) + return NULL; + return &utf8nfkdicfdata[i]; +} +EXPORT_SYMBOL(utf8nfkdicf); + +MODULE_AUTHOR("SGI"); +MODULE_DESCRIPTION("utf8 normalization"); +MODULE_LICENSE("GPL"); diff --git a/fs/xfs/utf8norm/utf8norm.h b/fs/xfs/utf8norm/utf8norm.h new file mode 100644 index 0000000..44a9e53 --- /dev/null +++ b/fs/xfs/utf8norm/utf8norm.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef UTF8NORM_H +#define UTF8NORM_H + +#include +#include +#include +#include + +/* An opaque type used to determine the normalization in use. */ +typedef const struct utf8data *utf8data_t; + +/* Encoding a unicode version number as a single unsigned int. */ +#define UNICODE_MAJ_SHIFT (16) +#define UNICODE_MIN_SHIFT (8) + +#define UNICODE_AGE(MAJ,MIN,REV) \ + (((unsigned int)(MAJ) << UNICODE_MAJ_SHIFT) | \ + ((unsigned int)(MIN) << UNICODE_MIN_SHIFT) | \ + ((unsigned int)(REV))) + +/* Highest unicode version supported by the data tables. */ +extern const unsigned int utf8version(void); + +/* + * Look for the correct utf8data_t for a unicode version. + * Returns NULL if the version requested is too new. + * + * Two normalization forms are supported: nfkdi and nfkdicf. + * + * nfkdi: + * - Apply unicode normalization form NFKD. + * - Remove any Default_Ignorable_Code_Point. + * + * nfkdicf: + * - Apply unicode normalization form NFKD. + * - Remove any Default_Ignorable_Code_Point. + * - Apply a full casefold (C + F). + */ +extern utf8data_t utf8nfkdi(unsigned int); +extern utf8data_t utf8nfkdicf(unsigned int); + +/* + * Determine the maximum age of any unicode character in the string. + * Returns 0 if only unassigned code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern int utf8agemax(utf8data_t, const char *); +extern int utf8nagemax(utf8data_t, const char *, size_t); + +/* + * Determine the minimum age of any unicode character in the string. + * Returns 0 if any unassigned code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern int utf8agemin(utf8data_t, const char *); +extern int utf8nagemin(utf8data_t, const char *, size_t); + +/* + * Determine the length of the normalized from of the string, + * excluding any terminating NULL byte. + * Returns 0 if only ignorable code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern ssize_t utf8len(utf8data_t, const char *); +extern ssize_t utf8nlen(utf8data_t, const char *, size_t); + +/* + * Cursor structure used by the normalizer. + */ +struct utf8cursor { + utf8data_t data; + const char *s; + const char *p; + const char *ss; + const char *sp; + unsigned int len; + unsigned int slen; + short int ccc; + short int nccc; +}; + +/* + * Initialize a utf8cursor to normalize a string. + * Returns 0 on success. + * Returns -1 on failure. + */ +extern int utf8cursor(struct utf8cursor *, utf8data_t, const char *); +extern int utf8ncursor(struct utf8cursor *, utf8data_t, const char *, size_t); + +/* + * Get the next byte in the normalization. + * Returns a value > 0 && < 256 on success. + * Returns 0 when the end of the normalization is reached. + * Returns -1 if the string being normalized is not valid UTF-8. + */ +extern int utf8byte(struct utf8cursor *); + +#endif /* UTF8NORM_H */ -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:16:30 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id DBE7A7F37 for ; Thu, 18 Sep 2014 15:16:29 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id 37B04AC002; Thu, 18 Sep 2014 13:16:29 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id D16C24266DC; Thu, 18 Sep 2014 15:16:28 -0500 (CDT) Date: Thu, 18 Sep 2014 15:16:28 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 08/10] xfs: add xfs_nameops for utf8 and utf8+casefold. Message-ID: <20140918201628.GK4482@sgi.com> References: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918195650.GI19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber The xfs_utf8_nameops use the nfkdi normalization when comparing filenames, and are installed if the utf8bit is set in the super block. The xfs_utf8_ci_nameops use the nfkdicf normalization when comparing filenames, and are installed if both the utf8bit and the borgbit are set in the superblock. Normalized filenames are not stored on disk. Normalization will fail if a filename is not valid UTF-8, in which case the filename is treated as an opaque blob. Signed-off-by: Olaf Weber --- [v2: updated to use utf8norm.ko module; compiled conditionally on CONFIG_XFS_UTF8=y; utf8version is now a function; move xfs_utf8.[ch] into libxfs. --bpm] --- fs/xfs/Makefile | 2 + fs/xfs/libxfs/xfs_dir2.c | 24 ++++- fs/xfs/libxfs/xfs_utf8.c | 242 +++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_utf8.h | 25 +++++ fs/xfs/xfs_iops.c | 2 +- 5 files changed, 290 insertions(+), 5 deletions(-) create mode 100644 fs/xfs/libxfs/xfs_utf8.c create mode 100644 fs/xfs/libxfs/xfs_utf8.h diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 6d000d3..5a4dfa0 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -114,6 +114,8 @@ xfs-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \ xfs_qm.o \ xfs_quotaops.o +xfs-$(CONFIG_XFS_UTF8) += libxfs/xfs_utf8.o + # xfs_rtbitmap is shared with libxfs xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 84e5ca9..e28736b 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -35,6 +35,7 @@ #include "xfs_error.h" #include "xfs_trace.h" #include "xfs_dinode.h" +#include "xfs_utf8.h" struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2, XFS_DIR3_FT_DIR }; @@ -156,10 +157,25 @@ xfs_da_mount( (uint)sizeof(xfs_da_node_entry_t); dageo->magicpct = (dageo->blksize * 37) / 100; - if (xfs_sb_version_hasasciici(&mp->m_sb)) - mp->m_dirnameops = &xfs_ascii_ci_nameops; - else - mp->m_dirnameops = &xfs_default_nameops; + if (xfs_sb_version_hasutf8(&mp->m_sb)) { +#ifdef CONFIG_XFS_UTF8 + if (xfs_sb_version_hasasciici(&mp->m_sb)) + mp->m_dirnameops = &xfs_utf8_ci_nameops; + else + mp->m_dirnameops = &xfs_utf8_nameops; +#else + xfs_warn(mp, + "Recompile XFS with CONFIG_XFS_UTF8 to mount this filesystem"); + kmem_free(mp->m_dir_geo); + kmem_free(mp->m_attr_geo); + return -ENOSYS; +#endif + } else { + if (xfs_sb_version_hasasciici(&mp->m_sb)) + mp->m_dirnameops = &xfs_ascii_ci_nameops; + else + mp->m_dirnameops = &xfs_default_nameops; + } return 0; } diff --git a/fs/xfs/libxfs/xfs_utf8.c b/fs/xfs/libxfs/xfs_utf8.c new file mode 100644 index 0000000..1e64c44 --- /dev/null +++ b/fs/xfs/libxfs/xfs_utf8.c @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "xfs.h" +#include "xfs_fs.h" +#include "xfs_types.h" +#include "xfs_bit.h" +#include "xfs_log_format.h" +#include "xfs_inum.h" +#include "xfs_trans.h" +#include "xfs_trans_resv.h" +#include "xfs_sb.h" +#include "xfs_ag.h" +#include "xfs_da_format.h" +#include "xfs_da_btree.h" +#include "xfs_dir2.h" +#include "xfs_mount.h" +#include "xfs_da_btree.h" +#include "xfs_format.h" +#include "xfs_bmap_btree.h" +#include "xfs_alloc_btree.h" +#include "xfs_dinode.h" +#include "xfs_inode.h" +#include "xfs_inode_item.h" +#include "xfs_bmap.h" +#include "xfs_error.h" +#include "xfs_trace.h" +#include "xfs_utf8.h" +#include + +/* + * xfs nameops using nfkdi + */ + +static xfs_dahash_t +xfs_utf8_hashname( + const unsigned char *name, + int len) +{ + utf8data_t nfkdi; + struct utf8cursor u8c; + xfs_dahash_t hash; + int val; + + nfkdi = utf8nfkdi(utf8version()); + hash = 0; + if (utf8ncursor(&u8c, nfkdi, name, len) < 0) + goto blob; + while ((val = utf8byte(&u8c)) > 0) + hash = val ^ rol32(hash, 7); + /* In case of error treat the name as a binary blob. */ + if (val == 0) + return hash; +blob: + return xfs_da_hashname(name, len); +} + +static int +xfs_utf8_normhash( + struct xfs_da_args *args) +{ + utf8data_t nfkdi; + struct utf8cursor u8c; + unsigned char *norm; + ssize_t normlen; + int c; + + nfkdi = utf8nfkdi(utf8version()); + /* Failure to normalize is treated as a blob. */ + if ((normlen = utf8nlen(nfkdi, args->name, args->namelen)) < 0) + goto blob; + if (utf8ncursor(&u8c, nfkdi, args->name, args->namelen) < 0) + goto blob; + if (!(norm = kmem_alloc(normlen + 1, KM_NOFS|KM_MAYFAIL))) + return -ENOMEM; + args->norm = norm; + args->normlen = normlen; + while ((c = utf8byte(&u8c)) > 0) + *norm++ = c; + if (c == 0) { + *norm = '\0'; + args->hashval = xfs_da_hashname(args->norm, args->normlen); + return 0; + } + kmem_free(args->norm); +blob: + args->norm = NULL; + args->normlen = -1; + args->hashval = xfs_da_hashname(args->name, args->namelen); + return 0; +} + +static enum xfs_dacmp +xfs_utf8_compname( + struct xfs_da_args *args, + const unsigned char *name, + int len) +{ + utf8data_t nfkdi; + struct utf8cursor u8c; + const unsigned char *norm; + int c; + + ASSERT(args->norm || args->normlen == -1); + + /* Check for an exact match first. */ + if (args->namelen == len && memcmp(args->name, name, len) == 0) + return XFS_CMP_EXACT; + /* xfs_utf8_normhash() set args->normlen to -1 for a blob */ + if (args->normlen < 0) + return XFS_CMP_DIFFERENT; + nfkdi = utf8nfkdi(utf8version()); + if (utf8ncursor(&u8c, nfkdi, name, len) < 0) + return XFS_CMP_DIFFERENT; + norm = args->norm; + while ((c = utf8byte(&u8c)) > 0) + if (c != *norm++) + return XFS_CMP_DIFFERENT; + if (c < 0 || *norm != '\0') + return XFS_CMP_DIFFERENT; + return XFS_CMP_MATCH; +} + +struct xfs_nameops xfs_utf8_nameops = { + .hashname = xfs_utf8_hashname, + .normhash = xfs_utf8_normhash, + .compname = xfs_utf8_compname, +}; + +/* + * xfs nameops using nfkdicf + */ + +static xfs_dahash_t +xfs_utf8_ci_hashname( + const unsigned char *name, + int len) +{ + utf8data_t nfkdicf; + struct utf8cursor u8c; + xfs_dahash_t hash; + int val; + + nfkdicf = utf8nfkdicf(utf8version()); + hash = 0; + if (utf8ncursor(&u8c, nfkdicf, name, len) < 0) + goto blob; + while ((val = utf8byte(&u8c)) > 0) + hash = val ^ rol32(hash, 7); + /* In case of error treat the name as a binary blob. */ + if (val == 0) + return hash; +blob: + return xfs_da_hashname(name, len); +} + +static int +xfs_utf8_ci_normhash( + struct xfs_da_args *args) +{ + utf8data_t nfkdicf; + struct utf8cursor u8c; + unsigned char *norm; + ssize_t normlen; + int c; + + nfkdicf = utf8nfkdicf(utf8version()); + /* Failure to normalize is treated as a blob. */ + if ((normlen = utf8nlen(nfkdicf, args->name, args->namelen)) < 0) + goto blob; + if (utf8ncursor(&u8c, nfkdicf, args->name, args->namelen) < 0) + goto blob; + if (!(norm = kmem_alloc(normlen + 1, KM_NOFS|KM_MAYFAIL))) + return -ENOMEM; + args->norm = norm; + args->normlen = normlen; + while ((c = utf8byte(&u8c)) > 0) + *norm++ = c; + if (c == 0) { + *norm = '\0'; + args->hashval = xfs_da_hashname(args->norm, args->normlen); + return 0; + } + kmem_free(args->norm); +blob: + args->norm = NULL; + args->normlen = -1; + args->hashval = xfs_da_hashname(args->name, args->namelen); + return 0; +} + +static enum xfs_dacmp +xfs_utf8_ci_compname( + struct xfs_da_args *args, + const unsigned char *name, + int len) +{ + utf8data_t nfkdicf; + struct utf8cursor u8c; + const unsigned char *norm; + int c; + + ASSERT(args->norm || args->normlen == -1); + + /* Check for an exact match first. */ + if (args->namelen == len && memcmp(args->name, name, len) == 0) + return XFS_CMP_EXACT; + /* xfs_utf8_ci_normhash() set args->normlen to -1 for a blob */ + if (args->normlen < 0) + return XFS_CMP_DIFFERENT; + nfkdicf = utf8nfkdicf(utf8version()); + if (utf8ncursor(&u8c, nfkdicf, name, len) < 0) + return XFS_CMP_DIFFERENT; + norm = args->norm; + while ((c = utf8byte(&u8c)) > 0) + if (c != *norm++) + return XFS_CMP_DIFFERENT; + if (c < 0 || *norm != '\0') + return XFS_CMP_DIFFERENT; + return XFS_CMP_MATCH; +} + +struct xfs_nameops xfs_utf8_ci_nameops = { + .hashname = xfs_utf8_ci_hashname, + .normhash = xfs_utf8_ci_normhash, + .compname = xfs_utf8_ci_compname, +}; diff --git a/fs/xfs/libxfs/xfs_utf8.h b/fs/xfs/libxfs/xfs_utf8.h new file mode 100644 index 0000000..97b6a91 --- /dev/null +++ b/fs/xfs/libxfs/xfs_utf8.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef XFS_UTF8_H +#define XFS_UTF8_H + +extern struct xfs_nameops xfs_utf8_nameops; +extern struct xfs_nameops xfs_utf8_ci_nameops; + +#endif /* XFS_UTF8_H */ diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index cea3d64..fbfb1bb 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -1257,7 +1257,7 @@ xfs_setup_inode( break; case S_IFDIR: lockdep_set_class(&ip->i_lock.mr_lock, &xfs_dir_ilock_class); - if (xfs_sb_version_hasasciici(&XFS_M(inode->i_sb)->m_sb)) + if (xfs_sb_version_hasci(&XFS_M(inode->i_sb)->m_sb)) inode->i_op = &xfs_dir_ci_inode_operations; else inode->i_op = &xfs_dir_inode_operations; -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:17:47 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id DDEAF7F37 for ; Thu, 18 Sep 2014 15:17:47 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id 625508F804B; Thu, 18 Sep 2014 13:17:47 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 2F5644266DC; Thu, 18 Sep 2014 15:17:47 -0500 (CDT) Date: Thu, 18 Sep 2014 15:17:47 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 09/10] xfs: apply utf-8 normalization rules to user extended attribute names Message-ID: <20140918201747.GL4482@sgi.com> References: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918195650.GI19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Apply the same rules for UTF-8 normalization to the names of user-defined extended attributes. System attributes are excluded because they are not user-visible in the first place, and the kernel is expected to know what it is doing when naming them. Signed-off-by: Olaf Weber --- fs/xfs/libxfs/xfs_attr.c | 56 ++++++++++++++++++++++++++++++++++++------- fs/xfs/libxfs/xfs_attr_leaf.c | 11 +++++++-- fs/xfs/libxfs/xfs_utf8.c | 7 ++++++ fs/xfs/xfs_attr_list.c | 11 ++++++++- 4 files changed, 74 insertions(+), 11 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 353fb42..68e7ce3 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -83,12 +83,14 @@ xfs_attr_args_init( const unsigned char *name, int flags) { + struct xfs_mount *mp = dp->i_mount; + int error; if (!name) return -EINVAL; memset(args, 0, sizeof(*args)); - args->geo = dp->i_mount->m_attr_geo; + args->geo = mp->m_attr_geo; args->whichfork = XFS_ATTR_FORK; args->dp = dp; args->flags = flags; @@ -97,7 +99,11 @@ xfs_attr_args_init( if (args->namelen >= MAXNAMELEN) return -EFAULT; /* match IRIX behaviour */ - args->hashval = xfs_da_hashname(args->name, args->namelen); + if (!xfs_sb_version_hasutf8(&mp->m_sb)) + args->hashval = xfs_da_hashname(args->name, args->namelen); + else if ((error = mp->m_dirnameops->normhash(args)) != 0) + return error; + return 0; } @@ -154,6 +160,9 @@ xfs_attr_get( error = xfs_attr_node_get(&args); xfs_iunlock(ip, lock_mode); + if (args.norm) + kmem_free(args.norm); + *valuelenp = args.valuelen; return error == -EEXIST ? 0 : error; } @@ -216,8 +225,11 @@ xfs_attr_set( return -EIO; error = xfs_attr_args_init(&args, dp, name, flags); - if (error) + if (error) { + if (args.norm) + kmem_free(args.norm); return error; + } args.value = value; args.valuelen = valuelen; @@ -227,8 +239,11 @@ xfs_attr_set( args.total = xfs_attr_calc_size(&args, &local); error = xfs_qm_dqattach(dp, 0); - if (error) + if (error) { + if (args.norm) + kmem_free(args.norm); return error; + } /* * If the inode doesn't have an attribute fork, add one. @@ -239,8 +254,11 @@ xfs_attr_set( XFS_ATTR_SF_ENTSIZE_BYNAME(args.namelen, valuelen); error = xfs_bmap_add_attrfork(dp, sf_size, rsvd); - if (error) + if (error) { + if (args.norm) + kmem_free(args.norm); return error; + } } /* @@ -270,6 +288,8 @@ xfs_attr_set( error = xfs_trans_reserve(args.trans, &tres, args.total, 0); if (error) { xfs_trans_cancel(args.trans, 0); + if (args.norm) + kmem_free(args.norm); return error; } xfs_ilock(dp, XFS_ILOCK_EXCL); @@ -280,6 +300,8 @@ xfs_attr_set( if (error) { xfs_iunlock(dp, XFS_ILOCK_EXCL); xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES); + if (args.norm) + kmem_free(args.norm); return error; } @@ -327,6 +349,8 @@ xfs_attr_set( XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (args.norm) + kmem_free(args.norm); return error ? error : err2; } @@ -388,7 +412,8 @@ xfs_attr_set( xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE); error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); - + if (args.norm) + kmem_free(args.norm); return error; out: @@ -397,6 +422,8 @@ out: XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); } xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (args.norm) + kmem_free(args.norm); return error; } @@ -425,8 +452,11 @@ xfs_attr_remove( return -ENOATTR; error = xfs_attr_args_init(&args, dp, name, flags); - if (error) + if (error) { + if (args.norm) + kmem_free(args.norm); return error; + } args.firstblock = &firstblock; args.flist = &flist; @@ -439,8 +469,11 @@ xfs_attr_remove( args.op_flags = XFS_DA_OP_OKNOENT; error = xfs_qm_dqattach(dp, 0); - if (error) + if (error) { + if (args.norm) + kmem_free(args.norm); return error; + } /* * Start our first transaction of the day. @@ -466,6 +499,8 @@ xfs_attr_remove( XFS_ATTRRM_SPACE_RES(mp), 0); if (error) { xfs_trans_cancel(args.trans, 0); + if (args.norm) + kmem_free(args.norm); return error; } @@ -506,6 +541,8 @@ xfs_attr_remove( xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE); error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (args.norm) + kmem_free(args.norm); return error; @@ -515,6 +552,9 @@ out: XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); } xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (args.norm) + kmem_free(args.norm); + return error; } diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index b1f73db..c991a88 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -661,6 +661,7 @@ int xfs_attr_shortform_to_leaf(xfs_da_args_t *args) { xfs_inode_t *dp; + struct xfs_mount *mp; xfs_attr_shortform_t *sf; xfs_attr_sf_entry_t *sfe; xfs_da_args_t nargs; @@ -673,6 +674,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) trace_xfs_attr_sf_to_leaf(args); dp = args->dp; + mp = dp->i_mount; ifp = dp->i_afp; sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; size = be16_to_cpu(sf->hdr.totsize); @@ -726,13 +728,18 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) nargs.namelen = sfe->namelen; nargs.value = &sfe->nameval[nargs.namelen]; nargs.valuelen = sfe->valuelen; - nargs.hashval = xfs_da_hashname(sfe->nameval, - sfe->namelen); nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags); + if (!xfs_sb_version_hasutf8(&mp->m_sb)) + nargs.hashval = xfs_da_hashname(sfe->nameval, + sfe->namelen); + else if ((error = mp->m_dirnameops->normhash(&nargs)) != 0) + goto out; error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */ ASSERT(error == -ENOATTR); error = xfs_attr3_leaf_add(bp, &nargs); ASSERT(error != -ENOSPC); + if (nargs.norm) + kmem_free(nargs.norm); if (error) goto out; sfe = XFS_ATTR_SF_NEXTENTRY(sfe); diff --git a/fs/xfs/libxfs/xfs_utf8.c b/fs/xfs/libxfs/xfs_utf8.c index 1e64c44..75f2b3a 100644 --- a/fs/xfs/libxfs/xfs_utf8.c +++ b/fs/xfs/libxfs/xfs_utf8.c @@ -38,6 +38,7 @@ #include "xfs_inode.h" #include "xfs_inode_item.h" #include "xfs_bmap.h" +#include "xfs_attr.h" #include "xfs_error.h" #include "xfs_trace.h" #include "xfs_utf8.h" @@ -80,6 +81,9 @@ xfs_utf8_normhash( ssize_t normlen; int c; + /* Don't normalize system attribute names. */ + if (args->flags & (ATTR_ROOT|ATTR_SECURE)) + goto blob; nfkdi = utf8nfkdi(utf8version()); /* Failure to normalize is treated as a blob. */ if ((normlen = utf8nlen(nfkdi, args->name, args->namelen)) < 0) @@ -179,6 +183,9 @@ xfs_utf8_ci_normhash( ssize_t normlen; int c; + /* Don't normalize system attribute names. */ + if (args->flags & (ATTR_ROOT|ATTR_SECURE)) + goto blob; nfkdicf = utf8nfkdicf(utf8version()); /* Failure to normalize is treated as a blob. */ if ((normlen = utf8nlen(nfkdicf, args->name, args->namelen)) < 0) diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index 62db83a..4075d54 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c @@ -76,12 +76,14 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) xfs_attr_shortform_t *sf; xfs_attr_sf_entry_t *sfe; xfs_inode_t *dp; + struct xfs_mount *mp; int sbsize, nsbuf, count, i; int error; ASSERT(context != NULL); dp = context->dp; ASSERT(dp != NULL); + mp = dp->i_mount; ASSERT(dp->i_afp != NULL); sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data; ASSERT(sf != NULL); @@ -154,7 +156,14 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) } sbp->entno = i; - sbp->hash = xfs_da_hashname(sfe->nameval, sfe->namelen); + /* ATTR_ROOT and ATTR_SECURE are never normalized. */ + if (!xfs_sb_version_hasutf8(&mp->m_sb) || + (sfe->flags & (ATTR_ROOT|ATTR_SECURE))) { + sbp->hash = xfs_da_hashname(sfe->nameval, sfe->namelen); + } else { + sbp->hash = mp->m_dirnameops->hashname(sfe->nameval, + sfe->namelen); + } sbp->name = sfe->nameval; sbp->namelen = sfe->namelen; /* These are bytes, and both on-disk, don't endian-flip */ -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:18:44 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id EF6417F37 for ; Thu, 18 Sep 2014 15:18:43 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6D205AC003; Thu, 18 Sep 2014 13:18:43 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 19F4E4266DC; Thu, 18 Sep 2014 15:18:43 -0500 (CDT) Date: Thu, 18 Sep 2014 15:18:43 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 10/10] xfs: implement demand load of utf8norm.ko Message-ID: <20140918201843.GM4482@sgi.com> References: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918195650.GI19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Ben Myers The utf8 normalization module is large and there is no need to have it loaded unless an xfs filesystem with utf8 enabled has been mounted. This loads utf8norm.ko at mount time for filesystems that need it. This is optional on CONFIG_XFS_UTF8_DEMAND_LOAD. Signed-off-by: Ben Myers --- fs/xfs/Kconfig | 10 +++++ fs/xfs/libxfs/xfs_dir2.c | 9 ++++ fs/xfs/libxfs/xfs_utf8.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_utf8.h | 5 +++ fs/xfs/xfs_super.c | 6 +++ 5 files changed, 134 insertions(+) diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig index a847857..69efd85c 100644 --- a/fs/xfs/Kconfig +++ b/fs/xfs/Kconfig @@ -103,3 +103,13 @@ config XFS_UTF8 Say Y here to enable utf8 normalization support in XFS. You will be able to mount and use filesystems created with the utf8 mkfs.xfs option. + +config XFS_UTF8_DEMAND_LOAD + bool "XFS loads UTF-8 normalization module on demand" + depends on XFS_FS + depends on XFS_UTF8 + help + Say Y here to enable on demand loading of the utf8 + normalization module. This enables the large nomalization + module to remain unloaded until a filesystem with utf8 support + is mounted. diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index e28736b..436738d 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -35,7 +35,9 @@ #include "xfs_error.h" #include "xfs_trace.h" #include "xfs_dinode.h" +#ifdef CONFIG_XFS_UTF8 #include "xfs_utf8.h" +#endif struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2, XFS_DIR3_FT_DIR }; @@ -159,6 +161,13 @@ xfs_da_mount( if (xfs_sb_version_hasutf8(&mp->m_sb)) { #ifdef CONFIG_XFS_UTF8 +#ifdef CONFIG_XFS_UTF8_DEMAND_LOAD + if (xfs_init_utf8_module(mp)) { + kmem_free(mp->m_dir_geo); + kmem_free(mp->m_attr_geo); + return -ENOSYS; + } +#endif /* CONFIG_XFS_UTF8_DEMAND_LOAD */ if (xfs_sb_version_hasasciici(&mp->m_sb)) mp->m_dirnameops = &xfs_utf8_ci_nameops; else diff --git a/fs/xfs/libxfs/xfs_utf8.c b/fs/xfs/libxfs/xfs_utf8.c index 75f2b3a..71978c8 100644 --- a/fs/xfs/libxfs/xfs_utf8.c +++ b/fs/xfs/libxfs/xfs_utf8.c @@ -44,6 +44,110 @@ #include "xfs_utf8.h" #include +#ifdef CONFIG_XFS_UTF8_DEMAND_LOAD +#include + +static DEFINE_SPINLOCK(utf8norm_lock); +static int utf8norm_initialized; + +static const unsigned int (*utf8version_func)(void); +static utf8data_t (*utf8nfkdi_func)(unsigned int); +static utf8data_t (*utf8nfkdicf_func)(unsigned int); +static ssize_t (*utf8nlen_func)(utf8data_t, const char *, size_t); +static int (*utf8ncursor_func)(struct utf8cursor *, utf8data_t, + const char *, size_t); +static int (*utf8byte_func)(struct utf8cursor *); + +static void +xfs_put_utf8_module_locked(void) +{ + if (utf8version_func) + symbol_put(utf8version); + + if (utf8nfkdi_func) + symbol_put(utf8nfkdi); + + if (utf8nfkdicf_func) + symbol_put(utf8nfkdicf); + + if (utf8nlen_func) + symbol_put(utf8nlen); + + if (utf8ncursor_func) + symbol_put(utf8ncursor); + + if (utf8byte_func) + symbol_put(utf8byte); +} + +void +xfs_put_utf8_module(void) +{ + spin_lock(&utf8norm_lock); + if (!utf8norm_initialized) { + spin_unlock(&utf8norm_lock); + return; + } + xfs_put_utf8_module_locked(); + spin_unlock(&utf8norm_lock); +} + +int +xfs_init_utf8_module(struct xfs_mount *mp) +{ + request_module("utf8norm"); + + spin_lock(&utf8norm_lock); + if (utf8norm_initialized) { + spin_unlock(&utf8norm_lock); + return 0; + } + + utf8version_func = symbol_get(utf8version); + if (!utf8version_func) + goto error; + + utf8nfkdi_func = symbol_get(utf8nfkdi); + if (!utf8nfkdi_func) + goto error; + + utf8nfkdicf_func = symbol_get(utf8nfkdicf); + if (!utf8nfkdicf_func) + goto error; + + utf8nlen_func = symbol_get(utf8nlen); + if (!utf8nlen_func) + goto error; + + utf8ncursor_func = symbol_get(utf8ncursor); + if (!utf8ncursor_func) + goto error; + + utf8byte_func = symbol_get(utf8byte); + if (!utf8byte_func) + goto error; + + utf8norm_initialized = 1; + spin_unlock(&utf8norm_lock); + return 0; +error: + xfs_put_utf8_module_locked(); + spin_unlock(&utf8norm_lock); + xfs_warn(mp, + "Failed to load utf8norm.ko which is required to " + "mount a filesystem with utf8 support."); + return -ENOSYS; +} + +#define utf8version (*utf8version_func) +#define utf8nfkdi (*utf8nfkdi_func) +#define utf8nfkdicf (*utf8nfkdicf_func) +#define utf8nlen (*utf8nlen_func) +#define utf8ncursor (*utf8ncursor_func) +#define utf8byte (*utf8byte_func) + +#endif /* CONFIG_XFS_UTF8_DEMAND_LOAD */ + /* * xfs nameops using nfkdi */ diff --git a/fs/xfs/libxfs/xfs_utf8.h b/fs/xfs/libxfs/xfs_utf8.h index 97b6a91..9d1125a 100644 --- a/fs/xfs/libxfs/xfs_utf8.h +++ b/fs/xfs/libxfs/xfs_utf8.h @@ -22,4 +22,9 @@ extern struct xfs_nameops xfs_utf8_nameops; extern struct xfs_nameops xfs_utf8_ci_nameops; +#ifdef CONFIG_XFS_UTF8_DEMAND_LOAD +extern int xfs_init_utf8_module(struct xfs_mount *); +extern void xfs_put_utf8_module(void); +#endif + #endif /* XFS_UTF8_H */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index b194652..050a949 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -47,6 +47,9 @@ #include "xfs_dinode.h" #include "xfs_filestream.h" #include "xfs_quota.h" +#ifdef CONFIG_XFS_UTF8_DEMAND_LOAD +#include "xfs_utf8.h" +#endif #include #include @@ -1809,6 +1812,9 @@ exit_xfs_fs(void) xfs_mru_cache_uninit(); xfs_destroy_workqueues(); xfs_destroy_zones(); +#ifdef CONFIG_XFS_UTF8_DEMAND_LOAD + xfs_put_utf8_module(); +#endif } module_init(init_xfs_fs); -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:31:15 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 0ACF17F37 for ; Thu, 18 Sep 2014 15:31:15 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8A82CAC003; Thu, 18 Sep 2014 13:31:14 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 3C5744266DC; Thu, 18 Sep 2014 15:31:14 -0500 (CDT) Date: Thu, 18 Sep 2014 15:31:14 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 00/13] xfsprogs: Unicode/UTF-8 support for XFS Message-ID: <20140918203114.GN4482@sgi.com> References: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918195650.GI19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) Hi, Here is the xfsprogs portion of the Unicode/UTF-8 support. A number of the patches in libxfs correspond with kernel patches previously posted, and then there are patches to add support to mkfs, xfs_info, xfs_repair, and a test. (Note that the Unicode character database files have also been removed here due to their size.) Thanks, Ben From bpm@sgi.com Thu Sep 18 15:33:17 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 8B7A87F37 for ; Thu, 18 Sep 2014 15:33:17 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay2.corp.sgi.com (Postfix) with ESMTP id 58D77304032; Thu, 18 Sep 2014 13:33:17 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 207A94266DC; Thu, 18 Sep 2014 15:33:17 -0500 (CDT) Date: Thu, 18 Sep 2014 15:33:17 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 01/13] libxfs: return the first match during case-insensitive lookup Message-ID: <20140918203317.GO4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918203114.GN4482@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Change the XFS case-insensitive lookup code to return the first match found, even if it is not an exact match. Whether a filesystem uses case-insensitive lookups is determined by a superblock bit set during filesystem creation. This means that normal use cannot create two files that both match the same filename. Signed-off-by: Olaf Weber --- libxfs/xfs_dir2_block.c | 17 ++++------- libxfs/xfs_dir2_leaf.c | 38 ++++------------------- libxfs/xfs_dir2_node.c | 80 ++++++++++++++++++------------------------------- libxfs/xfs_dir2_sf.c | 8 ++--- 4 files changed, 44 insertions(+), 99 deletions(-) diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c index cede01f..2880431 100644 --- a/libxfs/xfs_dir2_block.c +++ b/libxfs/xfs_dir2_block.c @@ -705,28 +705,21 @@ xfs_dir2_block_lookup_int( dep = (xfs_dir2_data_entry_t *) ((char *)hdr + xfs_dir2_dataptr_to_off(mp, addr)); /* - * Compare name and if it's an exact match, return the index - * and buffer. If it's the first case-insensitive match, store - * the index and buffer and continue looking for an exact match. + * Compare name and if it's a match, return the + * index and buffer. */ cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); - if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { + if (cmp != XFS_CMP_DIFFERENT) { args->cmpresult = cmp; *bpp = bp; *entno = mid; - if (cmp == XFS_CMP_EXACT) - return 0; + return 0; } } while (++mid < be32_to_cpu(btp->count) && be32_to_cpu(blp[mid].hashval) == hash); ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); - /* - * Here, we can only be doing a lookup (not a rename or replace). - * If a case-insensitive match was found earlier, return success. - */ - if (args->cmpresult == XFS_CMP_CASE) - return 0; + ASSERT(args->cmpresult == XFS_CMP_DIFFERENT); /* * No match, release the buffer and return ENOENT. */ diff --git a/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c index 8e0cbc9..b1901d3 100644 --- a/libxfs/xfs_dir2_leaf.c +++ b/libxfs/xfs_dir2_leaf.c @@ -1246,7 +1246,6 @@ xfs_dir2_leaf_lookup_int( xfs_mount_t *mp; /* filesystem mount point */ xfs_dir2_db_t newdb; /* new data block number */ xfs_trans_t *tp; /* transaction pointer */ - xfs_dir2_db_t cidb = -1; /* case match data block no. */ enum xfs_dacmp cmp; /* name compare result */ struct xfs_dir2_leaf_entry *ents; struct xfs_dir3_icleaf_hdr leafhdr; @@ -1307,47 +1306,22 @@ xfs_dir2_leaf_lookup_int( dep = (xfs_dir2_data_entry_t *)((char *)dbp->b_addr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); /* - * Compare name and if it's an exact match, return the index - * and buffer. If it's the first case-insensitive match, store - * the index and buffer and continue looking for an exact match. + * Compare name and if it's a match, return the index + * and buffer. */ cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); - if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { + if (cmp != XFS_CMP_DIFFERENT) { args->cmpresult = cmp; *indexp = index; - /* case exact match: return the current buffer. */ - if (cmp == XFS_CMP_EXACT) { - *dbpp = dbp; - return 0; - } - cidb = curdb; + *dbpp = dbp; + return 0; } } ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); - /* - * Here, we can only be doing a lookup (not a rename or remove). - * If a case-insensitive match was found earlier, re-read the - * appropriate data block if required and return it. - */ - if (args->cmpresult == XFS_CMP_CASE) { - ASSERT(cidb != -1); - if (cidb != curdb) { - xfs_trans_brelse(tp, dbp); - error = xfs_dir3_data_read(tp, dp, - xfs_dir2_db_to_da(mp, cidb), - -1, &dbp); - if (error) { - xfs_trans_brelse(tp, lbp); - return error; - } - } - *dbpp = dbp; - return 0; - } + ASSERT(args->cmpresult == XFS_CMP_DIFFERENT); /* * No match found, return ENOENT. */ - ASSERT(cidb == -1); if (dbp) xfs_trans_brelse(tp, dbp); xfs_trans_brelse(tp, lbp); diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c index 3737e4e..fb27506 100644 --- a/libxfs/xfs_dir2_node.c +++ b/libxfs/xfs_dir2_node.c @@ -702,6 +702,7 @@ xfs_dir2_leafn_lookup_for_entry( xfs_dir2_db_t curdb = -1; /* current data block number */ xfs_dir2_data_entry_t *dep; /* data block entry */ xfs_inode_t *dp; /* incore directory inode */ + int di = -1; /* data entry index */ int error; /* error return value */ int index; /* leaf entry index */ xfs_dir2_leaf_t *leaf; /* leaf structure */ @@ -733,6 +734,7 @@ xfs_dir2_leafn_lookup_for_entry( if (state->extravalid) { curbp = state->extrablk.bp; curdb = state->extrablk.blkno; + di = state->extrablk.index; } /* * Loop over leaf entries with the right hash value. @@ -757,27 +759,20 @@ xfs_dir2_leafn_lookup_for_entry( */ if (newdb != curdb) { /* - * If we had a block before that we aren't saving - * for a CI name, drop it + * If we had a block, drop it */ - if (curbp && (args->cmpresult == XFS_CMP_DIFFERENT || - curdb != state->extrablk.blkno)) + if (curbp) { xfs_trans_brelse(tp, curbp); + di = -1; + } /* - * If needing the block that is saved with a CI match, - * use it otherwise read in the new data block. + * Read in the new data block. */ - if (args->cmpresult != XFS_CMP_DIFFERENT && - newdb == state->extrablk.blkno) { - ASSERT(state->extravalid); - curbp = state->extrablk.bp; - } else { - error = xfs_dir3_data_read(tp, dp, - xfs_dir2_db_to_da(mp, newdb), - -1, &curbp); - if (error) - return error; - } + error = xfs_dir3_data_read(tp, dp, + xfs_dir2_db_to_da(mp, newdb), + -1, &curbp); + if (error) + return error; xfs_dir3_data_check(dp, curbp); curdb = newdb; } @@ -787,53 +782,36 @@ xfs_dir2_leafn_lookup_for_entry( dep = (xfs_dir2_data_entry_t *)((char *)curbp->b_addr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); /* - * Compare the entry and if it's an exact match, return - * EEXIST immediately. If it's the first case-insensitive - * match, store the block & inode number and continue looking. + * Compare the entry and if it's a match, return + * EEXIST immediately. */ cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); - if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { - /* If there is a CI match block, drop it */ - if (args->cmpresult != XFS_CMP_DIFFERENT && - curdb != state->extrablk.blkno) - xfs_trans_brelse(tp, state->extrablk.bp); + if (cmp != XFS_CMP_DIFFERENT) { args->cmpresult = cmp; args->inumber = be64_to_cpu(dep->inumber); args->filetype = xfs_dir3_dirent_get_ftype(mp, dep); - *indexp = index; - state->extravalid = 1; - state->extrablk.bp = curbp; - state->extrablk.blkno = curdb; - state->extrablk.index = (int)((char *)dep - - (char *)curbp->b_addr); - state->extrablk.magic = XFS_DIR2_DATA_MAGIC; - curbp->b_ops = &xfs_dir3_data_buf_ops; - xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF); - if (cmp == XFS_CMP_EXACT) - return XFS_ERROR(EEXIST); + error = EEXIST; + goto out; } } + /* Didn't find a match */ + error = ENOENT; ASSERT(index == leafhdr.count || (args->op_flags & XFS_DA_OP_OKNOENT)); +out: if (curbp) { - if (args->cmpresult == XFS_CMP_DIFFERENT) { - /* Giving back last used data block. */ - state->extravalid = 1; - state->extrablk.bp = curbp; - state->extrablk.index = -1; - state->extrablk.blkno = curdb; - state->extrablk.magic = XFS_DIR2_DATA_MAGIC; - curbp->b_ops = &xfs_dir3_data_buf_ops; - xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF); - } else { - /* If the curbp is not the CI match block, drop it */ - if (state->extrablk.bp != curbp) - xfs_trans_brelse(tp, curbp); - } + /* Giving back last used data block. */ + state->extravalid = 1; + state->extrablk.bp = curbp; + state->extrablk.index = di; + state->extrablk.blkno = curdb; + state->extrablk.magic = XFS_DIR2_DATA_MAGIC; + curbp->b_ops = &xfs_dir3_data_buf_ops; + xfs_trans_buf_set_type(tp, curbp, XFS_BLFT_DIR_DATA_BUF); } else { state->extravalid = 0; } *indexp = index; - return XFS_ERROR(ENOENT); + return XFS_ERROR(error); } /* diff --git a/libxfs/xfs_dir2_sf.c b/libxfs/xfs_dir2_sf.c index 7580333..7b01d43 100644 --- a/libxfs/xfs_dir2_sf.c +++ b/libxfs/xfs_dir2_sf.c @@ -833,13 +833,12 @@ xfs_dir2_sf_lookup( for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; i++, sfep = xfs_dir3_sf_nextentry(dp->i_mount, sfp, sfep)) { /* - * Compare name and if it's an exact match, return the inode - * number. If it's the first case-insensitive match, store the - * inode number and continue looking for an exact match. + * Compare name and if it's a match, return the inode + * number. */ cmp = dp->i_mount->m_dirnameops->compname(args, sfep->name, sfep->namelen); - if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { + if (cmp != XFS_CMP_DIFFERENT) { args->cmpresult = cmp; args->inumber = xfs_dir3_sfe_get_ino(dp->i_mount, sfp, sfep); @@ -848,6 +847,7 @@ xfs_dir2_sf_lookup( if (cmp == XFS_CMP_EXACT) return XFS_ERROR(EEXIST); ci_sfep = sfep; + break; } } ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:33:53 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id E3B8B7F37 for ; Thu, 18 Sep 2014 15:33:53 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay2.corp.sgi.com (Postfix) with ESMTP id AAD83304032; Thu, 18 Sep 2014 13:33:53 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 7DE754266DC; Thu, 18 Sep 2014 15:33:53 -0500 (CDT) Date: Thu, 18 Sep 2014 15:33:53 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 02/13] libxfs: rename XFS_CMP_CASE to XFS_CMP_MATCH Message-ID: <20140918203353.GP4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918203114.GN4482@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Rename XFS_CMP_CASE to XFS_CMP_MATCH. With unicode filenames and normalization, different strings will match on other criteria than case insensitivity. Signed-off-by: Olaf Weber --- include/xfs_da_btree.h | 2 +- libxfs/xfs_dir2.c | 9 ++++++--- libxfs/xfs_dir2_node.c | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/xfs_da_btree.h b/include/xfs_da_btree.h index e492dca..3d9f9dd 100644 --- a/include/xfs_da_btree.h +++ b/include/xfs_da_btree.h @@ -34,7 +34,7 @@ struct zone; enum xfs_dacmp { XFS_CMP_DIFFERENT, /* names are completely different */ XFS_CMP_EXACT, /* names are exactly the same */ - XFS_CMP_CASE /* names are same but differ in case */ + XFS_CMP_MATCH /* names are same but differ in encoding */ }; /* diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index 4c8c836..57e98a3 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -72,7 +72,7 @@ xfs_ascii_ci_compname( continue; if (tolower(args->name[i]) != tolower(name[i])) return XFS_CMP_DIFFERENT; - result = XFS_CMP_CASE; + result = XFS_CMP_MATCH; } return result; @@ -248,8 +248,11 @@ xfs_dir_cilookup_result( { if (args->cmpresult == XFS_CMP_DIFFERENT) return ENOENT; - if (args->cmpresult != XFS_CMP_CASE || - !(args->op_flags & XFS_DA_OP_CILOOKUP)) + if (args->cmpresult == XFS_CMP_EXACT) + return EEXIST; + ASSERT(args->cmpresult == XFS_CMP_MATCH); + /* Only dup the found name if XFS_DA_OP_CILOOKUP is set. */ + if (!(args->op_flags & XFS_DA_OP_CILOOKUP)) return EEXIST; args->value = kmem_alloc(len, KM_NOFS | KM_MAYFAIL); diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c index fb27506..550ca99 100644 --- a/libxfs/xfs_dir2_node.c +++ b/libxfs/xfs_dir2_node.c @@ -2034,7 +2034,7 @@ xfs_dir2_node_lookup( error = xfs_da3_node_lookup_int(state, &rval); if (error) rval = error; - else if (rval == ENOENT && args->cmpresult == XFS_CMP_CASE) { + else if (rval == ENOENT && args->cmpresult == XFS_CMP_MATCH) { /* If a CI match, dup the actual name and return EEXIST */ xfs_dir2_data_entry_t *dep; -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:34:39 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id BB2CA7F37 for ; Thu, 18 Sep 2014 15:34:39 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8953B304032; Thu, 18 Sep 2014 13:34:39 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 4AFD84266DC; Thu, 18 Sep 2014 15:34:39 -0500 (CDT) Date: Thu, 18 Sep 2014 15:34:39 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 03/13] libxfs: add xfs_nameops.normhash Message-ID: <20140918203439.GQ4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918203114.GN4482@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Add a normhash callout to the xfs_nameops. This callout takes an xfs_da_args structure as its argument, and calculates a hash value over the name. It may in the process create a normalized form of the name, and assign that to the norm/normlen fields in the xfs_da_args structure. Changes: The pointer in kmem_free() was type converted to suppress compiler warnings. Signed-off-by: Olaf Weber --- include/xfs_da_btree.h | 5 ++++- libxfs/xfs_da_btree.c | 9 ++++++++ libxfs/xfs_dir2.c | 56 +++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/include/xfs_da_btree.h b/include/xfs_da_btree.h index 3d9f9dd..06b50bf 100644 --- a/include/xfs_da_btree.h +++ b/include/xfs_da_btree.h @@ -42,7 +42,9 @@ enum xfs_dacmp { */ typedef struct xfs_da_args { const __uint8_t *name; /* string (maybe not NULL terminated) */ - int namelen; /* length of string (maybe no NULL) */ + const __uint8_t *norm; /* normalized name (may be NULL) */ + int namelen; /* length of string (maybe no NULL) */ + int normlen; /* length of normalized name */ __uint8_t filetype; /* filetype of inode for directories */ __uint8_t *value; /* set of bytes (maybe contain NULLs) */ int valuelen; /* length of value */ @@ -131,6 +133,7 @@ typedef struct xfs_da_state { */ struct xfs_nameops { xfs_dahash_t (*hashname)(struct xfs_name *); + int (*normhash)(struct xfs_da_args *); enum xfs_dacmp (*compname)(struct xfs_da_args *, const unsigned char *, int); }; diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c index b731b54..eb97317 100644 --- a/libxfs/xfs_da_btree.c +++ b/libxfs/xfs_da_btree.c @@ -2000,8 +2000,17 @@ xfs_default_hashname( return xfs_da_hashname(name->name, name->len); } +STATIC int +xfs_da_normhash( + struct xfs_da_args *args) +{ + args->hashval = xfs_da_hashname(args->name, args->namelen); + return 0; +} + const struct xfs_nameops xfs_default_nameops = { .hashname = xfs_default_hashname, + .normhash = xfs_da_normhash, .compname = xfs_da_compname }; diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index 57e98a3..e52d082 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -54,6 +54,21 @@ xfs_ascii_ci_hashname( return hash; } +STATIC int +xfs_ascii_ci_normhash( + struct xfs_da_args *args) +{ + xfs_dahash_t hash; + int i; + + for (i = 0, hash = 0; i < args->namelen; i++) + hash = tolower(args->name[i]) ^ rol32(hash, 7); + + args->hashval = hash; + return 0; +} + + STATIC enum xfs_dacmp xfs_ascii_ci_compname( struct xfs_da_args *args, @@ -80,6 +95,7 @@ xfs_ascii_ci_compname( static struct xfs_nameops xfs_ascii_ci_nameops = { .hashname = xfs_ascii_ci_hashname, + .normhash = xfs_ascii_ci_normhash, .compname = xfs_ascii_ci_compname, }; @@ -211,7 +227,6 @@ xfs_dir_createname( args.name = name->name; args.namelen = name->len; args.filetype = name->type; - args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = inum; args.dp = dp; args.firstblock = first; @@ -220,19 +235,24 @@ xfs_dir_createname( args.whichfork = XFS_DATA_FORK; args.trans = tp; args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; + if ((rval = dp->i_mount->m_dirnameops->normhash(&args))) + return rval; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_addname(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_block_addname(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_leaf_addname(&args); else rval = xfs_dir2_node_addname(&args); +out_free: + if (args.norm) + kmem_free((void *)args.norm); return rval; } @@ -289,22 +309,23 @@ xfs_dir_lookup( args.name = name->name; args.namelen = name->len; args.filetype = name->type; - args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.dp = dp; args.whichfork = XFS_DATA_FORK; args.trans = tp; args.op_flags = XFS_DA_OP_OKNOENT; if (ci_name) args.op_flags |= XFS_DA_OP_CILOOKUP; + if ((rval = dp->i_mount->m_dirnameops->normhash(&args))) + return rval; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_lookup(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_block_lookup(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_leaf_lookup(&args); else @@ -318,6 +339,9 @@ xfs_dir_lookup( ci_name->len = args.valuelen; } } +out_free: + if (args.norm) + kmem_free((void *)args.norm); return rval; } @@ -345,7 +369,6 @@ xfs_dir_removename( args.name = name->name; args.namelen = name->len; args.filetype = name->type; - args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = ino; args.dp = dp; args.firstblock = first; @@ -353,19 +376,24 @@ xfs_dir_removename( args.total = total; args.whichfork = XFS_DATA_FORK; args.trans = tp; + if ((rval = dp->i_mount->m_dirnameops->normhash(&args))) + return rval; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_removename(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_block_removename(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_leaf_removename(&args); else rval = xfs_dir2_node_removename(&args); +out_free: + if (args.norm) + kmem_free((void *)args.norm); return rval; } @@ -395,7 +423,6 @@ xfs_dir_replace( args.name = name->name; args.namelen = name->len; args.filetype = name->type; - args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = inum; args.dp = dp; args.firstblock = first; @@ -403,19 +430,24 @@ xfs_dir_replace( args.total = total; args.whichfork = XFS_DATA_FORK; args.trans = tp; + if ((rval = dp->i_mount->m_dirnameops->normhash(&args))) + return rval; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_replace(&args); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_block_replace(&args); else if ((rval = xfs_dir2_isleaf(tp, dp, &v))) - return rval; + goto out_free; else if (v) rval = xfs_dir2_leaf_replace(&args); else rval = xfs_dir2_node_replace(&args); +out_free: + if (args.norm) + kmem_free((void *)args.norm); return rval; } -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:35:55 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D94787F37 for ; Thu, 18 Sep 2014 15:35:55 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id B61B18F8040; Thu, 18 Sep 2014 13:35:55 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 7D1DC4266DC; Thu, 18 Sep 2014 15:35:55 -0500 (CDT) Date: Thu, 18 Sep 2014 15:35:55 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 04/13] libxfs: change interface of xfs_nameops.normhash Message-ID: <20140918203555.GR4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918203114.GN4482@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber With the introduction of the xfs_nameops.normhash callout, all uses of the hashname callout now occur in places where an xfs_name structure must be explicitly created just to match the parameter passing convention of this callout. Change the arguments to a const unsigned char * and int instead. Signed-off-by: Olaf Weber --- db/check.c | 6 ++---- include/xfs_da_btree.h | 2 +- libxfs/xfs_da_btree.c | 9 +-------- libxfs/xfs_dir2.c | 10 ++++++---- libxfs/xfs_dir2_block.c | 5 +---- libxfs/xfs_dir2_data.c | 6 ++---- repair/phase6.c | 2 +- 7 files changed, 14 insertions(+), 26 deletions(-) diff --git a/db/check.c b/db/check.c index 4fd9fd0..49359d7 100644 --- a/db/check.c +++ b/db/check.c @@ -2212,7 +2212,6 @@ process_data_dir_v2( int stale = 0; int tag_err; __be16 *tagp; - struct xfs_name xname; data = iocur_top->data; block = iocur_top->data; @@ -2323,9 +2322,8 @@ process_data_dir_v2( tag_err += be16_to_cpu(*tagp) != (char *)dep - (char *)data; addr = xfs_dir2_db_off_to_dataptr(mp, db, (char *)dep - (char *)data); - xname.name = dep->name; - xname.len = dep->namelen; - dir_hash_add(mp->m_dirnameops->hashname(&xname), addr); + dir_hash_add(mp->m_dirnameops->hashname(dep->name, + dep->namelen), addr); ptr += xfs_dir3_data_entsize(mp, dep->namelen); count++; lastfree = 0; diff --git a/include/xfs_da_btree.h b/include/xfs_da_btree.h index 06b50bf..9674bed 100644 --- a/include/xfs_da_btree.h +++ b/include/xfs_da_btree.h @@ -132,7 +132,7 @@ typedef struct xfs_da_state { * Name ops for directory and/or attr name operations */ struct xfs_nameops { - xfs_dahash_t (*hashname)(struct xfs_name *); + xfs_dahash_t (*hashname)(const unsigned char *, int); int (*normhash)(struct xfs_da_args *); enum xfs_dacmp (*compname)(struct xfs_da_args *, const unsigned char *, int); diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c index eb97317..7be5eaf 100644 --- a/libxfs/xfs_da_btree.c +++ b/libxfs/xfs_da_btree.c @@ -1993,13 +1993,6 @@ xfs_da_compname( XFS_CMP_EXACT : XFS_CMP_DIFFERENT; } -static xfs_dahash_t -xfs_default_hashname( - struct xfs_name *name) -{ - return xfs_da_hashname(name->name, name->len); -} - STATIC int xfs_da_normhash( struct xfs_da_args *args) @@ -2009,7 +2002,7 @@ xfs_da_normhash( } const struct xfs_nameops xfs_default_nameops = { - .hashname = xfs_default_hashname, + .hashname = xfs_da_hashname, .normhash = xfs_da_normhash, .compname = xfs_da_compname }; diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index e52d082..1893931 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -43,13 +43,14 @@ const unsigned char xfs_mode_to_ftype[S_IFMT >> S_SHIFT] = { */ STATIC xfs_dahash_t xfs_ascii_ci_hashname( - struct xfs_name *name) + const unsigned char *name, + int len) { xfs_dahash_t hash; int i; - for (i = 0, hash = 0; i < name->len; i++) - hash = tolower(name->name[i]) ^ rol32(hash, 7); + for (i = 0, hash = 0; i < len; i++) + hash = tolower(name[i]) ^ rol32(hash, 7); return hash; } @@ -475,7 +476,8 @@ xfs_dir_canenter( args.name = name->name; args.namelen = name->len; args.filetype = name->type; - args.hashval = dp->i_mount->m_dirnameops->hashname(name); + args.hashval = dp->i_mount->m_dirnameops->hashname(name->name, + name->len); args.dp = dp; args.whichfork = XFS_DATA_FORK; args.trans = tp; diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c index 2880431..1a8b5f5 100644 --- a/libxfs/xfs_dir2_block.c +++ b/libxfs/xfs_dir2_block.c @@ -1047,7 +1047,6 @@ xfs_dir2_sf_to_block( xfs_dir2_sf_hdr_t *sfp; /* shortform header */ __be16 *tagp; /* end of data entry */ xfs_trans_t *tp; /* transaction pointer */ - struct xfs_name name; struct xfs_ifork *ifp; trace_xfs_dir2_sf_to_block(args); @@ -1205,10 +1204,8 @@ xfs_dir2_sf_to_block( tagp = xfs_dir3_data_entry_tag_p(mp, dep); *tagp = cpu_to_be16((char *)dep - (char *)hdr); xfs_dir2_data_log_entry(tp, bp, dep); - name.name = sfep->name; - name.len = sfep->namelen; blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops-> - hashname(&name)); + hashname(sfep->name, sfep->namelen)); blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, (char *)dep - (char *)hdr)); offset = (int)((char *)(tagp + 1) - (char *)hdr); diff --git a/libxfs/xfs_dir2_data.c b/libxfs/xfs_dir2_data.c index dc9df4d..9b3f750 100644 --- a/libxfs/xfs_dir2_data.c +++ b/libxfs/xfs_dir2_data.c @@ -46,7 +46,6 @@ __xfs_dir3_data_check( xfs_mount_t *mp; /* filesystem mount point */ char *p; /* current data position */ int stale; /* count of stale leaves */ - struct xfs_name name; mp = bp->b_target->bt_mount; hdr = bp->b_addr; @@ -142,9 +141,8 @@ __xfs_dir3_data_check( addr = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, (xfs_dir2_data_aoff_t) ((char *)dep - (char *)hdr)); - name.name = dep->name; - name.len = dep->namelen; - hash = mp->m_dirnameops->hashname(&name); + hash = mp->m_dirnameops-> + hashname(dep->name, dep->namelen); for (i = 0; i < be32_to_cpu(btp->count); i++) { if (be32_to_cpu(lep[i].address) == addr && be32_to_cpu(lep[i].hashval) == hash) diff --git a/repair/phase6.c b/repair/phase6.c index f13069f..f374fd0 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -195,7 +195,7 @@ dir_hash_add( dup = 0; if (!junk) { - hash = mp->m_dirnameops->hashname(&xname); + hash = mp->m_dirnameops->hashname(name, namelen); byhash = DIR_HASH_FUNC(hashtab, hash); /* -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:36:39 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 15F247F37 for ; Thu, 18 Sep 2014 15:36:39 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id D14418F804B; Thu, 18 Sep 2014 13:36:38 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 9DD544266DC; Thu, 18 Sep 2014 15:36:38 -0500 (CDT) Date: Thu, 18 Sep 2014 15:36:38 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 05/13] libxfs: add a superblock feature bit to indicate UTF-8 support. Message-ID: <20140918203638.GS4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918203114.GN4482@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber When UTF-8 support is enabled, the xfs_dir_ci_inode_operations must be installed. Add xfs_sb_version_hasci(), which tests both the borgbit and the utf8bit, and returns true if at least one of them is set. Replace calls to xfs_sb_version_hasasciici() as needed. Signed-off-by: Olaf Weber --- include/xfs_fs.h | 2 +- include/xfs_sb.h | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/include/xfs_fs.h b/include/xfs_fs.h index 59c40fc..1be539d 100644 --- a/include/xfs_fs.h +++ b/include/xfs_fs.h @@ -239,7 +239,7 @@ typedef struct xfs_fsop_resblks { #define XFS_FSOP_GEOM_FLAGS_V5SB 0x8000 /* version 5 superblock */ #define XFS_FSOP_GEOM_FLAGS_FTYPE 0x10000 /* inode directory types */ #define XFS_FSOP_GEOM_FLAGS_FINOBT 0x20000 /* free inode btree */ - +#define XFS_FSOP_GEOM_FLAGS_UTF8 0x40000 /* utf8 filenames */ /* * Minimum and maximum sizes need for growth checks. diff --git a/include/xfs_sb.h b/include/xfs_sb.h index 950d1ea..5ac7f06 100644 --- a/include/xfs_sb.h +++ b/include/xfs_sb.h @@ -82,6 +82,8 @@ struct xfs_trans; #define XFS_SB_VERSION2_RESERVED4BIT 0x00000004 #define XFS_SB_VERSION2_ATTR2BIT 0x00000008 /* Inline attr rework */ #define XFS_SB_VERSION2_PARENTBIT 0x00000010 /* parent pointers */ +#define XFS_SB_VERSION2_PARENTBIT 0x00000010 /* parent pointers */ +#define XFS_SB_VERSION2_UTF8BIT 0x00000020 /* utf8 names */ #define XFS_SB_VERSION2_PROJID32BIT 0x00000080 /* 32 bit project id */ #define XFS_SB_VERSION2_CRCBIT 0x00000100 /* metadata CRCs */ #define XFS_SB_VERSION2_FTYPE 0x00000200 /* inode type in dir */ @@ -89,6 +91,7 @@ struct xfs_trans; #define XFS_SB_VERSION2_OKREALFBITS \ (XFS_SB_VERSION2_LAZYSBCOUNTBIT | \ XFS_SB_VERSION2_ATTR2BIT | \ + XFS_SB_VERSION2_UTF8BIT | \ XFS_SB_VERSION2_PROJID32BIT | \ XFS_SB_VERSION2_FTYPE) #define XFS_SB_VERSION2_OKSASHFBITS \ @@ -600,8 +603,10 @@ xfs_sb_has_ro_compat_feature( } #define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ +#define XFS_SB_FEAT_INCOMPAT_UTF8 (1 << 1) /* utf-8 name support */ #define XFS_SB_FEAT_INCOMPAT_ALL \ - (XFS_SB_FEAT_INCOMPAT_FTYPE) + (XFS_SB_FEAT_INCOMPAT_FTYPE | \ + XFS_SB_FEAT_INCOMPAT_UTF8) #define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool @@ -649,6 +654,24 @@ static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp) (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_FINOBT); } +static inline int xfs_sb_version_hasutf8(xfs_sb_t *sbp) +{ + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 && + xfs_sb_has_incompat_feature(sbp, XFS_SB_FEAT_INCOMPAT_UTF8)) || + (xfs_sb_version_hasmorebits(sbp) && + (sbp->sb_features2 & XFS_SB_VERSION2_UTF8BIT)); +} + +/* + * Special case: there are a number of places where we need to test + * both the borgbit and the utf8bit, and take the same action if + * either of those is set. + */ +static inline int xfs_sb_version_hasci(xfs_sb_t *sbp) +{ + return xfs_sb_version_hasasciici(sbp) || xfs_sb_version_hasutf8(sbp); +} + /* * end of superblock version macros */ -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:37:17 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D11817F37 for ; Thu, 18 Sep 2014 15:37:17 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5FE9CAC002; Thu, 18 Sep 2014 13:37:17 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 245C54266DC; Thu, 18 Sep 2014 15:37:17 -0500 (CDT) Date: Thu, 18 Sep 2014 15:37:17 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 06/13] xfsprogs: add unicode character database files Message-ID: <20140918203717.GT4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918203114.GN4482@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Add files from the Unicode Character Database, version 7.0.0, to the source. A helper program that generates a trie used for normalization from these files is part of a separate commit. Signed-off-by: Olaf Weber --- [v2: removed large unicode files. download them as below. -bpm] cd support/ucd-7.0.0 wget http://www.unicode.org/Public/7.0.0/ucd/CaseFolding.txt wget http://www.unicode.org/Public/7.0.0/ucd/DerivedAge.txt wget http://www.unicode.org/Public/7.0.0/ucd/extracted/DerivedCombiningClass.txt wget http://www.unicode.org/Public/7.0.0/ucd/DerivedCoreProperties.txt wget http://www.unicode.org/Public/7.0.0/ucd/NormalizationCorrections.txt wget http://www.unicode.org/Public/7.0.0/ucd/NormalizationTest.txt wget http://www.unicode.org/Public/7.0.0/ucd/UnicodeData.txt --- support/ucd-7.0.0/README | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 support/ucd-7.0.0/README diff --git a/support/ucd-7.0.0/README b/support/ucd-7.0.0/README new file mode 100644 index 0000000..d713e66 --- /dev/null +++ b/support/ucd-7.0.0/README @@ -0,0 +1,33 @@ +The files in this directory are part of the Unicode Character Database +for version 7.0.0 of the Unicode standard. + +The full set of files can be found here: + + http://www.unicode.org/Public/7.0.0/ucd/ + +The latest released version of the UCD can be found here: + + http://www.unicode.org/Public/UCD/latest/ + +The files in this directory are identical, except that they have been +renamed with a suffix indicating the unicode version. + +Individual source links: + + http://www.unicode.org/Public/7.0.0/ucd/CaseFolding.txt + http://www.unicode.org/Public/7.0.0/ucd/DerivedAge.txt + http://www.unicode.org/Public/7.0.0/ucd/extracted/DerivedCombiningClass.txt + http://www.unicode.org/Public/7.0.0/ucd/DerivedCoreProperties.txt + http://www.unicode.org/Public/7.0.0/ucd/NormalizationCorrections.txt + http://www.unicode.org/Public/7.0.0/ucd/NormalizationTest.txt + http://www.unicode.org/Public/7.0.0/ucd/UnicodeData.txt + +md5sums + + 9a92b2bfe56c6719def926bab524fefd CaseFolding-7.0.0.txt + 07b8b1027eb824cf0835314e94f23d2e DerivedAge-7.0.0.txt + 90c3340b16821e2f2153acdbe6fc6180 DerivedCombiningClass-7.0.0.txt + c41c0601f808116f623de47110ed4f93 DerivedCoreProperties-7.0.0.txt + 522720ddfc150d8e63a2518634829bce NormalizationCorrections-7.0.0.txt + 1f35175eba4a2ad795db489f789ae352 NormalizationTest-7.0.0.txt + c8355655731d75e6a3de8c20d7e601ba UnicodeData-7.0.0.txt -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:38:06 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD, T_FILL_THIS_FORM_SHORT autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2364E7F37 for ; Thu, 18 Sep 2014 15:38:06 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id DA2658F804B; Thu, 18 Sep 2014 13:38:05 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 364474266DC; Thu, 18 Sep 2014 15:38:05 -0500 (CDT) Date: Thu, 18 Sep 2014 15:38:05 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 07/13] libxfs: add trie generator and supporting code for UTF-8. Message-ID: <20140918203805.GU4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918203114.GN4482@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber mkutf8data.c is the source for a program that generates utf8data.h, which contains the trie that utf8norm.c uses. The trie is generated from the Unicode 7.0.0 data files. The format of the utf8data[] table is described in utf8norm.c. Supporting functions for UTF-8 normalization are in utf8norm.c with the header utf8norm.h. Two normalization forms are supported: nfkdi and nfkdicf. nfkdi: - Apply unicode normalization form NFKD. - Remove any Default_Ignorable_Code_Point. nfkdicf: - Apply unicode normalization form NFKD. - Remove any Default_Ignorable_Code_Point. - Apply a full casefold (C + F). For the purposes of the code, a string is valid UTF-8 if: - The values encoded are 0x1..0x10FFFF. - The surrogate codepoints 0xD800..0xDFFFF are not encoded. - The shortest possible encoding is used for all values. The supporting functions work on null-terminated strings (utf8 prefix) and on length-limited strings (utf8n prefix). Signed-off-by: Olaf Weber --- include/utf8norm.h | 111 ++ libxfs/utf8norm.c | 628 ++++++++++ support/mkutf8data.c | 3232 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 3971 insertions(+) create mode 100644 include/utf8norm.h create mode 100644 libxfs/utf8norm.c create mode 100644 support/mkutf8data.c diff --git a/include/utf8norm.h b/include/utf8norm.h new file mode 100644 index 0000000..6aa3391 --- /dev/null +++ b/include/utf8norm.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef UTF8NORM_H +#define UTF8NORM_H + +/* An opaque type used to determine the normalization in use. */ +typedef const struct utf8data *utf8data_t; + +/* Encoding a unicode version number as a single unsigned int. */ +#define UNICODE_MAJ_SHIFT (16) +#define UNICODE_MIN_SHIFT (8) + +#define UNICODE_AGE(MAJ,MIN,REV) \ + (((unsigned int)(MAJ) << UNICODE_MAJ_SHIFT) | \ + ((unsigned int)(MIN) << UNICODE_MIN_SHIFT) | \ + ((unsigned int)(REV))) + +/* Highest unicode version supported by the data tables. */ +extern const unsigned int utf8version; + +/* + * Look for the correct utf8data_t for a unicode version. + * Returns NULL if the version requested is too new. + * + * Two normalization forms are supported: nfkdi and nfkdicf. + * + * nfkdi: + * - Apply unicode normalization form NFKD. + * - Remove any Default_Ignorable_Code_Point. + * + * nfkdicf: + * - Apply unicode normalization form NFKD. + * - Remove any Default_Ignorable_Code_Point. + * - Apply a full casefold (C + F). + */ +extern utf8data_t utf8nfkdi(unsigned int); +extern utf8data_t utf8nfkdicf(unsigned int); + +/* + * Determine the maximum age of any unicode character in the string. + * Returns 0 if only unassigned code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern int utf8agemax(utf8data_t, const char *); +extern int utf8nagemax(utf8data_t, const char *, size_t); + +/* + * Determine the minimum age of any unicode character in the string. + * Returns 0 if any unassigned code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern int utf8agemin(utf8data_t, const char *); +extern int utf8nagemin(utf8data_t, const char *, size_t); + +/* + * Determine the length of the normalized from of the string, + * excluding any terminating NULL byte. + * Returns 0 if only ignorable code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern ssize_t utf8len(utf8data_t, const char *); +extern ssize_t utf8nlen(utf8data_t, const char *, size_t); + +/* + * Cursor structure used by the normalizer. + */ +struct utf8cursor { + utf8data_t data; + const char *s; + const char *p; + const char *ss; + const char *sp; + unsigned int len; + unsigned int slen; + short int ccc; + short int nccc; +}; + +/* + * Initialize a utf8cursor to normalize a string. + * Returns 0 on success. + * Returns -1 on failure. + */ +extern int utf8cursor(struct utf8cursor *, utf8data_t, const char *); +extern int utf8ncursor(struct utf8cursor *, utf8data_t, const char *, size_t); + +/* + * Get the next byte in the normalization. + * Returns a value > 0 && < 256 on success. + * Returns 0 when the end of the normalization is reached. + * Returns -1 if the string being normalized is not valid UTF-8. + */ +extern int utf8byte(struct utf8cursor *); + +#endif /* UTF8NORM_H */ diff --git a/libxfs/utf8norm.c b/libxfs/utf8norm.c new file mode 100644 index 0000000..6232d1a --- /dev/null +++ b/libxfs/utf8norm.c @@ -0,0 +1,628 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "xfs.h" +#include "xfs_types.h" +#include + +struct utf8data { + unsigned int maxage; + unsigned int offset; +}; + +#define __INCLUDED_FROM_UTF8NORM_C__ +#include +#undef __INCLUDED_FROM_UTF8NORM_C__ + +/* + * UTF-8 valid ranges. + * + * The UTF-8 encoding spreads the bits of a 32bit word over several + * bytes. This table gives the ranges that can be held and how they'd + * be represented. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000000 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000000 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * There is an additional requirement on UTF-8, in that only the + * shortest representation of a 32bit value is to be used. A decoder + * must not decode sequences that do not satisfy this requirement. + * Thus the allowed ranges have a lower bound. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000080 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000800 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00010000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00200000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x04000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Actual unicode characters are limited to the range 0x0 - 0x10FFFF, + * 17 planes of 65536 values. This limits the sequences actually seen + * even more, to just the following. + * + * 0 - 0x7F: 0 - 0x7F + * 0x80 - 0x7FF: 0xC2 0x80 - 0xDF 0xBF + * 0x800 - 0xFFFF: 0xE0 0xA0 0x80 - 0xEF 0xBF 0xBF + * 0x10000 - 0x10FFFF: 0xF0 0x90 0x80 0x80 - 0xF4 0x8F 0xBF 0xBF + * + * Within those ranges the surrogates 0xD800 - 0xDFFF are not allowed. + * + * Note that the longest sequence seen with valid usage is 4 bytes, + * the same a single UTF-32 character. This makes the UTF-8 + * representation of Unicode strictly smaller than UTF-32. + * + * The shortest sequence requirement was introduced by: + * Corrigendum #1: UTF-8 Shortest Form + * It can be found here: + * http://www.unicode.org/versions/corrigendum1.html + * + */ + +/* + * Return the number of bytes used by the current UTF-8 sequence. + * Assumes the input points to the first byte of a valid UTF-8 + * sequence. + */ +static inline int +utf8clen(const char *s) +{ + unsigned char c = *s; + return 1 + (c >= 0xC0) + (c >= 0xE0) + (c >= 0xF0); +} + +/* + * utf8trie_t + * + * A compact binary tree, used to decode UTF-8 characters. + * + * Internal nodes are one byte for the node itself, and up to three + * bytes for an offset into the tree. The first byte contains the + * following information: + * NEXTBYTE - flag - advance to next byte if set + * BITNUM - 3 bit field - the bit number to tested + * OFFLEN - 2 bit field - number of bytes in the offset + * if offlen == 0 (non-branching node) + * RIGHTPATH - 1 bit field - set if the following node is for the + * right-hand path (tested bit is set) + * TRIENODE - 1 bit field - set if the following node is an internal + * node, otherwise it is a leaf node + * if offlen != 0 (branching node) + * LEFTNODE - 1 bit field - set if the left-hand node is internal + * RIGHTNODE - 1 bit field - set if the right-hand node is internal + * + * Due to the way utf8 works, there cannot be branching nodes with + * NEXTBYTE set, and moreover those nodes always have a righthand + * descendant. + */ +typedef const unsigned char utf8trie_t; +#define BITNUM 0x07 +#define NEXTBYTE 0x08 +#define OFFLEN 0x30 +#define OFFLEN_SHIFT 4 +#define RIGHTPATH 0x40 +#define TRIENODE 0x80 +#define RIGHTNODE 0x40 +#define LEFTNODE 0x80 + +/* + * utf8leaf_t + * + * The leaves of the trie are embedded in the trie, and so the same + * underlying datatype: unsigned char. + * + * leaf[0]: The unicode version, stored as a generation number that is + * an index into utf8agetab[]. With this we can filter code + * points based on the unicode version in which they were + * defined. The CCC of a non-defined code point is 0. + * leaf[1]: Canonical Combining Class. During normalization, we need + * to do a stable sort into ascending order of all characters + * with a non-zero CCC that occur between two characters with + * a CCC of 0, or at the begin or end of a string. + * The unicode standard guarantees that all CCC values are + * between 0 and 254 inclusive, which leaves 255 available as + * a special value. + * Code points with CCC 0 are known as stoppers. + * leaf[2]: Decomposition. If leaf[1] == 255, then leaf[2] is the + * start of a NUL-terminated string that is the decomposition + * of the character. + * The CCC of a decomposable character is the same as the CCC + * of the first character of its decomposition. + * Some characters decompose as the empty string: these are + * characters with the Default_Ignorable_Code_Point property. + * These do affect normalization, as they all have CCC 0. + * + * The decompositions in the trie have been fully expanded. + * + * Casefolding, if applicable, is also done using decompositions. + * + * The trie is constructed in such a way that leaves exist for all + * UTF-8 sequences that match the criteria from the "UTF-8 valid + * ranges" comment above, and only for those sequences. Therefore a + * lookup in the trie can be used to validate the UTF-8 input. + */ +typedef const unsigned char utf8leaf_t; + +#define LEAF_GEN(LEAF) ((LEAF)[0]) +#define LEAF_CCC(LEAF) ((LEAF)[1]) +#define LEAF_STR(LEAF) ((const char*)((LEAF) + 2)) + +#define MINCCC (0) +#define MAXCCC (254) +#define STOPPER (0) +#define DECOMPOSE (255) + +/* + * Use trie to scan s, touching at most len bytes. + * Returns the leaf if one exists, NULL otherwise. + * + * A non-NULL return guarantees that the UTF-8 sequence starting at s + * is well-formed and corresponds to a known unicode code point. The + * shorthand for this will be "is valid UTF-8 unicode". + */ +static utf8leaf_t * +utf8nlookup(utf8data_t data, const char *s, size_t len) +{ + utf8trie_t *trie = utf8data + data->offset; + int offlen; + int offset; + int mask; + int node; + + if (!data) + return NULL; + if (len == 0) + return NULL; + node = 1; + while (node) { + offlen = (*trie & OFFLEN) >> OFFLEN_SHIFT; + if (*trie & NEXTBYTE) { + if (--len == 0) + return NULL; + s++; + } + mask = 1 << (*trie & BITNUM); + if (*s & mask) { + /* Right leg */ + if (offlen) { + /* Right node at offset of trie */ + node = (*trie & RIGHTNODE); + offset = trie[offlen]; + while (--offlen) { + offset <<= 8; + offset |= trie[offlen]; + } + trie += offset; + } else if (*trie & RIGHTPATH) { + /* Right node after this node */ + node = (*trie & TRIENODE); + trie++; + } else { + /* No right node. */ + node = 0; + trie = NULL; + } + } else { + /* Left leg */ + if (offlen) { + /* Left node after this node. */ + node = (*trie & LEFTNODE); + trie += offlen + 1; + } else if (*trie & RIGHTPATH) { + /* No left node. */ + node = 0; + trie = NULL; + } else { + /* Left node after this node */ + node = (*trie & TRIENODE); + trie++; + } + } + } + return trie; +} + +/* + * Use trie to scan s. + * Returns the leaf if one exists, NULL otherwise. + * + * Forwards to utf8nlookup(). + */ +static utf8leaf_t * +utf8lookup(utf8data_t data, const char *s) +{ + return utf8nlookup(data, s, (size_t)-1); +} + +/* + * Maximum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if only non-assigned code points are used. + */ +int +utf8agemax(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!data) + return -1; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age > age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Minimum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if non-assigned code points are used. + */ +int +utf8agemin(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + int age = data->maxage; + int leaf_age; + + if (!data) + return -1; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age < age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemax(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!data) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age > age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemin(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int leaf_age; + int age = data->maxage; + + if (!data) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age < age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Length of the normalization of s. + * Return -1 if s is not valid UTF-8 unicode. + * + * A string of Default_Ignorable_Code_Point has length 0. + */ +ssize_t +utf8len(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!data) + return -1; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + if (utf8agetab[LEAF_GEN(leaf)] > data->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Length of the normalization of s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +ssize_t +utf8nlen(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!data) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + if (utf8agetab[LEAF_GEN(leaf)] > data->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + len -= utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * u8c : pointer to cursor. + * data : utf8data_t to use for normalization. + * s : string. + * len : length of s. + * + * Returns -1 on error, 0 on success. + */ +int +utf8ncursor( + struct utf8cursor *u8c, + utf8data_t data, + const char *s, + size_t len) +{ + if (!data) + return -1; + if (!s) + return -1; + u8c->data = data; + u8c->s = s; + u8c->p = NULL; + u8c->ss = NULL; + u8c->sp = NULL; + u8c->len = len; + u8c->slen = 0; + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + /* Check we didn't clobber the maximum length. */ + if (u8c->len != len) + return -1; + /* The first byte of s may not be an utf8 continuation. */ + if (len > 0 && (*s & 0xC0) == 0x80) + return -1; + return 0; +} + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * u8c : pointer to cursor. + * data : utf8data_t to use for normalization. + * s : NUL-terminated string. + * + * Returns -1 on error, 0 on success. + */ +int +utf8cursor( + struct utf8cursor *u8c, + utf8data_t data, + const char *s) +{ + return utf8ncursor(u8c, data, s, (unsigned int)-1); +} + +/* + * Get one byte from the normalized form of the string described by u8c. + * + * Returns the byte cast to an unsigned char on succes, and -1 on failure. + * + * The cursor keeps track of the location in the string in u8c->s. + * When a character is decomposed, the current location is stored in + * u8c->p, and u8c->s is set to the start of the decomposition. Note + * that bytes from a decomposition do not count against u8c->len. + * + * Characters are emitted if they match the current CCC in u8c->ccc. + * Hitting end-of-string while u8c->ccc == STOPPER means we're done, + * and the function returns 0 in that case. + * + * Sorting by CCC is done by repeatedly scanning the string. The + * values of u8c->s and u8c->p are stored in u8c->ss and u8c->sp at + * the start of the scan. The first pass finds the lowest CCC to be + * emitted and stores it in u8c->nccc, the second pass emits the + * characters with this CCC and finds the next lowest CCC. This limits + * the number of passes to 1 + the number of different CCCs in the + * sequence being scanned. + * + * Therefore: + * u8c->p != NULL -> a decomposition is being scanned. + * u8c->ss != NULL -> this is a repeating scan. + * u8c->ccc == -1 -> this is the first scan of a repeating scan. + */ +int +utf8byte(struct utf8cursor *u8c) +{ + utf8leaf_t *leaf; + int ccc; + + for (;;) { + /* Check for the end of a decomposed character. */ + if (u8c->p && *u8c->s == '\0') { + u8c->s = u8c->p; + u8c->p = NULL; + } + + /* Check for end-of-string. */ + if (!u8c->p && (u8c->len == 0 || *u8c->s == '\0')) { + /* There is no next byte. */ + if (u8c->ccc == STOPPER) + return 0; + /* End-of-string during a scan counts as a stopper. */ + ccc = STOPPER; + goto ccc_mismatch; + } else if ((*u8c->s & 0xC0) == 0x80) { + /* This is a continuation of the current character. */ + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Look up the data for the current character. */ + if (u8c->p) + leaf = utf8lookup(u8c->data, u8c->s); + else + leaf = utf8nlookup(u8c->data, u8c->s, u8c->len); + + /* No leaf found implies that the input is a binary blob. */ + if (!leaf) + return -1; + + /* Characters that are too new have CCC 0. */ + if (utf8agetab[LEAF_GEN(leaf)] > u8c->data->maxage) { + ccc = STOPPER; + } else if ((ccc = LEAF_CCC(leaf)) == DECOMPOSE) { + u8c->len -= utf8clen(u8c->s); + u8c->p = u8c->s + utf8clen(u8c->s); + u8c->s = LEAF_STR(leaf); + /* Empty decomposition implies CCC 0. */ + if (*u8c->s == '\0') { + if (u8c->ccc == STOPPER) + continue; + ccc = STOPPER; + goto ccc_mismatch; + } + leaf = utf8lookup(u8c->data, u8c->s); + ccc = LEAF_CCC(leaf); + } + + /* + * If this is not a stopper, then see if it updates + * the next canonical class to be emitted. + */ + if (ccc != STOPPER && u8c->ccc < ccc && ccc < u8c->nccc) + u8c->nccc = ccc; + + /* + * Return the current byte if this is the current + * combining class. + */ + if (ccc == u8c->ccc) { + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Current combining class mismatch. */ + ccc_mismatch: + if (u8c->nccc == STOPPER) { + /* + * Scan forward for the first canonical class + * to be emitted. Save the position from + * which to restart. + */ + u8c->ccc = MINCCC - 1; + u8c->nccc = ccc; + u8c->sp = u8c->p; + u8c->ss = u8c->s; + u8c->slen = u8c->len; + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (ccc != STOPPER) { + /* Not a stopper, and not the ccc we're emitting. */ + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (u8c->nccc != MAXCCC + 1) { + /* At a stopper, restart for next ccc. */ + u8c->ccc = u8c->nccc; + u8c->nccc = MAXCCC + 1; + u8c->s = u8c->ss; + u8c->p = u8c->sp; + u8c->len = u8c->slen; + } else { + /* All done, proceed from here. */ + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->sp = NULL; + u8c->ss = NULL; + u8c->slen = 0; + } + } +} + +const struct utf8data * +utf8nfkdi(unsigned int maxage) +{ + int i = sizeof(utf8nfkdidata)/sizeof(utf8nfkdidata[0]) - 1; + + while (maxage < utf8nfkdidata[i].maxage) + i--; + if (maxage > utf8nfkdidata[i].maxage) + return NULL; + return &utf8nfkdidata[i]; +} + +const struct utf8data * +utf8nfkdicf(unsigned int maxage) +{ + int i = sizeof(utf8nfkdicfdata)/sizeof(utf8nfkdicfdata[0]) - 1; + + while (maxage < utf8nfkdicfdata[i].maxage) + i--; + if (maxage > utf8nfkdicfdata[i].maxage) + return NULL; + return &utf8nfkdicfdata[i]; +} diff --git a/support/mkutf8data.c b/support/mkutf8data.c new file mode 100644 index 0000000..e5c3507 --- /dev/null +++ b/support/mkutf8data.c @@ -0,0 +1,3232 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Generator for a compact trie for unicode normalization */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Default names of the in- and output files. */ + +#define AGE_NAME "DerivedAge.txt" +#define CCC_NAME "DerivedCombiningClass.txt" +#define PROP_NAME "DerivedCoreProperties.txt" +#define DATA_NAME "UnicodeData.txt" +#define FOLD_NAME "CaseFolding.txt" +#define NORM_NAME "NormalizationCorrections.txt" +#define TEST_NAME "NormalizationTest.txt" +#define UTF8_NAME "utf8data.h" + +const char *age_name = AGE_NAME; +const char *ccc_name = CCC_NAME; +const char *prop_name = PROP_NAME; +const char *data_name = DATA_NAME; +const char *fold_name = FOLD_NAME; +const char *norm_name = NORM_NAME; +const char *test_name = TEST_NAME; +const char *utf8_name = UTF8_NAME; + +int verbose = 0; + +/* An arbitrary line size limit on input lines. */ + +#define LINESIZE 1024 +char line[LINESIZE]; +char buf0[LINESIZE]; +char buf1[LINESIZE]; +char buf2[LINESIZE]; +char buf3[LINESIZE]; + +const char *argv0; + +/* ------------------------------------------------------------------ */ + +/* + * Unicode version numbers consist of three parts: major, minor, and a + * revision. These numbers are packed into an unsigned int to obtain + * a single version number. + * + * To save space in the generated trie, the unicode version is not + * stored directly, instead we calculate a generation number from the + * unicode versions seen in the DerivedAge file, and use that as an + * index into a table of unicode versions. + */ +#define UNICODE_MAJ_SHIFT (16) +#define UNICODE_MIN_SHIFT (8) + +#define UNICODE_MAJ_MAX ((unsigned short)-1) +#define UNICODE_MIN_MAX ((unsigned char)-1) +#define UNICODE_REV_MAX ((unsigned char)-1) + +#define UNICODE_AGE(MAJ,MIN,REV) \ + (((unsigned int)(MAJ) << UNICODE_MAJ_SHIFT) | \ + ((unsigned int)(MIN) << UNICODE_MIN_SHIFT) | \ + ((unsigned int)(REV))) + +unsigned int *ages; +int ages_count; + +unsigned int unicode_maxage; + +static int +age_valid(unsigned int major, unsigned int minor, unsigned int revision) +{ + if (major > UNICODE_MAJ_MAX) + return 0; + if (minor > UNICODE_MIN_MAX) + return 0; + if (revision > UNICODE_REV_MAX) + return 0; + return 1; +} + +/* ------------------------------------------------------------------ */ + +/* + * utf8trie_t + * + * A compact binary tree, used to decode UTF-8 characters. + * + * Internal nodes are one byte for the node itself, and up to three + * bytes for an offset into the tree. The first byte contains the + * following information: + * NEXTBYTE - flag - advance to next byte if set + * BITNUM - 3 bit field - the bit number to tested + * OFFLEN - 2 bit field - number of bytes in the offset + * if offlen == 0 (non-branching node) + * RIGHTPATH - 1 bit field - set if the following node is for the + * right-hand path (tested bit is set) + * TRIENODE - 1 bit field - set if the following node is an internal + * node, otherwise it is a leaf node + * if offlen != 0 (branching node) + * LEFTNODE - 1 bit field - set if the left-hand node is internal + * RIGHTNODE - 1 bit field - set if the right-hand node is internal + * + * Due to the way utf8 works, there cannot be branching nodes with + * NEXTBYTE set, and moreover those nodes always have a righthand + * descendant. + */ +typedef unsigned char utf8trie_t; +#define BITNUM 0x07 +#define NEXTBYTE 0x08 +#define OFFLEN 0x30 +#define OFFLEN_SHIFT 4 +#define RIGHTPATH 0x40 +#define TRIENODE 0x80 +#define RIGHTNODE 0x40 +#define LEFTNODE 0x80 + +/* + * utf8leaf_t + * + * The leaves of the trie are embedded in the trie, and so the same + * underlying datatype, unsigned char. + * + * leaf[0]: The unicode version, stored as a generation number that is + * an index into utf8agetab[]. With this we can filter code + * points based on the unicode version in which they were + * defined. The CCC of a non-defined code point is 0. + * leaf[1]: Canonical Combining Class. During normalization, we need + * to do a stable sort into ascending order of all characters + * with a non-zero CCC that occur between two characters with + * a CCC of 0, or at the begin or end of a string. + * The unicode standard guarantees that all CCC values are + * between 0 and 254 inclusive, which leaves 255 available as + * a special value. + * Code points with CCC 0 are known as stoppers. + * leaf[2]: Decomposition. If leaf[1] == 255, then leaf[2] is the + * start of a NUL-terminated string that is the decomposition + * of the character. + * The CCC of a decomposable character is the same as the CCC + * of the first character of its decomposition. + * Some characters decompose as the empty string: these are + * characters with the Default_Ignorable_Code_Point property. + * These do affect normalization, as they all have CCC 0. + * + * The decompositions in the trie have been fully expanded. + * + * Casefolding, if applicable, is also done using decompositions. + */ +typedef unsigned char utf8leaf_t; + +#define LEAF_GEN(LEAF) ((LEAF)[0]) +#define LEAF_CCC(LEAF) ((LEAF)[1]) +#define LEAF_STR(LEAF) ((const char*)((LEAF) + 2)) + +#define MAXGEN (255) + +#define MINCCC (0) +#define MAXCCC (254) +#define STOPPER (0) +#define DECOMPOSE (255) + +struct tree; +static utf8leaf_t *utf8nlookup(struct tree *, const char *, size_t); +static utf8leaf_t *utf8lookup(struct tree *, const char *); + +unsigned char *utf8data; +size_t utf8data_size; + +utf8trie_t *nfkdi; +utf8trie_t *nfkdicf; + +/* ------------------------------------------------------------------ */ + +/* + * UTF8 valid ranges. + * + * The UTF-8 encoding spreads the bits of a 32bit word over several + * bytes. This table gives the ranges that can be held and how they'd + * be represented. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000000 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000000 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * There is an additional requirement on UTF-8, in that only the + * shortest representation of a 32bit value is to be used. A decoder + * must not decode sequences that do not satisfy this requirement. + * Thus the allowed ranges have a lower bound. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000080 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000800 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00010000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00200000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x04000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Actual unicode characters are limited to the range 0x0 - 0x10FFFF, + * 17 planes of 65536 values. This limits the sequences actually seen + * even more, to just the following. + * + * 0 - 0x7f: 0 0x7f + * 0x80 - 0x7ff: 0xc2 0x80 0xdf 0xbf + * 0x800 - 0xffff: 0xe0 0xa0 0x80 0xef 0xbf 0xbf + * 0x10000 - 0x10ffff: 0xf0 0x90 0x80 0x80 0xf4 0x8f 0xbf 0xbf + * + * Even within those ranges not all values are allowed: the surrogates + * 0xd800 - 0xdfff should never be seen. + * + * Note that the longest sequence seen with valid usage is 4 bytes, + * the same a single UTF-32 character. This makes the UTF-8 + * representation of Unicode strictly smaller than UTF-32. + * + * The shortest sequence requirement was introduced by: + * Corrigendum #1: UTF-8 Shortest Form + * It can be found here: + * http://www.unicode.org/versions/corrigendum1.html + * + */ + +#define UTF8_2_BITS 0xC0 +#define UTF8_3_BITS 0xE0 +#define UTF8_4_BITS 0xF0 +#define UTF8_N_BITS 0x80 +#define UTF8_2_MASK 0xE0 +#define UTF8_3_MASK 0xF0 +#define UTF8_4_MASK 0xF8 +#define UTF8_N_MASK 0xC0 +#define UTF8_V_MASK 0x3F +#define UTF8_V_SHIFT 6 + +static int +utf8key(unsigned int key, char keyval[]) +{ + int keylen; + + if (key < 0x80) { + keyval[0] = key; + keylen = 1; + } else if (key < 0x800) { + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_2_BITS; + keylen = 2; + } else if (key < 0x10000) { + keyval[2] = key & UTF8_V_MASK; + keyval[2] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_3_BITS; + keylen = 3; + } else if (key < 0x110000) { + keyval[3] = key & UTF8_V_MASK; + keyval[3] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[2] = key & UTF8_V_MASK; + keyval[2] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_4_BITS; + keylen = 4; + } else { + printf("%#x: illegal key\n", key); + keylen = 0; + } + return keylen; +} + +static unsigned int +utf8code(const char *str) +{ + const unsigned char *s = (const unsigned char*)str; + unsigned int unichar = 0; + + if (*s < 0x80) { + unichar = *s; + } else if (*s < UTF8_3_BITS) { + unichar = *s++ & 0x1F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } else if (*s < UTF8_4_BITS) { + unichar = *s++ & 0x0F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } else { + unichar = *s++ & 0x0F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } + return unichar; +} + +static int +utf32valid(unsigned int unichar) +{ + return unichar < 0x110000; +} + +#define NODE 1 +#define LEAF 0 + +struct tree { + void *root; + int childnode; + const char *type; + unsigned int maxage; + struct tree *next; + int (*leaf_equal)(void *, void *); + void (*leaf_print)(void *, int); + int (*leaf_mark)(void *); + int (*leaf_size)(void *); + int *(*leaf_index)(struct tree *, void *); + unsigned char *(*leaf_emit)(void *, unsigned char *); + int leafindex[0x110000]; + int index; +}; + +struct node { + int index; + int offset; + int mark; + int size; + struct node *parent; + void *left; + void *right; + unsigned char bitnum; + unsigned char nextbyte; + unsigned char leftnode; + unsigned char rightnode; + unsigned int keybits; + unsigned int keymask; +}; + +/* + * Example lookup function for a tree. + */ +static void * +lookup(struct tree *tree, const char *key) +{ + struct node *node; + void *leaf = NULL; + + node = tree->root; + while (!leaf && node) { + if (node->nextbyte) + key++; + if (*key & (1 << (node->bitnum & 7))) { + /* Right leg */ + if (node->rightnode == NODE) { + node = node->right; + } else if (node->rightnode == LEAF) { + leaf = node->right; + } else { + node = NULL; + } + } else { + /* Left leg */ + if (node->leftnode == NODE) { + node = node->left; + } else if (node->leftnode == LEAF) { + leaf = node->left; + } else { + node = NULL; + } + } + } + + return leaf; +} + +/* + * A simple non-recursive tree walker: keep track of visits to the + * left and right branches in the leftmask and rightmask. + */ +static void +tree_walk(struct tree *tree) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int indent = 1; + int nodes, singletons, leaves; + + nodes = singletons = leaves = 0; + + printf("%s_%x root %p\n", tree->type, tree->maxage, tree->root); + if (tree->childnode == LEAF) { + assert(tree->root); + tree->leaf_print(tree->root, indent); + leaves = 1; + } else { + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + printf("%*snode @ %p bitnum %d nextbyte %d" + " left %p right %p mask %x bits %x\n", + indent, "", node, + node->bitnum, node->nextbyte, + node->left, node->right, + node->keymask, node->keybits); + nodes += 1; + if (!(node->left && node->right)) + singletons += 1; + + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + tree->leaf_print(node->left, + indent+1); + leaves += 1; + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + tree->leaf_print(node->right, + indent+1); + leaves += 1; + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } + } + printf("nodes %d leaves %d singletons %d\n", + nodes, leaves, singletons); +} + +/* + * Allocate an initialize a new internal node. + */ +static struct node * +alloc_node(struct node *parent) +{ + struct node *node; + int bitnum; + + node = malloc(sizeof(*node)); + node->left = node->right = NULL; + node->parent = parent; + node->leftnode = NODE; + node->rightnode = NODE; + node->keybits = 0; + node->keymask = 0; + node->mark = 0; + node->index = 0; + node->offset = -1; + node->size = 4; + + if (node->parent) { + bitnum = parent->bitnum; + if ((bitnum & 7) == 0) { + node->bitnum = bitnum + 7 + 8; + node->nextbyte = 1; + } else { + node->bitnum = bitnum - 1; + node->nextbyte = 0; + } + } else { + node->bitnum = 7; + node->nextbyte = 0; + } + + return node; +} + +/* + * Insert a new leaf into the tree, and collapse any subtrees that are + * fully populated and end in identical leaves. A nextbyte tagged + * internal node will not be removed to preserve the tree's integrity. + * Note that due to the structure of utf8, no nextbyte tagged node + * will be a candidate for removal. + */ +static int +insert(struct tree *tree, char *key, int keylen, void *leaf) +{ + struct node *node; + struct node *parent; + void **cursor; + int keybits; + + assert(keylen >= 1 && keylen <= 4); + + node = NULL; + cursor = &tree->root; + keybits = 8 * keylen; + + /* Insert, creating path along the way. */ + while (keybits) { + if (!*cursor) + *cursor = alloc_node(node); + node = *cursor; + if (node->nextbyte) + key++; + if (*key & (1 << (node->bitnum & 7))) + cursor = &node->right; + else + cursor = &node->left; + keybits--; + } + *cursor = leaf; + + /* Merge subtrees if possible. */ + while (node) { + if (*key & (1 << (node->bitnum & 7))) + node->rightnode = LEAF; + else + node->leftnode = LEAF; + if (node->nextbyte) + break; + if (node->leftnode == NODE || node->rightnode == NODE) + break; + assert(node->left); + assert(node->right); + /* Compare */ + if (! tree->leaf_equal(node->left, node->right)) + break; + /* Keep left, drop right leaf. */ + leaf = node->left; + /* Check in parent */ + parent = node->parent; + if (!parent) { + /* root of tree! */ + tree->root = leaf; + tree->childnode = LEAF; + } else if (parent->left == node) { + parent->left = leaf; + parent->leftnode = LEAF; + if (parent->right) { + parent->keymask = 0; + parent->keybits = 0; + } else { + parent->keymask |= (1 << node->bitnum); + } + } else if (parent->right == node) { + parent->right = leaf; + parent->rightnode = LEAF; + if (parent->left) { + parent->keymask = 0; + parent->keybits = 0; + } else { + parent->keymask |= (1 << node->bitnum); + parent->keybits |= (1 << node->bitnum); + } + } else { + /* internal tree error */ + assert(0); + } + free(node); + node = parent; + } + + /* Propagate keymasks up along singleton chains. */ + while (node) { + parent = node->parent; + if (!parent) + break; + /* Nix the mask for parents with two children. */ + if (node->keymask == 0) { + parent->keymask = 0; + parent->keybits = 0; + } else if (parent->left && parent->right) { + parent->keymask = 0; + parent->keybits = 0; + } else { + assert((parent->keymask & node->keymask) == 0); + parent->keymask |= node->keymask; + parent->keymask |= (1 << parent->bitnum); + parent->keybits |= node->keybits; + if (parent->right) + parent->keybits |= (1 << parent->bitnum); + } + node = parent; + } + + return 0; +} + +/* + * Prune internal nodes. + * + * Fully populated subtrees that end at the same leaf have already + * been collapsed. There are still internal nodes that have for both + * their left and right branches a sequence of singletons that make + * identical choices and end in identical leaves. The keymask and + * keybits collected in the nodes describe the choices made in these + * singleton chains. When they are identical for the left and right + * branch of a node, and the two leaves comare identical, the node in + * question can be removed. + * + * Note that nodes with the nextbyte tag set will not be removed by + * this to ensure tree integrity. Note as well that the structure of + * utf8 ensures that these nodes would not have been candidates for + * removal in any case. + */ +static void +prune(struct tree *tree) +{ + struct node *node; + struct node *left; + struct node *right; + struct node *parent; + void *leftleaf; + void *rightleaf; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int count; + + if (verbose > 0) + printf("Pruning %s_%x\n", tree->type, tree->maxage); + + count = 0; + if (tree->childnode == LEAF) + return; + if (!tree->root) + return; + + leftmask = rightmask = 0; + node = tree->root; + while (node) { + if (node->nextbyte) + goto advance; + if (node->leftnode == LEAF) + goto advance; + if (node->rightnode == LEAF) + goto advance; + if (!node->left) + goto advance; + if (!node->right) + goto advance; + left = node->left; + right = node->right; + if (left->keymask == 0) + goto advance; + if (right->keymask == 0) + goto advance; + if (left->keymask != right->keymask) + goto advance; + if (left->keybits != right->keybits) + goto advance; + leftleaf = NULL; + while (!leftleaf) { + assert(left->left || left->right); + if (left->leftnode == LEAF) + leftleaf = left->left; + else if (left->rightnode == LEAF) + leftleaf = left->right; + else if (left->left) + left = left->left; + else if (left->right) + left = left->right; + else + assert(0); + } + rightleaf = NULL; + while (!rightleaf) { + assert(right->left || right->right); + if (right->leftnode == LEAF) + rightleaf = right->left; + else if (right->rightnode == LEAF) + rightleaf = right->right; + else if (right->left) + right = right->left; + else if (right->right) + right = right->right; + else + assert(0); + } + if (! tree->leaf_equal(leftleaf, rightleaf)) + goto advance; + /* + * This node has identical singleton-only subtrees. + * Remove it. + */ + parent = node->parent; + left = node->left; + right = node->right; + if (parent->left == node) + parent->left = left; + else if (parent->right == node) + parent->right = left; + else + assert(0); + left->parent = parent; + left->keymask |= (1 << node->bitnum); + node->left = NULL; + while (node) { + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + if (node->leftnode == NODE && node->left) { + left = node->left; + free(node); + count++; + node = left; + } else if (node->rightnode == NODE && node->right) { + right = node->right; + free(node); + count++; + node = right; + } else { + node = NULL; + } + } + /* Propagate keymasks up along singleton chains. */ + node = parent; + /* Force re-check */ + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + for (;;) { + if (node->left && node->right) + break; + if (node->left) { + left = node->left; + node->keymask |= left->keymask; + node->keybits |= left->keybits; + } + if (node->right) { + right = node->right; + node->keymask |= right->keymask; + node->keybits |= right->keybits; + } + node->keymask |= (1 << node->bitnum); + node = node->parent; + /* Force re-check */ + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + } + advance: + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0 && + node->leftnode == NODE && + node->left) { + leftmask |= bitmask; + node = node->left; + } else if ((rightmask & bitmask) == 0 && + node->rightnode == NODE && + node->right) { + rightmask |= bitmask; + node = node->right; + } else { + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } + } + if (verbose > 0) + printf("Pruned %d nodes\n", count); +} + +/* + * Mark the nodes in the tree that lead to leaves that must be + * emitted. + */ +static void +mark_nodes(struct tree *tree) +{ + struct node *node; + struct node *n; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int marked; + + marked = 0; + if (verbose > 0) + printf("Marking %s_%x\n", tree->type, tree->maxage); + if (tree->childnode == LEAF) + goto done; + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + if (tree->leaf_mark(node->left)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->left) { + assert(node->leftnode == NODE); + node = node->left; + continue; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + if (tree->leaf_mark(node->right)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->right) { + assert(node->rightnode==NODE); + node = node->right; + continue; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } + + /* second pass: left siblings and singletons */ + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + if (tree->leaf_mark(node->left)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->left) { + assert(node->leftnode == NODE); + node = node->left; + if (!node->mark && node->parent->mark) { + marked++; + node->mark = 1; + } + continue; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + if (tree->leaf_mark(node->right)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->right) { + assert(node->rightnode==NODE); + node = node->right; + if (!node->mark && node->parent->mark && + !node->parent->left) { + marked++; + node->mark = 1; + } + continue; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } +done: + if (verbose > 0) + printf("Marked %d nodes\n", marked); +} + +/* + * Compute the index of each node and leaf, which is the offset in the + * emitted trie. These value must be pre-computed because relative + * offsets between nodes are used to navigate the tree. + */ +static int +index_nodes(struct tree *tree, int index) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int count; + int indent; + + /* Align to a cache line (or half a cache line?). */ + while (index % 64) + index++; + tree->index = index; + indent = 1; + count = 0; + + if (verbose > 0) + printf("Indexing %s_%x: %d", tree->type, tree->maxage, index); + if (tree->childnode == LEAF) { + index += tree->leaf_size(tree->root); + goto done; + } + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + count++; + if (node->index != index) + node->index = index; + index += node->size; +skip: + while (node) { + bitmask = 1 << node->bitnum; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + *tree->leaf_index(tree, node->left) = + index; + index += tree->leaf_size(node->left); + count++; + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + *tree->leaf_index(tree, node->right) = index; + index += tree->leaf_size(node->right); + count++; + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +done: + /* Round up to a multiple of 16 */ + while (index % 16) + index++; + if (verbose > 0) + printf("Final index %d\n", index); + return index; +} + +/* + * Compute the size of nodes and leaves. We start by assuming that + * each node needs to store a three-byte offset. The indexes of the + * nodes are calculated based on that, and then this function is + * called to see if the sizes of some nodes can be reduced. This is + * repeated until no more changes are seen. + */ +static int +size_nodes(struct tree *tree) +{ + struct tree *next; + struct node *node; + struct node *right; + struct node *n; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + unsigned int pathbits; + unsigned int pathmask; + int changed; + int offset; + int size; + int indent; + + indent = 1; + changed = 0; + size = 0; + + if (verbose > 0) + printf("Sizing %s_%x", tree->type, tree->maxage); + if (tree->childnode == LEAF) + goto done; + + assert(tree->childnode == NODE); + pathbits = 0; + pathmask = 0; + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + offset = 0; + if (!node->left || !node->right) { + size = 1; + } else { + if (node->rightnode == NODE) { + right = node->right; + next = tree->next; + while (!right->mark) { + assert(next); + n = next->root; + while (n->bitnum != node->bitnum) { + if (pathbits & (1<bitnum)) + n = n->right; + else + n = n->left; + } + n = n->right; + assert(right->bitnum == n->bitnum); + right = n; + next = next->next; + } + offset = right->index - node->index; + } else { + offset = *tree->leaf_index(tree, node->right); + offset -= node->index; + } + assert(offset >= 0); + assert(offset <= 0xffffff); + if (offset <= 0xff) { + size = 2; + } else if (offset <= 0xffff) { + size = 3; + } else { /* offset <= 0xffffff */ + size = 4; + } + } + if (node->size != size || node->offset != offset) { + node->size = size; + node->offset = offset; + changed++; + } +skip: + while (node) { + bitmask = 1 << node->bitnum; + pathmask |= bitmask; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + pathbits |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + pathmask &= ~bitmask; + pathbits &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +done: + if (verbose > 0) + printf("Found %d changes\n", changed); + return changed; +} + +/* + * Emit a trie for the given tree into the data array. + */ +static void +emit(struct tree *tree, unsigned char *data) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int offlen; + int offset; + int index; + int indent; + unsigned char byte; + + index = tree->index; + data += index; + indent = 1; + if (verbose > 0) + printf("Emitting %s_%x\n", tree->type, tree->maxage); + if (tree->childnode == LEAF) { + assert(tree->root); + tree->leaf_emit(tree->root, data); + return; + } + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + assert(node->offset != -1); + assert(node->index == index); + + byte = 0; + if (node->nextbyte) + byte |= NEXTBYTE; + byte |= (node->bitnum & BITNUM); + if (node->left && node->right) { + if (node->leftnode == NODE) + byte |= LEFTNODE; + if (node->rightnode == NODE) + byte |= RIGHTNODE; + if (node->offset <= 0xff) + offlen = 1; + else if (node->offset <= 0xffff) + offlen = 2; + else + offlen = 3; + offset = node->offset; + byte |= offlen << OFFLEN_SHIFT; + *data++ = byte; + index++; + while (offlen--) { + *data++ = offset & 0xff; + index++; + offset >>= 8; + } + } else if (node->left) { + if (node->leftnode == NODE) + byte |= TRIENODE; + *data++ = byte; + index++; + } else if (node->right) { + byte |= RIGHTNODE; + if (node->rightnode == NODE) + byte |= TRIENODE; + *data++ = byte; + index++; + } else { + assert(0); + } +skip: + while (node) { + bitmask = 1 << node->bitnum; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + data = tree->leaf_emit(node->left, + data); + index += tree->leaf_size(node->left); + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + data = tree->leaf_emit(node->right, + data); + index += tree->leaf_size(node->right); + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +} + +/* ------------------------------------------------------------------ */ + +/* + * Unicode data. + * + * We need to keep track of the Canonical Combining Class, the Age, + * and decompositions for a code point. + * + * For the Age, we store the index into the ages table. Effectively + * this is a generation number that the table maps to a unicode + * version. + * + * The correction field is used to indicate that this entry is in the + * corrections array, which contains decompositions that were + * corrected in later revisions. The value of the correction field is + * the Unicode version in which the mapping was corrected. + */ +struct unicode_data { + unsigned int code; + int ccc; + int gen; + int correction; + unsigned int *utf32nfkdi; + unsigned int *utf32nfkdicf; + char *utf8nfkdi; + char *utf8nfkdicf; +}; + +struct unicode_data unicode_data[0x110000]; +struct unicode_data *corrections; +int corrections_count; + +struct tree *nfkdi_tree; +struct tree *nfkdicf_tree; + +struct tree *trees; +int trees_count; + +/* + * Check the corrections array to see if this entry was corrected at + * some point. + */ +static struct unicode_data * +corrections_lookup(struct unicode_data *u) +{ + int i; + + for (i = 0; i != corrections_count; i++) + if (u->code == corrections[i].code) + return &corrections[i]; + return u; +} + +static int +nfkdi_equal(void *l, void *r) +{ + struct unicode_data *left = l; + struct unicode_data *right = r; + + if (left->gen != right->gen) + return 0; + if (left->ccc != right->ccc) + return 0; + if (left->utf8nfkdi && right->utf8nfkdi && + strcmp(left->utf8nfkdi, right->utf8nfkdi) == 0) + return 1; + if (left->utf8nfkdi || right->utf8nfkdi) + return 0; + return 1; +} + +static int +nfkdicf_equal(void *l, void *r) +{ + struct unicode_data *left = l; + struct unicode_data *right = r; + + if (left->gen != right->gen) + return 0; + if (left->ccc != right->ccc) + return 0; + if (left->utf8nfkdicf && right->utf8nfkdicf && + strcmp(left->utf8nfkdicf, right->utf8nfkdicf) == 0) + return 1; + if (left->utf8nfkdicf && right->utf8nfkdicf) + return 0; + if (left->utf8nfkdicf || right->utf8nfkdicf) + return 0; + if (left->utf8nfkdi && right->utf8nfkdi && + strcmp(left->utf8nfkdi, right->utf8nfkdi) == 0) + return 1; + if (left->utf8nfkdi || right->utf8nfkdi) + return 0; + return 1; +} + +static void +nfkdi_print(void *l, int indent) +{ + struct unicode_data *leaf = l; + + printf("%*sleaf @ %p code %X ccc %d gen %d", indent, "", leaf, + leaf->code, leaf->ccc, leaf->gen); + if (leaf->utf8nfkdi) + printf(" nfkdi \"%s\"", (const char*)leaf->utf8nfkdi); + printf("\n"); +} + +static void +nfkdicf_print(void *l, int indent) +{ + struct unicode_data *leaf = l; + + printf("%*sleaf @ %p code %X ccc %d gen %d", indent, "", leaf, + leaf->code, leaf->ccc, leaf->gen); + if (leaf->utf8nfkdicf) + printf(" nfkdicf \"%s\"", (const char*)leaf->utf8nfkdicf); + else if (leaf->utf8nfkdi) + printf(" nfkdi \"%s\"", (const char*)leaf->utf8nfkdi); + printf("\n"); +} + +static int +nfkdi_mark(void *l) +{ + return 1; +} + +static int +nfkdicf_mark(void *l) +{ + struct unicode_data *leaf = l; + if (leaf->utf8nfkdicf) + return 1; + return 0; +} + +static int +correction_mark(void *l) +{ + struct unicode_data *leaf = l; + return leaf->correction; +} + +static int +nfkdi_size(void *l) +{ + struct unicode_data *leaf = l; + int size = 2; + if (leaf->utf8nfkdi) + size += strlen(leaf->utf8nfkdi) + 1; + return size; +} + +static int +nfkdicf_size(void *l) +{ + struct unicode_data *leaf = l; + int size = 2; + if (leaf->utf8nfkdicf) + size += strlen(leaf->utf8nfkdicf) + 1; + else if (leaf->utf8nfkdi) + size += strlen(leaf->utf8nfkdi) + 1; + return size; +} + +static int * +nfkdi_index(struct tree *tree, void *l) +{ + struct unicode_data *leaf = l; + return &tree->leafindex[leaf->code]; +} + +static int * +nfkdicf_index(struct tree *tree, void *l) +{ + struct unicode_data *leaf = l; + return &tree->leafindex[leaf->code]; +} + +static unsigned char * +nfkdi_emit(void *l, unsigned char *data) +{ + struct unicode_data *leaf = l; + unsigned char *s; + + *data++ = leaf->gen; + if (leaf->utf8nfkdi) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdi; + while ((*data++ = *s++) != 0) + ; + } else { + *data++ = leaf->ccc; + } + return data; +} + +static unsigned char * +nfkdicf_emit(void *l, unsigned char *data) +{ + struct unicode_data *leaf = l; + unsigned char *s; + + *data++ = leaf->gen; + if (leaf->utf8nfkdicf) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdicf; + while ((*data++ = *s++) != 0) + ; + } else if (leaf->utf8nfkdi) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdi; + while ((*data++ = *s++) != 0) + ; + } else { + *data++ = leaf->ccc; + } + return data; +} + +static void +utf8_create(struct unicode_data *data) +{ + char utf[18*4+1]; + char *u; + unsigned int *um; + int i; + + u = utf; + um = data->utf32nfkdi; + if (um) { + for (i = 0; um[i]; i++) + u += utf8key(um[i], u); + *u = '\0'; + data->utf8nfkdi = strdup((char*)utf); + } + u = utf; + um = data->utf32nfkdicf; + if (um) { + for (i = 0; um[i]; i++) + u += utf8key(um[i], u); + *u = '\0'; + if (!data->utf8nfkdi || strcmp(data->utf8nfkdi, (char*)utf)) + data->utf8nfkdicf = strdup((char*)utf); + } +} + +static void +utf8_init(void) +{ + unsigned int unichar; + int i; + + for (unichar = 0; unichar != 0x110000; unichar++) + utf8_create(&unicode_data[unichar]); + + for (i = 0; i != corrections_count; i++) + utf8_create(&corrections[i]); +} + +static void +trees_init(void) +{ + struct unicode_data *data; + unsigned int maxage; + unsigned int nextage; + int count; + int i; + int j; + + /* Count the number of different ages. */ + count = 0; + nextage = (unsigned int)-1; + do { + maxage = nextage; + nextage = 0; + for (i = 0; i <= corrections_count; i++) { + data = &corrections[i]; + if (nextage < data->correction && + data->correction < maxage) + nextage = data->correction; + } + count++; + } while (nextage); + + /* Two trees per age: nfkdi and nfkdicf */ + trees_count = count * 2; + trees = calloc(trees_count, sizeof(struct tree)); + + /* Assign ages to the trees. */ + count = trees_count; + nextage = (unsigned int)-1; + do { + maxage = nextage; + trees[--count].maxage = maxage; + trees[--count].maxage = maxage; + nextage = 0; + for (i = 0; i <= corrections_count; i++) { + data = &corrections[i]; + if (nextage < data->correction && + data->correction < maxage) + nextage = data->correction; + } + } while (nextage); + + /* The ages assigned above are off by one. */ + for (i = 0; i != trees_count; i++) { + j = 0; + while (ages[j] < trees[i].maxage) + j++; + trees[i].maxage = ages[j-1]; + } + + /* Set up the forwarding between trees. */ + trees[trees_count-2].next = &trees[trees_count-1]; + trees[trees_count-1].leaf_mark = nfkdi_mark; + trees[trees_count-2].leaf_mark = nfkdicf_mark; + for (i = 0; i != trees_count-2; i += 2) { + trees[i].next = &trees[trees_count-2]; + trees[i].leaf_mark = correction_mark; + trees[i+1].next = &trees[trees_count-1]; + trees[i+1].leaf_mark = correction_mark; + } + + /* Assign the callouts. */ + for (i = 0; i != trees_count; i += 2) { + trees[i].type = "nfkdicf"; + trees[i].leaf_equal = nfkdicf_equal; + trees[i].leaf_print = nfkdicf_print; + trees[i].leaf_size = nfkdicf_size; + trees[i].leaf_index = nfkdicf_index; + trees[i].leaf_emit = nfkdicf_emit; + + trees[i+1].type = "nfkdi"; + trees[i+1].leaf_equal = nfkdi_equal; + trees[i+1].leaf_print = nfkdi_print; + trees[i+1].leaf_size = nfkdi_size; + trees[i+1].leaf_index = nfkdi_index; + trees[i+1].leaf_emit = nfkdi_emit; + } + + /* Finish init. */ + for (i = 0; i != trees_count; i++) + trees[i].childnode = NODE; +} + +static void +trees_populate(void) +{ + struct unicode_data *data; + unsigned int unichar; + char keyval[4]; + int keylen; + int i; + + for (i = 0; i != trees_count; i++) { + if (verbose > 0) { + printf("Populating %s_%x\n", + trees[i].type, trees[i].maxage); + } + for (unichar = 0; unichar != 0x110000; unichar++) { + if (unicode_data[unichar].gen < 0) + continue; + keylen = utf8key(unichar, keyval); + data = corrections_lookup(&unicode_data[unichar]); + if (data->correction <= trees[i].maxage) + data = &unicode_data[unichar]; + insert(&trees[i], keyval, keylen, data); + } + } +} + +static void +trees_reduce(void) +{ + int i; + int size; + int changed; + + for (i = 0; i != trees_count; i++) + prune(&trees[i]); + for (i = 0; i != trees_count; i++) + mark_nodes(&trees[i]); + do { + size = 0; + for (i = 0; i != trees_count; i++) + size = index_nodes(&trees[i], size); + changed = 0; + for (i = 0; i != trees_count; i++) + changed += size_nodes(&trees[i]); + } while (changed); + + utf8data = calloc(size, 1); + utf8data_size = size; + for (i = 0; i != trees_count; i++) + emit(&trees[i], utf8data); + + if (verbose > 0) { + for (i = 0; i != trees_count; i++) { + printf("%s_%x idx %d\n", + trees[i].type, trees[i].maxage, trees[i].index); + } + } + + nfkdi = utf8data + trees[trees_count-1].index; + nfkdicf = utf8data + trees[trees_count-2].index; + + nfkdi_tree = &trees[trees_count-1]; + nfkdicf_tree = &trees[trees_count-2]; +} + +static void +verify(struct tree *tree) +{ + struct unicode_data *data; + utf8leaf_t *leaf; + unsigned int unichar; + char key[4]; + int report; + int nocf; + + if (verbose > 0) + printf("Verifying %s_%x\n", tree->type, tree->maxage); + nocf = strcmp(tree->type, "nfkdicf"); + + for (unichar = 0; unichar != 0x110000; unichar++) { + report = 0; + data = corrections_lookup(&unicode_data[unichar]); + if (data->correction <= tree->maxage) + data = &unicode_data[unichar]; + utf8key(unichar, key); + leaf = utf8lookup(tree, key); + if (!leaf) { + if (data->gen != -1) + report++; + if (unichar < 0xd800 || unichar > 0xdfff) + report++; + } else { + if (unichar >= 0xd800 && unichar <= 0xdfff) + report++; + if (data->gen == -1) + report++; + if (data->gen != LEAF_GEN(leaf)) + report++; + if (LEAF_CCC(leaf) == DECOMPOSE) { + if (nocf) { + if (!data->utf8nfkdi) { + report++; + } else if (strcmp(data->utf8nfkdi, + LEAF_STR(leaf))) { + report++; + } + } else { + if (!data->utf8nfkdicf && + !data->utf8nfkdi) { + report++; + } else if (data->utf8nfkdicf) { + if (strcmp(data->utf8nfkdicf, + LEAF_STR(leaf))) + report++; + } else if (strcmp(data->utf8nfkdi, + LEAF_STR(leaf))) { + report++; + } + } + } else if (data->ccc != LEAF_CCC(leaf)) { + report++; + } + } + if (report) { + printf("%X code %X gen %d ccc %d" + " nfdki -> \"%s\"", + unichar, data->code, data->gen, + data->ccc, + data->utf8nfkdi); + if (leaf) { + printf(" age %d ccc %d" + " nfdki -> \"%s\"\n", + LEAF_GEN(leaf), + LEAF_CCC(leaf), + LEAF_CCC(leaf) == DECOMPOSE ? + LEAF_STR(leaf) : ""); + } + printf("\n"); + } + } +} + +static void +trees_verify(void) +{ + int i; + + for (i = 0; i != trees_count; i++) + verify(&trees[i]); +} + +/* ------------------------------------------------------------------ */ + +static void +help(void) +{ + printf("Usage: %s [options]\n", argv0); + printf("\n"); + printf("This program creates an a data trie used for parsing and\n"); + printf("normalization of UTF-8 strings. The trie is derived from\n"); + printf("a set of input files from the Unicode character database\n"); + printf("found at: http://www.unicode.org/Public/UCD/latest/ucd/\n"); + printf("\n"); + printf("The generated tree supports two normalization forms:\n"); + printf("\n"); + printf("\tnfkdi:\n"); + printf("\t- Apply unicode normalization form NFKD.\n"); + printf("\t- Remove any Default_Ignorable_Code_Point.\n"); + printf("\n"); + printf("\tnfkdicf:\n"); + printf("\t- Apply unicode normalization form NFKD.\n"); + printf("\t- Remove any Default_Ignorable_Code_Point.\n"); + printf("\t- Apply a full casefold (C + F).\n"); + printf("\n"); + printf("These forms were chosen as being most useful when dealing\n"); + printf("with file names: NFKD catches most cases where characters\n"); + printf("should be considered equivalent. The ignorables are mostly\n"); + printf("invisible, making names hard to type.\n"); + printf("\n"); + printf("The options to specify the files to be used are listed\n"); + printf("below with their default values, which are the names used\n"); + printf("by version 7.0.0 of the Unicode Character Database.\n"); + printf("\n"); + printf("The input files:\n"); + printf("\t-a %s\n", AGE_NAME); + printf("\t-c %s\n", CCC_NAME); + printf("\t-p %s\n", PROP_NAME); + printf("\t-d %s\n", DATA_NAME); + printf("\t-f %s\n", FOLD_NAME); + printf("\t-n %s\n", NORM_NAME); + printf("\n"); + printf("Additionally, the generated tables are tested using:\n"); + printf("\t-t %s\n", TEST_NAME); + printf("\n"); + printf("Finally, the output file:\n"); + printf("\t-o %s\n", UTF8_NAME); + printf("\n"); +} + +static void +usage(void) +{ + help(); + exit(1); +} + +static void +open_fail(const char *name, int error) +{ + printf("Error %d opening %s: %s\n", error, name, strerror(error)); + exit(1); +} + +static void +file_fail(const char *filename) +{ + printf("Error parsing %s\n", filename); + exit(1); +} + +static void +line_fail(const char *filename, const char *line) +{ + printf("Error parsing %s:%s\n", filename, line); + exit(1); +} + +/* ------------------------------------------------------------------ */ + +static void +print_utf32(unsigned int *utf32str) +{ + int i; + for (i = 0; utf32str[i]; i++) + printf(" %X", utf32str[i]); +} + +static void +print_utf32nfkdi(unsigned int unichar) +{ + printf(" %X ->", unichar); + print_utf32(unicode_data[unichar].utf32nfkdi); + printf("\n"); +} + +static void +print_utf32nfkdicf(unsigned int unichar) +{ + printf(" %X ->", unichar); + print_utf32(unicode_data[unichar].utf32nfkdicf); + printf("\n"); +} + +/* ------------------------------------------------------------------ */ + +static void +age_init(void) +{ + FILE *file; + unsigned int first; + unsigned int last; + unsigned int unichar; + unsigned int major; + unsigned int minor; + unsigned int revision; + int gen; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", age_name); + + file = fopen(age_name, "r"); + if (!file) + open_fail(age_name, errno); + count = 0; + + gen = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "# Age=V%d_%d_%d", + &major, &minor, &revision); + if (ret == 3) { + ages_count++; + if (verbose > 1) + printf(" Age V%d_%d_%d\n", + major, minor, revision); + if (!age_valid(major, minor, revision)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "# Age=V%d_%d", &major, &minor); + if (ret == 2) { + ages_count++; + if (verbose > 1) + printf(" Age V%d_%d\n", major, minor); + if (!age_valid(major, minor, 0)) + line_fail(age_name, line); + continue; + } + } + + /* We must have found something above. */ + if (verbose > 1) + printf("%d age entries\n", ages_count); + if (ages_count == 0 || ages_count > MAXGEN) + file_fail(age_name); + + /* There is a 0 entry. */ + ages_count++; + ages = calloc(ages_count + 1, sizeof(*ages)); + /* And a guard entry. */ + ages[ages_count] = (unsigned int)-1; + + rewind(file); + count = 0; + gen = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "# Age=V%d_%d_%d", + &major, &minor, &revision); + if (ret == 3) { + ages[++gen] = + UNICODE_AGE(major, minor, revision); + if (verbose > 1) + printf(" Age V%d_%d_%d = gen %d\n", + major, minor, revision, gen); + if (!age_valid(major, minor, revision)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "# Age=V%d_%d", &major, &minor); + if (ret == 2) { + ages[++gen] = UNICODE_AGE(major, minor, 0); + if (verbose > 1) + printf(" Age V%d_%d = %d\n", + major, minor, gen); + if (!age_valid(major, minor, 0)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "%X..%X ; %d.%d #", + &first, &last, &major, &minor); + if (ret == 4) { + for (unichar = first; unichar <= last; unichar++) + unicode_data[unichar].gen = gen; + count += 1 + last - first; + if (verbose > 1) + printf(" %X..%X gen %d\n", first, last, gen); + if (!utf32valid(first) || !utf32valid(last)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "%X ; %d.%d #", &unichar, &major, &minor); + if (ret == 3) { + unicode_data[unichar].gen = gen; + count++; + if (verbose > 1) + printf(" %X gen %d\n", unichar, gen); + if (!utf32valid(unichar)) + line_fail(age_name, line); + continue; + } + } + unicode_maxage = ages[gen]; + fclose(file); + + /* Nix surrogate block */ + if (verbose > 1) + printf(" Removing surrogate block D800..DFFF\n"); + for (unichar = 0xd800; unichar <= 0xdfff; unichar++) + unicode_data[unichar].gen = -1; + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(age_name); +} + +static void +ccc_init(void) +{ + FILE *file; + unsigned int first; + unsigned int last; + unsigned int unichar; + unsigned int value; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", ccc_name); + + file = fopen(ccc_name, "r"); + if (!file) + open_fail(ccc_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X..%X ; %d #", &first, &last, &value); + if (ret == 3) { + for (unichar = first; unichar <= last; unichar++) { + unicode_data[unichar].ccc = value; + count++; + } + if (verbose > 1) + printf(" %X..%X ccc %d\n", first, last, value); + if (!utf32valid(first) || !utf32valid(last)) + line_fail(ccc_name, line); + continue; + } + ret = sscanf(line, "%X ; %d #", &unichar, &value); + if (ret == 2) { + unicode_data[unichar].ccc = value; + count++; + if (verbose > 1) + printf(" %X ccc %d\n", unichar, value); + if (!utf32valid(unichar)) + line_fail(ccc_name, line); + continue; + } + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(ccc_name); +} + +static void +nfkdi_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char *s; + unsigned int *um; + int count; + int i; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", data_name); + file = fopen(data_name, "r"); + if (!file) + open_fail(data_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%*[^;];%*[^;];%*[^;];%*[^;];%[^;];", + &unichar, buf0); + if (ret != 2) + continue; + if (!utf32valid(unichar)) + line_fail(data_name, line); + + s = buf0; + /* skip over */ + if (*s == '<') + while (*s++ != ' ') + ; + /* decode the decomposition into UTF-32 */ + i = 0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(data_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + + if (verbose > 1) + print_utf32nfkdi(unichar); + count++; + } + fclose(file); + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(data_name); +} + +static void +nfkdicf_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char status; + char *s; + unsigned int *um; + int i; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", fold_name); + file = fopen(fold_name, "r"); + if (!file) + open_fail(fold_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X; %c; %[^;];", &unichar, &status, buf0); + if (ret != 3) + continue; + if (!utf32valid(unichar)) + line_fail(fold_name, line); + /* Use the C+F casefold. */ + if (status != 'C' && status != 'F') + continue; + s = buf0; + if (*s == '<') + while (*s++ != ' ') + ; + i = 0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(fold_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + + if (verbose > 1) + print_utf32nfkdicf(unichar); + count++; + } + fclose(file); + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(fold_name); +} + +static void +ignore_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int first; + unsigned int last; + unsigned int *um; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", prop_name); + file = fopen(prop_name, "r"); + if (!file) + open_fail(prop_name, errno); + assert(file); + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X..%X ; %s # ", &first, &last, buf0); + if (ret == 3) { + if (strcmp(buf0, "Default_Ignorable_Code_Point")) + continue; + if (!utf32valid(first) || !utf32valid(last)) + line_fail(prop_name, line); + for (unichar = first; unichar <= last; unichar++) { + free(unicode_data[unichar].utf32nfkdi); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdi = um; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdicf = um; + count++; + } + if (verbose > 1) + printf(" %X..%X Default_Ignorable_Code_Point\n", + first, last); + continue; + } + ret = sscanf(line, "%X ; %s # ", &unichar, buf0); + if (ret == 2) { + if (strcmp(buf0, "Default_Ignorable_Code_Point")) + continue; + if (!utf32valid(unichar)) + line_fail(prop_name, line); + free(unicode_data[unichar].utf32nfkdi); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdi = um; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdicf = um; + if (verbose > 1) + printf(" %X Default_Ignorable_Code_Point\n", + unichar); + count++; + continue; + } + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(prop_name); +} + +static void +corrections_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int major; + unsigned int minor; + unsigned int revision; + unsigned int age; + unsigned int *um; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char *s; + int i; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", norm_name); + file = fopen(norm_name, "r"); + if (!file) + open_fail(norm_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%[^;];%[^;];%d.%d.%d #", + &unichar, buf0, buf1, + &major, &minor, &revision); + if (ret != 6) + continue; + if (!utf32valid(unichar) || !age_valid(major, minor, revision)) + line_fail(norm_name, line); + count++; + } + corrections = calloc(count, sizeof(struct unicode_data)); + corrections_count = count; + rewind(file); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%[^;];%[^;];%d.%d.%d #", + &unichar, buf0, buf1, + &major, &minor, &revision); + if (ret != 6) + continue; + if (!utf32valid(unichar) || !age_valid(major, minor, revision)) + line_fail(norm_name, line); + corrections[count] = unicode_data[unichar]; + assert(corrections[count].code == unichar); + age = UNICODE_AGE(major, minor, revision); + corrections[count].correction = age; + + i = 0; + s = buf0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(norm_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + corrections[count].utf32nfkdi = um; + + if (verbose > 1) + printf(" %X -> %s -> %s V%d_%d_%d\n", + unichar, buf0, buf1, major, minor, revision); + count++; + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(norm_name); +} + +/* ------------------------------------------------------------------ */ + +/* + * Hangul decomposition (algorithm from Section 3.12 of Unicode 6.3.0) + * + * AC00;;Lo;0;L;;;;;N;;;;; + * D7A3;;Lo;0;L;;;;;N;;;;; + * + * SBase = 0xAC00 + * LBase = 0x1100 + * VBase = 0x1161 + * TBase = 0x11A7 + * LCount = 19 + * VCount = 21 + * TCount = 28 + * NCount = 588 (VCount * TCount) + * SCount = 11172 (LCount * NCount) + * + * Decomposition: + * SIndex = s - SBase + * + * LV (Canonical/Full) + * LIndex = SIndex / NCount + * VIndex = (Sindex % NCount) / TCount + * LPart = LBase + LIndex + * VPart = VBase + VIndex + * + * LVT (Canonical) + * LVIndex = (SIndex / TCount) * TCount + * TIndex = (Sindex % TCount + * LVPart = LBase + LVIndex + * TPart = TBase + TIndex + * + * LVT (Full) + * LIndex = SIndex / NCount + * VIndex = (Sindex % NCount) / TCount + * TIndex = (Sindex % TCount + * LPart = LBase + LIndex + * VPart = VBase + VIndex + * if (TIndex == 0) { + * d = + * } else { + * TPart = TBase + TIndex + * d = + * } + * + */ + +static void +hangul_decompose(void) +{ + unsigned int sb = 0xAC00; + unsigned int lb = 0x1100; + unsigned int vb = 0x1161; + unsigned int tb = 0x11a7; + /* unsigned int lc = 19; */ + unsigned int vc = 21; + unsigned int tc = 28; + unsigned int nc = (vc * tc); + /* unsigned int sc = (lc * nc); */ + unsigned int unichar; + unsigned int mapping[4]; + unsigned int *um; + int count; + int i; + + if (verbose > 0) + printf("Decomposing hangul\n"); + /* Hangul */ + count = 0; + for (unichar = 0xAC00; unichar <= 0xD7A3; unichar++) { + unsigned int si = unichar - sb; + unsigned int li = si / nc; + unsigned int vi = (si % nc) / tc; + unsigned int ti = si % tc; + + i = 0; + mapping[i++] = lb + li; + mapping[i++] = vb + vi; + if (ti) + mapping[i++] = tb + ti; + mapping[i++] = 0; + + assert(!unicode_data[unichar].utf32nfkdi); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + + assert(!unicode_data[unichar].utf32nfkdicf); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + + if (verbose > 1) + print_utf32nfkdi(unichar); + + count++; + } + if (verbose > 0) + printf("Created %d entries\n", count); +} + +static void +nfkdi_decompose(void) +{ + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + unsigned int *um; + unsigned int *dc; + int count; + int i; + int j; + int ret; + + if (verbose > 0) + printf("Decomposing nfkdi\n"); + + count = 0; + for (unichar = 0; unichar != 0x110000; unichar++) { + if (!unicode_data[unichar].utf32nfkdi) + continue; + for (;;) { + ret = 1; + i = 0; + um = unicode_data[unichar].utf32nfkdi; + while (*um) { + dc = unicode_data[*um].utf32nfkdi; + if (dc) { + for (j = 0; dc[j]; j++) + mapping[i++] = dc[j]; + ret = 0; + } else { + mapping[i++] = *um; + } + um++; + } + mapping[i++] = 0; + if (ret) + break; + free(unicode_data[unichar].utf32nfkdi); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + } + /* Add this decomposition to nfkdicf if there is no entry. */ + if (!unicode_data[unichar].utf32nfkdicf) { + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + } + if (verbose > 1) + print_utf32nfkdi(unichar); + count++; + } + if (verbose > 0) + printf("Processed %d entries\n", count); +} + +static void +nfkdicf_decompose(void) +{ + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + unsigned int *um; + unsigned int *dc; + int count; + int i; + int j; + int ret; + + if (verbose > 0) + printf("Decomposing nfkdicf\n"); + count = 0; + for (unichar = 0; unichar != 0x110000; unichar++) { + if (!unicode_data[unichar].utf32nfkdicf) + continue; + for (;;) { + ret = 1; + i = 0; + um = unicode_data[unichar].utf32nfkdicf; + while (*um) { + dc = unicode_data[*um].utf32nfkdicf; + if (dc) { + for (j = 0; dc[j]; j++) + mapping[i++] = dc[j]; + ret = 0; + } else { + mapping[i++] = *um; + } + um++; + } + mapping[i++] = 0; + if (ret) + break; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + } + if (verbose > 1) + print_utf32nfkdicf(unichar); + count++; + } + if (verbose > 0) + printf("Processed %d entries\n", count); +} + +/* ------------------------------------------------------------------ */ + +int utf8agemax(struct tree *, const char *); +int utf8nagemax(struct tree *, const char *, size_t); +int utf8agemin(struct tree *, const char *); +int utf8nagemin(struct tree *, const char *, size_t); +ssize_t utf8len(struct tree *, const char *); +ssize_t utf8nlen(struct tree *, const char *, size_t); +struct utf8cursor; +int utf8cursor(struct utf8cursor *, struct tree *, const char *); +int utf8ncursor(struct utf8cursor *, struct tree *, const char *, size_t); +int utf8byte(struct utf8cursor *); + +/* + * Use trie to scan s, touching at most len bytes. + * Returns the leaf if one exists, NULL otherwise. + * + * A non-NULL return guarantees that the UTF-8 sequence starting at s + * is well-formed and corresponds to a known unicode code point. The + * shorthand for this will be "is valid UTF-8 unicode". + */ +static utf8leaf_t * +utf8nlookup(struct tree *tree, const char *s, size_t len) +{ + utf8trie_t *trie = utf8data + tree->index; + int offlen; + int offset; + int mask; + int node; + + if (!tree) + return NULL; + if (len == 0) + return NULL; + node = 1; + while (node) { + offlen = (*trie & OFFLEN) >> OFFLEN_SHIFT; + if (*trie & NEXTBYTE) { + if (--len == 0) + return NULL; + s++; + } + mask = 1 << (*trie & BITNUM); + if (*s & mask) { + /* Right leg */ + if (offlen) { + /* Right node at offset of trie */ + node = (*trie & RIGHTNODE); + offset = trie[offlen]; + while (--offlen) { + offset <<= 8; + offset |= trie[offlen]; + } + trie += offset; + } else if (*trie & RIGHTPATH) { + /* Right node after this node */ + node = (*trie & TRIENODE); + trie++; + } else { + /* No right node. */ + node = 0; + trie = NULL; + } + } else { + /* Left leg */ + if (offlen) { + /* Left node after this node. */ + node = (*trie & LEFTNODE); + trie += offlen + 1; + } else if (*trie & RIGHTPATH) { + /* No left node. */ + node = 0; + trie = NULL; + } else { + /* Left node after this node */ + node = (*trie & TRIENODE); + trie++; + } + } + } + return trie; +} + +/* + * Use trie to scan s. + * Returns the leaf if one exists, NULL otherwise. + * + * Forwards to trie_nlookup(). + */ +static utf8leaf_t * +utf8lookup(struct tree *tree, const char *s) +{ + return utf8nlookup(tree, s, (size_t)-1); +} + +/* + * Return the number of bytes used by the current UTF-8 sequence. + * Assumes the input points to the first byte of a valid UTF-8 + * sequence. + */ +static inline int +utf8clen(const char *s) +{ + unsigned char c = *s; + return 1 + (c >= 0xC0) + (c >= 0xE0) + (c >= 0xF0); +} + +/* + * Maximum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if only non-assigned code points are used. + */ +int +utf8agemax(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age > age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Minimum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if non-assigned code points are used. + */ +int +utf8agemin(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + int age = tree->maxage; + int leaf_age; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age < age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemax(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age > age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemin(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int leaf_age; + int age = tree->maxage; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age < age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Length of the normalization of s. + * Return -1 if s is not valid UTF-8 unicode. + * + * A string of Default_Ignorable_Code_Point has length 0. + */ +ssize_t +utf8len(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + if (ages[LEAF_GEN(leaf)] > tree->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Length of the normalization of s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +ssize_t +utf8nlen(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + if (ages[LEAF_GEN(leaf)] > tree->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + len -= utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Cursor structure used by the normalizer. + */ +struct utf8cursor { + struct tree *tree; + const char *s; + const char *p; + const char *ss; + const char *sp; + unsigned int len; + unsigned int slen; + short int ccc; + short int nccc; + unsigned int unichar; +}; + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * s : string. + * len : length of s. + * u8c : pointer to cursor. + * trie : utf8trie_t to use for normalization. + * + * Returns -1 on error, 0 on success. + */ +int +utf8ncursor( + struct utf8cursor *u8c, + struct tree *tree, + const char *s, + size_t len) +{ + if (!tree) + return -1; + if (!s) + return -1; + u8c->tree = tree; + u8c->s = s; + u8c->p = NULL; + u8c->ss = NULL; + u8c->sp = NULL; + u8c->len = len; + u8c->slen = 0; + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->unichar = 0; + /* Check we didn't clobber the maximum length. */ + if (u8c->len != len) + return -1; + /* The first byte of s may not be an utf8 continuation. */ + if (len > 0 && (*s & 0xC0) == 0x80) + return -1; + return 0; +} + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * s : NUL-terminated string. + * u8c : pointer to cursor. + * trie : utf8trie_t to use for normalization. + * + * Returns -1 on error, 0 on success. + */ +int +utf8cursor( + struct utf8cursor *u8c, + struct tree *tree, + const char *s) +{ + return utf8ncursor(u8c, tree, s, (unsigned int)-1); +} + +/* + * Get one byte from the normalized form of the string described by u8c. + * + * Returns the byte cast to an unsigned char on succes, and -1 on failure. + * + * The cursor keeps track of the location in the string in u8c->s. + * When a character is decomposed, the current location is stored in + * u8c->p, and u8c->s is set to the start of the decomposition. Note + * that bytes from a decomposition do not count against u8c->len. + * + * Characters are emitted if they match the current CCC in u8c->ccc. + * Hitting end-of-string while u8c->ccc == STOPPER means we're done, + * and the function returns 0 in that case. + * + * Sorting by CCC is done by repeatedly scanning the string. The + * values of u8c->s and u8c->p are stored in u8c->ss and u8c->sp at + * the start of the scan. The first pass finds the lowest CCC to be + * emitted and stores it in u8c->nccc, the second pass emits the + * characters with this CCC and finds the next lowest CCC. This limits + * the number of passes to 1 + the number of different CCCs in the + * sequence being scanned. + * + * Therefore: + * u8c->p != NULL -> a decomposition is being scanned. + * u8c->ss != NULL -> this is a repeating scan. + * u8c->ccc == -1 -> this is the first scan of a repeating scan. + */ +int +utf8byte(struct utf8cursor *u8c) +{ + utf8leaf_t *leaf; + int ccc; + + for (;;) { + /* Check for the end of a decomposed character. */ + if (u8c->p && *u8c->s == '\0') { + u8c->s = u8c->p; + u8c->p = NULL; + } + + /* Check for end-of-string. */ + if (!u8c->p && (u8c->len == 0 || *u8c->s == '\0')) { + /* There is no next byte. */ + if (u8c->ccc == STOPPER) + return 0; + /* End-of-string during a scan counts as a stopper. */ + ccc = STOPPER; + goto ccc_mismatch; + } else if ((*u8c->s & 0xC0) == 0x80) { + /* This is a continuation of the current character. */ + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Look up the data for the current character. */ + if (u8c->p) + leaf = utf8lookup(u8c->tree, u8c->s); + else + leaf = utf8nlookup(u8c->tree, u8c->s, u8c->len); + + /* No leaf found implies that the input is a binary blob. */ + if (!leaf) + return -1; + + /* Characters that are too new have CCC 0. */ + if (ages[LEAF_GEN(leaf)] > u8c->tree->maxage) { + ccc = STOPPER; + } else if ((ccc = LEAF_CCC(leaf)) == DECOMPOSE) { + u8c->len -= utf8clen(u8c->s); + u8c->p = u8c->s + utf8clen(u8c->s); + u8c->s = LEAF_STR(leaf); + /* Empty decomposition implies CCC 0. */ + if (*u8c->s == '\0') { + if (u8c->ccc == STOPPER) + continue; + ccc = STOPPER; + goto ccc_mismatch; + } + leaf = utf8lookup(u8c->tree, u8c->s); + ccc = LEAF_CCC(leaf); + } + u8c->unichar = utf8code(u8c->s); + + /* + * If this is not a stopper, then see if it updates + * the next canonical class to be emitted. + */ + if (ccc != STOPPER && u8c->ccc < ccc && ccc < u8c->nccc) + u8c->nccc = ccc; + + /* + * Return the current byte if this is the current + * combining class. + */ + if (ccc == u8c->ccc) { + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Current combining class mismatch. */ + ccc_mismatch: + if (u8c->nccc == STOPPER) { + /* + * Scan forward for the first canonical class + * to be emitted. Save the position from + * which to restart. + */ + assert(u8c->ccc == STOPPER); + u8c->ccc = MINCCC - 1; + u8c->nccc = ccc; + u8c->sp = u8c->p; + u8c->ss = u8c->s; + u8c->slen = u8c->len; + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (ccc != STOPPER) { + /* Not a stopper, and not the ccc we're emitting. */ + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (u8c->nccc != MAXCCC + 1) { + /* At a stopper, restart for next ccc. */ + u8c->ccc = u8c->nccc; + u8c->nccc = MAXCCC + 1; + u8c->s = u8c->ss; + u8c->p = u8c->sp; + u8c->len = u8c->slen; + } else { + /* All done, proceed from here. */ + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->sp = NULL; + u8c->ss = NULL; + u8c->slen = 0; + } + } +} + +/* ------------------------------------------------------------------ */ + +static int +normalize_line(struct tree *tree) +{ + char *s; + char *t; + int c; + struct utf8cursor u8c; + + /* First test: null-terminated string. */ + s = buf2; + t = buf3; + if (utf8cursor(&u8c, tree, s)) + return -1; + while ((c = utf8byte(&u8c)) > 0) + if (c != (unsigned char)*t++) + return -1; + if (c < 0) + return -1; + if (*t != 0) + return -1; + + /* Second test: length-limited string. */ + s = buf2; + /* Replace NUL with a value that will cause an error if seen. */ + s[strlen(s) + 1] = -1; + t = buf3; + if (utf8cursor(&u8c, tree, s)) + return -1; + while ((c = utf8byte(&u8c)) > 0) + if (c != (unsigned char)*t++) + return -1; + if (c < 0) + return -1; + if (*t != 0) + return -1; + + return 0; +} + +static void +normalization_test(void) +{ + FILE *file; + unsigned int unichar; + struct unicode_data *data; + char *s; + char *t; + int ret; + int ignorables; + int tests = 0; + int failures = 0; + + if (verbose > 0) + printf("Parsing %s\n", test_name); + /* Step one, read data from file. */ + file = fopen(test_name, "r"); + if (!file) + open_fail(test_name, errno); + + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%[^;];%*[^;];%*[^;];%*[^;];%[^;];", + buf0, buf1); + if (ret != 2 || *line == '#') + continue; + s = buf0; + t = buf2; + while (*s) { + unichar = strtoul(s, &s, 16); + t += utf8key(unichar, t); + } + *t = '\0'; + + ignorables = 0; + s = buf1; + t = buf3; + while (*s) { + unichar = strtoul(s, &s, 16); + data = &unicode_data[unichar]; + if (data->utf8nfkdi && !*data->utf8nfkdi) + ignorables = 1; + else + t += utf8key(unichar, t); + } + *t = '\0'; + + tests++; + if (normalize_line(nfkdi_tree) < 0) { + printf("\nline %s -> %s", buf0, buf1); + if (ignorables) + printf(" (ignorables removed)"); + printf(" failure\n"); + failures++; + } + } + fclose(file); + if (verbose > 0) + printf("Ran %d tests with %d failures\n", tests, failures); + if (failures) + file_fail(test_name); +} + +/* ------------------------------------------------------------------ */ + +static void +write_file(void) +{ + FILE *file; + int i; + int j; + int t; + int gen; + + if (verbose > 0) + printf("Writing %s\n", utf8_name); + file = fopen(utf8_name, "w"); + if (!file) + open_fail(utf8_name, errno); + + fprintf(file, "/* This file is generated code, do not edit. */\n"); + fprintf(file, "#ifndef __INCLUDED_FROM_UTF8NORM_C__\n"); + fprintf(file, "#error Only xfs_utf8.c may include this file.\n"); + fprintf(file, "#endif\n"); + fprintf(file, "\n"); + fprintf(file, "const unsigned int utf8version = %#x;\n", + unicode_maxage); + fprintf(file, "\n"); + fprintf(file, "static const unsigned int utf8agetab[] = {\n"); + for (i = 0; i != ages_count; i++) + fprintf(file, "\t%#x%s\n", ages[i], + ages[i] == unicode_maxage ? "" : ","); + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const struct utf8data utf8nfkdicfdata[] = {\n"); + t = 0; + for (gen = 0; gen < ages_count; gen++) { + fprintf(file, "\t{ %#x, %d }%s\n", + ages[gen], trees[t].index, + ages[gen] == unicode_maxage ? "" : ","); + if (trees[t].maxage == ages[gen]) + t += 2; + } + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const struct utf8data utf8nfkdidata[] = {\n"); + t = 1; + for (gen = 0; gen < ages_count; gen++) { + fprintf(file, "\t{ %#x, %d }%s\n", + ages[gen], trees[t].index, + ages[gen] == unicode_maxage ? "" : ","); + if (trees[t].maxage == ages[gen]) + t += 2; + } + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const unsigned char utf8data[%zd] = {\n", + utf8data_size); + t = 0; + for (i = 0; i != utf8data_size; i += 16) { + if (i == trees[t].index) { + fprintf(file, "\t/* %s_%x */\n", + trees[t].type, trees[t].maxage); + if (t < trees_count-1) + t++; + } + fprintf(file, "\t"); + for (j = i; j != i + 16; j++) + fprintf(file, "0x%.2x%s", utf8data[j], + (j < utf8data_size -1 ? "," : "")); + fprintf(file, "\n"); + } + fprintf(file, "};\n"); + fclose(file); +} + +/* ------------------------------------------------------------------ */ + +int +main(int argc, char *argv[]) +{ + unsigned int unichar; + int opt; + + argv0 = argv[0]; + + while ((opt = getopt(argc, argv, "a:c:d:f:hn:o:p:t:v")) != -1) { + switch (opt) { + case 'a': + age_name = optarg; + break; + case 'c': + ccc_name = optarg; + break; + case 'd': + data_name = optarg; + break; + case 'f': + fold_name = optarg; + break; + case 'n': + norm_name = optarg; + break; + case 'o': + utf8_name = optarg; + break; + case 'p': + prop_name = optarg; + break; + case 't': + test_name = optarg; + break; + case 'v': + verbose++; + break; + case 'h': + help(); + exit(0); + default: + usage(); + } + } + + if (verbose > 1) + help(); + for (unichar = 0; unichar != 0x110000; unichar++) + unicode_data[unichar].code = unichar; + age_init(); + ccc_init(); + nfkdi_init(); + nfkdicf_init(); + ignore_init(); + corrections_init(); + hangul_decompose(); + nfkdi_decompose(); + nfkdicf_decompose(); + utf8_init(); + trees_init(); + trees_populate(); + trees_reduce(); + trees_verify(); + /* Prevent "unused function" warning. */ + (void)lookup(nfkdi_tree, " "); + if (verbose > 2) + tree_walk(nfkdi_tree); + if (verbose > 2) + tree_walk(nfkdicf_tree); + normalization_test(); + write_file(); + + return 0; +} -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:38:42 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C6DC07F52 for ; Thu, 18 Sep 2014 15:38:42 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8788C8F8065; Thu, 18 Sep 2014 13:38:42 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 439EE4266DC; Thu, 18 Sep 2014 15:38:42 -0500 (CDT) Date: Thu, 18 Sep 2014 15:38:42 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 08/13] libxfs: add xfs_nameops for utf8 and utf8+casefold. Message-ID: <20140918203842.GV4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918203114.GN4482@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber The xfs_utf8_nameops use the nfkdi normalization when comparing filenames, and are installed if the utf8bit is set in the super block. The xfs_utf8_ci_nameops use the nfkdicf normalization when comparing filenames, and are installed if both the utf8bit and the borgbit are set in the superblock. Normalized filenames are not stored on disk. Normalization will fail if a filename is not valid UTF-8, in which case the filename is treated as an opaque blob. Changes: Type conversion to "(const char *)" added to utf8ncursor() and utf8nlen() calls. Signed-off-by: Olaf Weber --- Makefile | 2 +- include/libxfs.h | 1 + include/xfs_utf8.h | 25 ++++++ libxfs/Makefile | 4 +- libxfs/xfs_dir2.c | 15 +++- libxfs/xfs_utf8.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++++ support/Makefile | 24 ++++++ 7 files changed, 303 insertions(+), 6 deletions(-) create mode 100644 include/xfs_utf8.h create mode 100644 libxfs/xfs_utf8.c create mode 100644 support/Makefile diff --git a/Makefile b/Makefile index f56aebd..c442da6 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ LDIRDIRT = $(SRCDIR) LDIRT += $(SRCTAR) endif -LIB_SUBDIRS = libxfs libxlog libxcmd libhandle libdisk +LIB_SUBDIRS = support libxfs libxlog libxcmd libhandle libdisk TOOL_SUBDIRS = copy db estimate fsck fsr growfs io logprint mkfs quota \ mdrestore repair rtcp m4 man doc po debian diff --git a/include/libxfs.h b/include/libxfs.h index 45a924f..99cb3d9 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -59,6 +59,7 @@ #include #include #include +#include #ifndef ARRAY_SIZE diff --git a/include/xfs_utf8.h b/include/xfs_utf8.h new file mode 100644 index 0000000..97b6a91 --- /dev/null +++ b/include/xfs_utf8.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef XFS_UTF8_H +#define XFS_UTF8_H + +extern struct xfs_nameops xfs_utf8_nameops; +extern struct xfs_nameops xfs_utf8_ci_nameops; + +#endif /* XFS_UTF8_H */ diff --git a/libxfs/Makefile b/libxfs/Makefile index ae15a5d..d836027 100644 --- a/libxfs/Makefile +++ b/libxfs/Makefile @@ -14,6 +14,7 @@ HFILES = xfs.h init.h xfs_dir2_priv.h crc32defs.h crc32table.h CFILES = cache.c \ crc32.c \ init.c kmem.c logitem.c radix-tree.c rdwr.c trans.c util.c \ + utf8norm.c \ xfs_alloc.c \ xfs_alloc_btree.c \ xfs_attr.c \ @@ -38,7 +39,8 @@ CFILES = cache.c \ xfs_rtbitmap.c \ xfs_sb.c \ xfs_symlink_remote.c \ - xfs_trans_resv.c + xfs_trans_resv.c \ + xfs_utf8.c CFILES += $(PKG_PLATFORM).c PCFILES = darwin.c freebsd.c irix.c linux.c diff --git a/libxfs/xfs_dir2.c b/libxfs/xfs_dir2.c index 1893931..6872844 100644 --- a/libxfs/xfs_dir2.c +++ b/libxfs/xfs_dir2.c @@ -123,10 +123,17 @@ xfs_dir_mount( (uint)sizeof(xfs_da_node_entry_t); mp->m_dir_magicpct = (mp->m_dirblksize * 37) / 100; - if (xfs_sb_version_hasasciici(&mp->m_sb)) - mp->m_dirnameops = &xfs_ascii_ci_nameops; - else - mp->m_dirnameops = &xfs_default_nameops; + if (xfs_sb_version_hasutf8(&mp->m_sb)) { + if (xfs_sb_version_hasasciici(&mp->m_sb)) + mp->m_dirnameops = &xfs_utf8_ci_nameops; + else + mp->m_dirnameops = &xfs_utf8_nameops; + } else { + if (xfs_sb_version_hasasciici(&mp->m_sb)) + mp->m_dirnameops = &xfs_ascii_ci_nameops; + else + mp->m_dirnameops = &xfs_default_nameops; + } } /* diff --git a/libxfs/xfs_utf8.c b/libxfs/xfs_utf8.c new file mode 100644 index 0000000..f5cc231 --- /dev/null +++ b/libxfs/xfs_utf8.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "xfs.h" +#include "xfs_fs.h" +#include "xfs_types.h" +#include "xfs_bit.h" +#include "xfs_inum.h" +#include "xfs_sb.h" +#include "xfs_ag.h" +#include "xfs_dir2.h" +#include "xfs_da_btree.h" +#include "xfs_bmap_btree.h" +#include "xfs_alloc_btree.h" +#include "xfs_dinode.h" +#include "xfs_inode_fork.h" +#include "xfs_bmap.h" +#include "xfs_dir2.h" +#include "xfs_trace.h" +#include "xfs_utf8.h" +#include "utf8norm.h" + +/* + * xfs nameops using nfkdi + */ + +static xfs_dahash_t +xfs_utf8_hashname( + const unsigned char *name, + int len) +{ + utf8data_t nfkdi; + struct utf8cursor u8c; + xfs_dahash_t hash; + int val; + + nfkdi = utf8nfkdi(utf8version); + hash = 0; + if (utf8ncursor(&u8c, nfkdi, (const char *)name, len) < 0) + goto blob; + while ((val = utf8byte(&u8c)) > 0) + hash = val ^ rol32(hash, 7); + /* In case of error treat the name as a binary blob. */ + if (val == 0) + return hash; +blob: + return xfs_da_hashname(name, len); +} + +static int +xfs_utf8_normhash( + struct xfs_da_args *args) +{ + utf8data_t nfkdi; + struct utf8cursor u8c; + unsigned char *norm; + ssize_t normlen; + int c; + + nfkdi = utf8nfkdi(utf8version); + /* Failure to normalize is treated as a blob. */ + if ((normlen = utf8nlen(nfkdi, (const char *)args->name, + args->namelen)) < 0) + goto blob; + if (utf8ncursor(&u8c, nfkdi, (const char *)args->name, + args->namelen) < 0) + goto blob; + if (!(norm = kmem_alloc(normlen + 1, KM_NOFS|KM_MAYFAIL))) + return ENOMEM; + args->norm = norm; + args->normlen = normlen; + while ((c = utf8byte(&u8c)) > 0) + *norm++ = c; + if (c == 0) { + *norm = '\0'; + args->hashval = xfs_da_hashname(args->norm, args->normlen); + return 0; + } + kmem_free((void *)args->norm); +blob: + args->norm = NULL; + args->normlen = -1; + args->hashval = xfs_da_hashname(args->name, args->namelen); + return 0; +} + +static enum xfs_dacmp +xfs_utf8_compname( + struct xfs_da_args *args, + const unsigned char *name, + int len) +{ + utf8data_t nfkdi; + struct utf8cursor u8c; + const char *norm; + int c; + + ASSERT(args->norm || args->normlen == -1); + + /* Check for an exact match first. */ + if (args->namelen == len && memcmp(args->name, name, len) == 0) + return XFS_CMP_EXACT; + /* xfs_utf8_normhash() set args->normlen to -1 for a blob */ + if (args->normlen < 0) + return XFS_CMP_DIFFERENT; + nfkdi = utf8nfkdi(utf8version); + if (utf8ncursor(&u8c, nfkdi, (const char *)name, len) < 0) + return XFS_CMP_DIFFERENT; + norm = (const char *)args->norm; + while ((c = utf8byte(&u8c)) > 0) + if (c != *norm++) + return XFS_CMP_DIFFERENT; + if (c < 0 || *norm != '\0') + return XFS_CMP_DIFFERENT; + return XFS_CMP_MATCH; +} + +struct xfs_nameops xfs_utf8_nameops = { + .hashname = xfs_utf8_hashname, + .normhash = xfs_utf8_normhash, + .compname = xfs_utf8_compname, +}; + +/* + * xfs nameops using nfkdicf + */ + +static xfs_dahash_t +xfs_utf8_ci_hashname( + const unsigned char *name, + int len) +{ + utf8data_t nfkdicf; + struct utf8cursor u8c; + xfs_dahash_t hash; + int val; + + nfkdicf = utf8nfkdicf(utf8version); + hash = 0; + if (utf8ncursor(&u8c, nfkdicf, (const char *)name, len) < 0) + goto blob; + while ((val = utf8byte(&u8c)) > 0) + hash = val ^ rol32(hash, 7); + /* In case of error treat the name as a binary blob. */ + if (val == 0) + return hash; +blob: + return xfs_da_hashname(name, len); +} + +static int +xfs_utf8_ci_normhash( + struct xfs_da_args *args) +{ + utf8data_t nfkdicf; + struct utf8cursor u8c; + unsigned char *norm; + ssize_t normlen; + int c; + + nfkdicf = utf8nfkdicf(utf8version); + /* Failure to normalize is treated as a blob. */ + if ((normlen = utf8nlen(nfkdicf, (const char *)args->name, + args->namelen)) < 0) + goto blob; + if (utf8ncursor(&u8c, nfkdicf, (const char *)args->name, + args->namelen) < 0) + goto blob; + if (!(norm = kmem_alloc(normlen + 1, KM_NOFS|KM_MAYFAIL))) + return ENOMEM; + args->norm = norm; + args->normlen = normlen; + while ((c = utf8byte(&u8c)) > 0) + *norm++ = c; + if (c == 0) { + *norm = '\0'; + args->hashval = xfs_da_hashname(args->norm, args->normlen); + return 0; + } + kmem_free((void *)args->norm); +blob: + args->norm = NULL; + args->normlen = -1; + args->hashval = xfs_da_hashname(args->name, args->namelen); + return 0; +} + +static enum xfs_dacmp +xfs_utf8_ci_compname( + struct xfs_da_args *args, + const unsigned char *name, + int len) +{ + utf8data_t nfkdicf; + struct utf8cursor u8c; + const unsigned char *norm; + int c; + + ASSERT(args->norm || args->normlen == -1); + + /* Check for an exact match first. */ + if (args->namelen == len && memcmp(args->name, name, len) == 0) + return XFS_CMP_EXACT; + /* xfs_utf8_ci_normhash() set args->normlen to -1 for a blob */ + if (args->normlen < 0) + return XFS_CMP_DIFFERENT; + nfkdicf = utf8nfkdicf(utf8version); + if (utf8ncursor(&u8c, nfkdicf, (const char *)name, len) < 0) + return XFS_CMP_DIFFERENT; + norm = args->norm; + while ((c = utf8byte(&u8c)) > 0) + if (c != *norm++) + return XFS_CMP_DIFFERENT; + if (c < 0 || *norm != '\0') + return XFS_CMP_DIFFERENT; + return XFS_CMP_MATCH; +} + +struct xfs_nameops xfs_utf8_ci_nameops = { + .hashname = xfs_utf8_ci_hashname, + .normhash = xfs_utf8_ci_normhash, + .compname = xfs_utf8_ci_compname, +}; diff --git a/support/Makefile b/support/Makefile new file mode 100644 index 0000000..cade5fe --- /dev/null +++ b/support/Makefile @@ -0,0 +1,24 @@ +# +# Copyright (c) 2014 SGI. All Rights Reserved. +# + +TOPDIR = .. +include $(TOPDIR)/include/builddefs + +default = ../include/utf8data.h + +../include/utf8data.h: mkutf8data.c + cc -o mkutf8data mkutf8data.c + cd ucd-7.0.0 ; ../mkutf8data + mv ucd-7.0.0/utf8data.h ../include + +default clean: + rm -f mkutf8data ../include/utf8data.h + +default install: + +default install-dev: + +default install-qa: + +-include .ltdep -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:39:34 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B5C1C7F52 for ; Thu, 18 Sep 2014 15:39:34 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8419C8F8065; Thu, 18 Sep 2014 13:39:34 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 4B0234266DC; Thu, 18 Sep 2014 15:39:34 -0500 (CDT) Date: Thu, 18 Sep 2014 15:39:34 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 09/13] libxfs: apply utf-8 normalization rules to user extended attribute names Message-ID: <20140918203934.GW4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918203114.GN4482@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Apply the same rules for UTF-8 normalization to the names of user-defined extended attributes. System attributes are excluded because they are not user-visible in the first place, and the kernel is expected to know what it is doing when naming them. Signed-off-by: Olaf Weber --- libxfs/xfs_attr.c | 49 +++++++++++++++++++++++++++++++++++++++++-------- libxfs/xfs_attr_leaf.c | 11 +++++++++-- libxfs/xfs_utf8.c | 7 +++++++ 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/libxfs/xfs_attr.c b/libxfs/xfs_attr.c index 17519d3..c30703b 100644 --- a/libxfs/xfs_attr.c +++ b/libxfs/xfs_attr.c @@ -88,8 +88,9 @@ xfs_attr_get_int( int *valuelenp, int flags) { - xfs_da_args_t args; - int error; + xfs_da_args_t args; + struct xfs_mount *mp = ip->i_mount; + int error; if (!xfs_inode_hasattr(ip)) return ENOATTR; @@ -103,9 +104,12 @@ xfs_attr_get_int( args.value = value; args.valuelen = *valuelenp; args.flags = flags; - args.hashval = xfs_da_hashname(args.name, args.namelen); args.dp = ip; args.whichfork = XFS_ATTR_FORK; + if (! xfs_sb_version_hasutf8(&mp->m_sb)) + args.hashval = xfs_da_hashname(args.name, args.namelen); + else if ((error = mp->m_dirnameops->normhash(&args)) != 0) + return error; /* * Decide on what work routines to call based on the inode size. @@ -118,6 +122,9 @@ xfs_attr_get_int( error = xfs_attr_node_get(&args); } + if (args.norm) + kmem_free((void *)args.norm); + /* * Return the number of bytes in the value to the caller. */ @@ -239,12 +246,15 @@ xfs_attr_set_int( args.value = value; args.valuelen = valuelen; args.flags = flags; - args.hashval = xfs_da_hashname(args.name, args.namelen); args.dp = dp; args.firstblock = &firstblock; args.flist = &flist; args.whichfork = XFS_ATTR_FORK; args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT; + if (! xfs_sb_version_hasutf8(&mp->m_sb)) + args.hashval = xfs_da_hashname(args.name, args.namelen); + else if ((error = mp->m_dirnameops->normhash(&args)) != 0) + return error; /* Size is now blocks for attribute data */ args.total = xfs_attr_calc_size(dp, name->len, valuelen, &local); @@ -276,6 +286,8 @@ xfs_attr_set_int( error = xfs_trans_reserve(args.trans, &tres, args.total, 0); if (error) { xfs_trans_cancel(args.trans, 0); + if (args.norm) + kmem_free((void *)args.norm); return(error); } xfs_ilock(dp, XFS_ILOCK_EXCL); @@ -286,6 +298,8 @@ xfs_attr_set_int( if (error) { xfs_iunlock(dp, XFS_ILOCK_EXCL); xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES); + if (args.norm) + kmem_free((void *)args.norm); return (error); } @@ -333,7 +347,8 @@ xfs_attr_set_int( err2 = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); - + if (args.norm) + kmem_free((void *)args.norm); return(error == 0 ? err2 : error); } @@ -398,6 +413,8 @@ xfs_attr_set_int( xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE); error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (args.norm) + kmem_free((void *)args.norm); return(error); @@ -406,6 +423,9 @@ out: xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (args.norm) + kmem_free((void *)args.norm); + return(error); } @@ -452,12 +472,15 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) args.name = name->name; args.namelen = name->len; args.flags = flags; - args.hashval = xfs_da_hashname(args.name, args.namelen); args.dp = dp; args.firstblock = &firstblock; args.flist = &flist; args.total = 0; args.whichfork = XFS_ATTR_FORK; + if (! xfs_sb_version_hasutf8(&mp->m_sb)) + args.hashval = xfs_da_hashname(args.name, args.namelen); + else if ((error = mp->m_dirnameops->normhash(&args)) != 0) + return error; /* * we have no control over the attribute names that userspace passes us @@ -470,8 +493,11 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) * Attach the dquots to the inode. */ error = xfs_qm_dqattach(dp, 0); - if (error) - return error; + if (error) { + if (args.norm) + kmem_free((void *)args.norm); + return error; + } /* * Start our first transaction of the day. @@ -497,6 +523,8 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) XFS_ATTRRM_SPACE_RES(mp), 0); if (error) { xfs_trans_cancel(args.trans, 0); + if (args.norm) + kmem_free((void *)args.norm); return(error); } @@ -546,6 +574,8 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags) xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE); error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES); xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (args.norm) + kmem_free((void *)args.norm); return(error); @@ -554,6 +584,9 @@ out: xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (args.norm) + kmem_free((void *)args.norm); + return(error); } diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c index f7f02ae..052a6a1 100644 --- a/libxfs/xfs_attr_leaf.c +++ b/libxfs/xfs_attr_leaf.c @@ -634,6 +634,7 @@ int xfs_attr_shortform_to_leaf(xfs_da_args_t *args) { xfs_inode_t *dp; + struct xfs_mount *mp; xfs_attr_shortform_t *sf; xfs_attr_sf_entry_t *sfe; xfs_da_args_t nargs; @@ -646,6 +647,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) trace_xfs_attr_sf_to_leaf(args); dp = args->dp; + mp = dp->i_mount; ifp = dp->i_afp; sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data; size = be16_to_cpu(sf->hdr.totsize); @@ -698,13 +700,18 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args) nargs.namelen = sfe->namelen; nargs.value = &sfe->nameval[nargs.namelen]; nargs.valuelen = sfe->valuelen; - nargs.hashval = xfs_da_hashname(sfe->nameval, - sfe->namelen); nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags); + if (! xfs_sb_version_hasutf8(&mp->m_sb)) + nargs.hashval = xfs_da_hashname(sfe->nameval, + sfe->namelen); + else if ((error = mp->m_dirnameops->normhash(&nargs)) != 0) + goto out; error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */ ASSERT(error == ENOATTR); error = xfs_attr3_leaf_add(bp, &nargs); ASSERT(error != ENOSPC); + if (nargs.norm) + kmem_free((void *)nargs.norm); if (error) goto out; sfe = XFS_ATTR_SF_NEXTENTRY(sfe); diff --git a/libxfs/xfs_utf8.c b/libxfs/xfs_utf8.c index f5cc231..5c69591 100644 --- a/libxfs/xfs_utf8.c +++ b/libxfs/xfs_utf8.c @@ -31,6 +31,7 @@ #include "xfs_inode_fork.h" #include "xfs_bmap.h" #include "xfs_dir2.h" +#include "xfs_attr_leaf.h" #include "xfs_trace.h" #include "xfs_utf8.h" #include "utf8norm.h" @@ -72,6 +73,9 @@ xfs_utf8_normhash( ssize_t normlen; int c; + /* Don't normalize system attribute names. */ + if (args->flags & (ATTR_ROOT|ATTR_SECURE)) + goto blob; nfkdi = utf8nfkdi(utf8version); /* Failure to normalize is treated as a blob. */ if ((normlen = utf8nlen(nfkdi, (const char *)args->name, @@ -173,6 +177,9 @@ xfs_utf8_ci_normhash( ssize_t normlen; int c; + /* Don't normalize system attribute names. */ + if (args->flags & (ATTR_ROOT|ATTR_SECURE)) + goto blob; nfkdicf = utf8nfkdicf(utf8version); /* Failure to normalize is treated as a blob. */ if ((normlen = utf8nlen(nfkdicf, (const char *)args->name, -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:40:17 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B1C867F52 for ; Thu, 18 Sep 2014 15:40:17 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id 338C1AC003; Thu, 18 Sep 2014 13:40:17 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id E9D5F4266DC; Thu, 18 Sep 2014 15:40:16 -0500 (CDT) Date: Thu, 18 Sep 2014 15:40:16 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 10/13] xfsprogs: add utf8 support to growfs Message-ID: <20140918204016.GX4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918203114.GN4482@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Mark Tinguely Add reporting of the utf-8 mkfs options to xfs_growfs and xfs_info. Signed-off-by: Mark Tinguely --- growfs/xfs_growfs.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/growfs/xfs_growfs.c b/growfs/xfs_growfs.c index 8e611b6..6c41803 100644 --- a/growfs/xfs_growfs.c +++ b/growfs/xfs_growfs.c @@ -57,7 +57,8 @@ report_info( int crcs_enabled, int cimode, int ftype_enabled, - int finobt_enabled) + int finobt_enabled, + int utf8) { printf(_( "meta-data=%-22s isize=%-6u agcount=%u, agsize=%u blks\n" @@ -65,7 +66,7 @@ report_info( " =%-22s crc=%-8u finobt=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" - "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" + "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d utf8=%d\n" "log =%-22s bsize=%-6u blocks=%u, version=%u\n" " =%-22s sectsz=%-5u sunit=%u blks, lazy-count=%u\n" "realtime =%-22s extsz=%-6u blocks=%llu, rtextents=%llu\n"), @@ -76,7 +77,7 @@ report_info( "", geo.blocksize, (unsigned long long)geo.datablocks, geo.imaxpct, "", geo.sunit, geo.swidth, - dirversion, geo.dirblocksize, cimode, ftype_enabled, + dirversion, geo.dirblocksize, cimode, ftype_enabled, utf8, isint ? _("internal") : logname ? logname : _("external"), geo.blocksize, geo.logblocks, logversion, "", geo.logsectsize, geo.logsunit / geo.blocksize, lazycount, @@ -114,6 +115,7 @@ main(int argc, char **argv) long long rsize; /* new rt size in fs blocks */ int ci; /* ASCII case-insensitive fs */ int lazycount; /* lazy superblock counters */ + int utf8; /* Unicode chars supported */ int xflag; /* -x flag */ char *fname; /* mount point name */ char *datadev; /* data device name */ @@ -247,11 +249,12 @@ main(int argc, char **argv) crcs_enabled = geo.flags & XFS_FSOP_GEOM_FLAGS_V5SB ? 1 : 0; ftype_enabled = geo.flags & XFS_FSOP_GEOM_FLAGS_FTYPE ? 1 : 0; finobt_enabled = geo.flags & XFS_FSOP_GEOM_FLAGS_FINOBT ? 1 : 0; + utf8 = geo.flags & XFS_FSOP_GEOM_FLAGS_UTF8 ? 1 : 0; if (nflag) { report_info(geo, datadev, isint, logdev, rtdev, lazycount, dirversion, logversion, attrversion, projid32bit, crcs_enabled, ci, - ftype_enabled, finobt_enabled); + ftype_enabled, finobt_enabled, utf8); exit(0); } @@ -289,7 +292,7 @@ main(int argc, char **argv) report_info(geo, datadev, isint, logdev, rtdev, lazycount, dirversion, logversion, attrversion, projid32bit, crcs_enabled, ci, ftype_enabled, - finobt_enabled); + finobt_enabled, utf8); ddsize = xi.dsize; dlsize = ( xi.logBBsize? xi.logBBsize : -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:41:26 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 0F23A7F52 for ; Thu, 18 Sep 2014 15:41:26 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id DFD718F8052; Thu, 18 Sep 2014 13:41:25 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id A47F84266DC; Thu, 18 Sep 2014 15:41:25 -0500 (CDT) Date: Thu, 18 Sep 2014 15:41:25 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 11/13] xfsprogs: add utf8 support to mkfs.xfs Message-ID: <20140918204125.GY4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918203114.GN4482@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Mark Tinguely Set the utf-8 feature bit. Signed-off-by: Mark Tinguely --- man/man8/mkfs.xfs.8 | 9 ++++++++- mkfs/xfs_mkfs.c | 27 ++++++++++++++++++++++----- mkfs/xfs_mkfs.h | 3 ++- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/man/man8/mkfs.xfs.8 b/man/man8/mkfs.xfs.8 index ad9ff3d..aa43cf5 100644 --- a/man/man8/mkfs.xfs.8 +++ b/man/man8/mkfs.xfs.8 @@ -558,7 +558,7 @@ any power of 2 size from the filesystem block size up to 65536. .IP The .B version=ci -option enables ASCII only case-insensitive filename lookup and version +option enables ASCII or UTF-8 case-insensitive filename lookup and version 2 directories. Filenames are case-preserving, that is, the names are stored in directories using the case they were created with. .IP @@ -582,6 +582,13 @@ When CRCs are enabled via the ftype functionality is always enabled. This feature can not be turned off for such filesystem configurations. .IP +.TP +.BI utf8[= value ] +This is used to enable the UTF-8 character set support. The +.I value +is either 0 or 1, with 1 signifying that UTF-8 character support is to be +enabled. If the value is omitted, 1 is assumed. +.IP .RE .TP .BI \-p " protofile" diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index c85258a..1829e51 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -149,6 +149,8 @@ char *nopts[] = { "version", #define N_FTYPE 3 "ftype", +#define N_UTF8 4 + "utf8", NULL, }; @@ -958,6 +960,7 @@ main( int nsflag; int nvflag; int nci; + int utf8; int Nflag; int discard = 1; char *p; @@ -1004,6 +1007,7 @@ main( logagno = logblocks = rtblocks = rtextblocks = 0; Nflag = nlflag = nsflag = nvflag = nci = 0; nftype = dirftype = 0; /* inode type information in the dir */ + utf8 = 0; /* utf-8 support */ dirblocklog = dirblocksize = 0; dirversion = XFS_DFL_DIR_VERSION; qflag = 0; @@ -1565,7 +1569,8 @@ _("cannot specify both crc and ftype\n")); if (nvflag) respec('n', nopts, N_VERSION); if (!strcasecmp(value, "ci")) { - nci = 1; /* ASCII CI mode */ + /* ASCII or UTF-8 CI mode */ + nci = 1; } else { dirversion = atoi(value); if (dirversion != 2) @@ -1587,6 +1592,14 @@ _("cannot specify both crc and ftype\n")); } nftype = 1; break; + case N_UTF8: + if (!value || *value == '\0') + value = "1"; + c = atoi(value); + if (c < 0 || c > 1) + illegal(value, "n utf8"); + utf8 = c; + break; default: unknown('n', value); } @@ -2460,7 +2473,8 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), */ sbp->sb_features2 = XFS_SB_VERSION2_MKFS(crcs_enabled, lazy_sb_counters, attrversion == 2, !projid16bit, 0, - (!crcs_enabled && dirftype)); + (!crcs_enabled && dirftype), + (!crcs_enabled && utf8)); sbp->sb_versionnum = XFS_SB_VERSION_MKFS(crcs_enabled, iaflag, dsunit != 0, logversion == 2, attrversion == 1, @@ -2534,6 +2548,9 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), if (crcs_enabled) { sbp->sb_features_incompat = XFS_SB_FEAT_INCOMPAT_FTYPE; dirftype = 1; + /* turn on the utf-8 support */ + if (utf8) + sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_UTF8; } if (!qflag || Nflag) { @@ -2543,7 +2560,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), " =%-22s crc=%-8u finobt=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" - "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" + "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d utf8=%d\n" "log =%-22s bsize=%-6d blocks=%lld, version=%d\n" " =%-22s sectsz=%-5u sunit=%d blks, lazy-count=%d\n" "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"), @@ -2552,7 +2569,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), "", crcs_enabled, finobt, "", blocksize, (long long)dblocks, imaxpct, "", dsunit, dswidth, - dirversion, dirblocksize, nci, dirftype, + dirversion, dirblocksize, nci, dirftype, utf8, logfile, 1 << blocklog, (long long)logblocks, logversion, "", lsectorsize, lsunit, lazy_sb_counters, rtfile, rtextblocks << blocklog, @@ -3171,7 +3188,7 @@ usage( void ) sunit=value|su=num,sectlog=n|sectsize=num,\n\ lazy-count=0|1]\n\ /* label */ [-L label (maximum 12 characters)]\n\ -/* naming */ [-n log=n|size=num,version=2|ci,ftype=0|1]\n\ +/* naming */ [-n log=n|size=num,version=2|ci,ftype=0|1,utf8=0|1]\n\ /* no-op info only */ [-N]\n\ /* prototype file */ [-p fname]\n\ /* quiet */ [-q]\n\ diff --git a/mkfs/xfs_mkfs.h b/mkfs/xfs_mkfs.h index 9df5f37..f40b284 100644 --- a/mkfs/xfs_mkfs.h +++ b/mkfs/xfs_mkfs.h @@ -37,13 +37,14 @@ 0 ) : XFS_SB_VERSION_1 ) #define XFS_SB_VERSION2_MKFS(crc, lazycount, attr2, projid32bit, parent, \ - ftype) (\ + ftype, utf8) (\ ((lazycount) ? XFS_SB_VERSION2_LAZYSBCOUNTBIT : 0) | \ ((attr2) ? XFS_SB_VERSION2_ATTR2BIT : 0) | \ ((projid32bit) ? XFS_SB_VERSION2_PROJID32BIT : 0) | \ ((parent) ? XFS_SB_VERSION2_PARENTBIT : 0) | \ ((crc) ? XFS_SB_VERSION2_CRCBIT : 0) | \ ((ftype) ? XFS_SB_VERSION2_FTYPE : 0) | \ + ((utf8) ? XFS_SB_VERSION2_UTF8BIT : 0) | \ 0 ) #define XFS_DFL_BLOCKSIZE_LOG 12 /* 4096 byte blocks */ -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:42:07 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD, T_FILL_THIS_FORM_SHORT autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1545E7F50 for ; Thu, 18 Sep 2014 15:42:07 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id 89A07AC009; Thu, 18 Sep 2014 13:42:06 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 4740E4266DC; Thu, 18 Sep 2014 15:42:06 -0500 (CDT) Date: Thu, 18 Sep 2014 15:42:06 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 12/13] xfsprogs: add utf8 support to xfs_repair Message-ID: <20140918204206.GZ4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918203114.GN4482@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Mark Tinguely Fix the duplicate filename detection to use the utf-8 normalization routines. Signed-off-by: Mark Tinguely --- repair/phase6.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/repair/phase6.c b/repair/phase6.c index f374fd0..eb3ea35 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -176,13 +176,15 @@ dir_hash_add( unsigned char *name, __uint8_t ftype) { - xfs_dahash_t hash = 0; int byaddr; int byhash = 0; dir_hash_ent_t *p; int dup; short junk; struct xfs_name xname; + xfs_da_args_t args; + + memset(&args, 0, sizeof(xfs_da_args_t)); ASSERT(!hashtab->names_duped); @@ -195,19 +197,30 @@ dir_hash_add( dup = 0; if (!junk) { - hash = mp->m_dirnameops->hashname(name, namelen); - byhash = DIR_HASH_FUNC(hashtab, hash); + int error; + + args.name = name; + args.namelen = namelen; + args.inumber = inum; + args.whichfork = XFS_DATA_FORK; + + error = mp->m_dirnameops->normhash(&args); + if (error) + do_error(_("normalize has failed %d)\n"), error); + + byhash = DIR_HASH_FUNC(hashtab, args.hashval); /* * search hash bucket for existing name. */ for (p = hashtab->byhash[byhash]; p; p = p->nextbyhash) { - if (p->hashval == hash && p->name.len == namelen) { - if (memcmp(p->name.name, name, namelen) == 0) { - dup = 1; - junk = 1; - break; - } + if (p->hashval == args.hashval && + mp->m_dirnameops->compname(&args, p->name.name, + p->name.len) != + XFS_CMP_DIFFERENT) { + dup = 1; + junk = 1; + break; } } } @@ -226,7 +239,7 @@ dir_hash_add( hashtab->last = p; if (!(p->junkit = junk)) { - p->hashval = hash; + p->hashval = args.hashval; p->nextbyhash = hashtab->byhash[byhash]; hashtab->byhash[byhash] = p; } @@ -235,6 +248,8 @@ dir_hash_add( p->seen = 0; p->name = xname; + if (args.norm) + kmem_free((void *) args.norm); return !dup; } -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 15:43:03 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 15FF37F50 for ; Thu, 18 Sep 2014 15:43:03 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7EE64AC00C; Thu, 18 Sep 2014 13:43:02 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 25CC44266DC; Thu, 18 Sep 2014 15:43:02 -0500 (CDT) Date: Thu, 18 Sep 2014 15:43:02 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 13/13] xfsprogs: add a preliminary test for utf8 support Message-ID: <20140918204302.GA4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918203114.GN4482@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Ben Myers Here's a preliminary test for utf8 support in xfs. It is based on code that also does some testing in the trie generator. Here too we are using the NormalizationTest.txt file from the unicode distribution. We check that the normalization in libxfs is working and then run checks on a filesystem. Note that there are some 'blacklisted' unichars which normalize to reserved characters. FIXME: For convenience of build this patch is against xfsprogs access to libxfs. Handling of ignorables and case fold is also not implemented here. --- Makefile | 2 +- chkutf8data/Makefile | 21 +++ chkutf8data/chkutf8data.c | 430 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 452 insertions(+), 1 deletion(-) create mode 100644 chkutf8data/Makefile create mode 100644 chkutf8data/chkutf8data.c diff --git a/Makefile b/Makefile index c442da6..d4c0a23 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ endif LIB_SUBDIRS = support libxfs libxlog libxcmd libhandle libdisk TOOL_SUBDIRS = copy db estimate fsck fsr growfs io logprint mkfs quota \ - mdrestore repair rtcp m4 man doc po debian + mdrestore repair rtcp m4 man doc po debian chkutf8data SUBDIRS = include $(LIB_SUBDIRS) $(TOOL_SUBDIRS) diff --git a/chkutf8data/Makefile b/chkutf8data/Makefile new file mode 100644 index 0000000..6ce5706 --- /dev/null +++ b/chkutf8data/Makefile @@ -0,0 +1,21 @@ +# +# Copyright (c) 2014 SGI. All Rights Reserved. +# + +TOPDIR = .. +include $(TOPDIR)/include/builddefs + +LTCOMMAND = chkutf8data +CFILES = chkutf8data.c + +LLDLIBS = $(LIBXFS) +LTDEPENDENCIES = $(LIBXFS) +LLDFLAGS = -static + +default: depend $(LTCOMMAND) + +include $(BUILDRULES) + +install: default + +-include .ltdep diff --git a/chkutf8data/chkutf8data.c b/chkutf8data/chkutf8data.c new file mode 100644 index 0000000..487cf1e --- /dev/null +++ b/chkutf8data/chkutf8data.c @@ -0,0 +1,430 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "utf8norm.h" + +#define FOLD_NAME "CaseFolding.txt" +#define TEST_NAME "NormalizationTest.txt" + +const char *fold_name = FOLD_NAME; +const char *test_name = TEST_NAME; + +/* An arbitrary line size limit on input lines. */ + +#define LINESIZE 1024 +char line[LINESIZE]; +char buf0[LINESIZE]; +char buf1[LINESIZE]; +char buf2[LINESIZE]; +char buf3[LINESIZE]; +char buf4[LINESIZE]; +char buf5[LINESIZE]; + +const char *mtpt; +int verbose = 0; + +/* ------------------------------------------------------------------ */ + +static void +help(void) +{ + printf("The input files:\n"); + printf("\t-f %s\n", FOLD_NAME); + printf("\t-t %s\n", TEST_NAME); + printf("\n\n"); + printf("\t-m mtpt\n"); + printf("\t-v (verbose)\n"); + printf("\t-h (help)\n"); + printf("\n"); +} + +static void +usage(void) +{ + help(); + exit(1); +} + +static void +open_fail(const char *name, int error) +{ + printf("Error %d opening %s: %s\n", error, name, strerror(error)); + exit(1); +} + +static void +file_fail(const char *filename) +{ + printf("Error parsing %s\n", filename); + exit(1); +} + +/* ------------------------------------------------------------------ */ + +/* + * UTF8 valid ranges. + * + * The UTF-8 encoding spreads the bits of a 32bit word over several + * bytes. This table gives the ranges that can be held and how they'd + * be represented. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000000 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000000 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * There is an additional requirement on UTF-8, in that only the + * shortest representation of a 32bit value is to be used. A decoder + * must not decode sequences that do not satisfy this requirement. + * Thus the allowed ranges have a lower bound. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000080 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000800 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00010000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00200000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x04000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Actual unicode characters are limited to the range 0x0 - 0x10FFFF, + * 17 planes of 65536 values. This limits the sequences actually seen + * even more, to just the following. + * + * 0 - 0x7f: 0 0x7f + * 0x80 - 0x7ff: 0xc2 0x80 0xdf 0xbf + * 0x800 - 0xffff: 0xe0 0xa0 0x80 0xef 0xbf 0xbf + * 0x10000 - 0x10ffff: 0xf0 0x90 0x80 0x80 0xf4 0x8f 0xbf 0xbf + * + * Even within those ranges not all values are allowed: the surrogates + * 0xd800 - 0xdfff should never be seen. + * + * Note that the longest sequence seen with valid usage is 4 bytes, + * the same a single UTF-32 character. This makes the UTF-8 + * representation of Unicode strictly smaller than UTF-32. + * + * The shortest sequence requirement was introduced by: + * Corrigendum #1: UTF-8 Shortest Form + * It can be found here: + * http://www.unicode.org/versions/corrigendum1.html + * + */ + +#define UTF8_2_BITS 0xC0 +#define UTF8_3_BITS 0xE0 +#define UTF8_4_BITS 0xF0 +#define UTF8_N_BITS 0x80 +#define UTF8_2_MASK 0xE0 +#define UTF8_3_MASK 0xF0 +#define UTF8_4_MASK 0xF8 +#define UTF8_N_MASK 0xC0 +#define UTF8_V_MASK 0x3F +#define UTF8_V_SHIFT 6 + +static int +utf8key(unsigned int key, char keyval[]) +{ + int keylen; + + if (key < 0x80) { + keyval[0] = key; + keylen = 1; + } else if (key < 0x800) { + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_2_BITS; + keylen = 2; + } else if (key < 0x10000) { + keyval[2] = key & UTF8_V_MASK; + keyval[2] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_3_BITS; + keylen = 3; + } else if (key < 0x110000) { + keyval[3] = key & UTF8_V_MASK; + keyval[3] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[2] = key & UTF8_V_MASK; + keyval[2] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_4_BITS; + keylen = 4; + } else { + printf("%#x: illegal key\n", key); + keylen = 0; + } + return keylen; +} + +static int +normalize_line(utf8data_t tree, char *s, char *t) +{ + struct utf8cursor u8c; + + if (utf8cursor(&u8c, tree, s)) { + printf("%s return utf8cursor failed\n", __func__); + return -1; + } + + while ((*t = utf8byte(&u8c)) > 0) + t++; + + if (*t < 0) { + printf("%s return error %d\r", __func__, *t); + return -1; + } + if (*t != 0) { + printf("%s return t not 0\n", __func__); + return -1; + } + + return 0; +} + +static void +test_key(char *source, + char *NFC, + char *NFD, + char *NFKC, + char *NFKD) +{ + int fd; + int error; + + if (verbose) + printf("Testing %s -> %s\n", source, NFKD); + + error = chdir(mtpt); /* XXX hardcoded mount point */ + if (error) { + perror(mtpt); + exit(-1); + } + + /* the initial create should succeed */ + if (verbose) + printf("Initial create %s... ", source); + fd = open(source, O_CREAT|O_EXCL, 0); + if (fd < 0) { + printf("Failed to create %s XXX\n", source); + perror(source); + close(fd); + exit(-1); + } + close(fd); + if (verbose) + printf("Success\n"); + + /* a second create should fail */ + if (verbose) + printf("Second create %s (should return EEXIST)... ", NFKD); + fd = open(NFKD, O_CREAT|O_EXCL, 0); + if (fd >= 1) { + printf("Test Failed. Was able to create %s XXX\n", NFKD); + perror(NFKD); + close(fd); + exit(-1); + } + close(fd); + if (verbose) + printf("EEXIST\n"); + + error = unlink(NFKD); + if (error) { + printf("Unlink failed\n"); + perror(NFKD); + exit(-1); + } +} + +int +blacklisted(unsigned int unichar) +{ + /* these unichars normalize to characters we don't allow */ + unsigned int list[] = { 0x2024 /* . */, + 0x2025 /* .. */, + 0x2100 /* a/c */, + 0x2101 /* a/s */, + 0x2105 /* c/o */, + 0x2106 /* c/u */, + 0xFE30 /* .. */, + 0xFE52 /* . */, + 0xFF0E /* . */, + 0xFF0F /* / */}; + int i; + + for (i=0; i < (sizeof(list) / sizeof(unichar)); i++) { + if (list[i] == unichar) + return 1; + } + return 0; +} + +static void +normalization_test(void) +{ + FILE *file; + unsigned int unichar; + char *s; + char *t; + int ret; + int tests = 0; + int failures = 0; + char source[LINESIZE]; + char NFKD[LINESIZE]; + int skip; + utf8data_t nfkdi = utf8nfkdi(utf8version); + + printf("Parsing %s\n", test_name); + /* Step one, read data from file. */ + file = fopen(test_name, "r"); + if (!file) + open_fail(test_name, errno); + + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%[^;];%*[^;];%*[^;];%*[^;];%[^;];", + source, NFKD); + //NFC, NFD, NFKC, NFKD); + if (ret != 2 || *line == '#') + continue; + + s = source; + t = buf2; + skip = 0; + while (*s) { + unichar = strtoul(s, &s, 16); + if (blacklisted(unichar)) + skip++; + t += utf8key(unichar, t); + } + *t = '\0'; + + if (skip) + continue; + + s = NFKD; + t = buf3; + while (*s) { + unichar = strtoul(s, &s, 16); + t += utf8key(unichar, t); + } + *t = '\0'; + + /* normalize source */ + if (normalize_line(nfkdi, buf2, buf4) < 0) { + printf("normalize_line for unichar %s Failed\n", buf0); + exit(1); + } + if (verbose) + printf("(%s) %s normalized to %s... ", + source, buf2, buf4); + + /* does it match NFKD? */ + tests++; + if (memcmp(buf4, buf3, strlen(buf3))) { + if (verbose) + printf("Fail!\n"); + failures++; + } else { + if (verbose) + printf("Correct!\n"); + } + + /* normalize NFKD */ + if (normalize_line(nfkdi, buf3, buf5) < 0) { + printf("normalize_line for unichar %s Failed\n", + buf3); + exit(1); + } + if (verbose) + printf("(%s) %s normalized to %s... ", + NFKD, buf3, buf5); + + /* does it normalize to itself? */ + tests++; + if (memcmp(buf5, buf3, strlen(buf3))) { + if (verbose) + printf("Fail!\n"); + failures++; + } else { + if (verbose) + printf("Correct!\n"); + } + + /* XXX ignorables need to be taken into account? */ + test_key(buf2, NULL, NULL, NULL, buf3); + } + fclose(file); + printf("Ran %d tests with %d failures\n", tests, failures); + if (failures) + file_fail(test_name); +} + +int +main(int argc, char *argv[]) +{ + int opt; + + while ((opt = getopt(argc, argv, "f:t:m:vh")) != -1) { + switch (opt) { + case 'f': + fold_name = optarg; + break; + case 't': + test_name = optarg; + break; + case 'm': + mtpt = optarg; + break; + case 'v': + verbose++; + break; + case 'h': + help(); + exit(0); + default: + usage(); + } + } + + if (!test_name || !mtpt) { + usage(); + exit(-1); + } + + normalization_test(); + + return 0; +} -- 1.7.12.4 From bpm@sgi.com Thu Sep 18 16:10:13 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id D01E57F37 for ; Thu, 18 Sep 2014 16:10:13 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay2.corp.sgi.com (Postfix) with ESMTP id B5BC3304032; Thu, 18 Sep 2014 14:10:10 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 716494266DC; Thu, 18 Sep 2014 16:10:10 -0500 (CDT) Date: Thu, 18 Sep 2014 16:10:10 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140918211010.GB4482@sgi.com> References: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918195650.GI19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) Hi, On Thu, Sep 18, 2014 at 02:56:50PM -0500, Ben Myers wrote: > I'm posting this RFC for Unicode support in XFS on Olaf's behalf, as he > is busy with other projects. Patch 7 of each series is the trie generator and utf8 normalization module. Either it's just a little slow or it's over the message size limit on vger at a little over 100k. In case it's the latter I've placed them here: ftp://oss.sgi.com/projects/xfs/tmp/18-Sep-14/0007-xfs-add-trie-generator-and-supporting-code-for-UTF-8.patch and ftp://oss.sgi.com/projects/xfs/tmp/18-Sep-14/0007-libxfs-add-trie-generator-and-supporting-code-for-UT.patch I'll give it a while and then see about splitting up the patch. Thanks, Ben From zab@zabbo.net Thu Sep 18 16:24:25 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 5A4CD7F37 for ; Thu, 18 Sep 2014 16:24:25 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id DDE7DAC002 for ; Thu, 18 Sep 2014 14:24:21 -0700 (PDT) X-ASG-Debug-ID: 1411075458-04cb6c50e718f40001-NocioJ Received: from tetsuo.zabbo.net (tetsuo.zabbo.net [50.193.208.193]) by cuda.sgi.com with ESMTP id kIrimkCfq4zbIgrB for ; Thu, 18 Sep 2014 14:24:18 -0700 (PDT) X-Barracuda-Envelope-From: zab@zabbo.net X-Barracuda-Apparent-Source-IP: 50.193.208.193 Received: from localhost (lenny.home.zabbo.net [192.168.242.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by tetsuo.zabbo.net (Postfix) with ESMTPSA id B62CA7200553; Thu, 18 Sep 2014 14:24:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zabbo.net; s=default; t=1411075456; bh=CCRPnWd9MO5Q0S4GscKCiDETDBNbG4i4h08GG99jngg=; h=Date:From:To:Cc:Subject:References:In-Reply-To; b=fWUyCDDFeR0BpREgGF7rz6AMRiD9LUsbKe7kuRnnstjVi9/2K45cKqCdzLwt8CFSm NUrWtQP0tPrz0ruhCw9D7eCloUByfdk+WqacjTG23aphBEKHRUSyhjn7rRJgkl/TTN mQaX4HzfomwwQBR5CpyIUo4R/R0ac0eo7A4BDKfA= Date: Thu, 18 Sep 2014 14:24:17 -0700 From: Zach Brown To: Ben Myers Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140918212417.GF16677@lenny.home.zabbo.net> X-ASG-Orig-Subj: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <20140918211010.GB4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918211010.GB4482@sgi.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: tetsuo.zabbo.net[50.193.208.193] X-Barracuda-Start-Time: 1411075458 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9628 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Thu, Sep 18, 2014 at 04:10:10PM -0500, Ben Myers wrote: > Hi, > > On Thu, Sep 18, 2014 at 02:56:50PM -0500, Ben Myers wrote: > > I'm posting this RFC for Unicode support in XFS on Olaf's behalf, as he > > is busy with other projects. > > Patch 7 of each series is the trie generator and utf8 normalization > module. Either it's just a little slow or it's over the message size > limit on vger at a little over 100k. Probably, yeah: http://vger.kernel.org/majordomo-info.html " * Message size exceeding 100 000 characters causes blocking. " - z From bpm@sgi.com Thu Sep 18 17:23:52 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 7E5ED7F37 for ; Thu, 18 Sep 2014 17:23:52 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id BA1FEAC002; Thu, 18 Sep 2014 15:23:48 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 6CC574266DC; Thu, 18 Sep 2014 17:23:48 -0500 (CDT) Date: Thu, 18 Sep 2014 17:23:48 -0500 From: Ben Myers To: Zach Brown Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140918222348.GC4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918211010.GB4482@sgi.com> <20140918212417.GF16677@lenny.home.zabbo.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918212417.GF16677@lenny.home.zabbo.net> User-Agent: Mutt/1.5.20 (2009-06-14) On Thu, Sep 18, 2014 at 02:24:17PM -0700, Zach Brown wrote: > On Thu, Sep 18, 2014 at 04:10:10PM -0500, Ben Myers wrote: > > On Thu, Sep 18, 2014 at 02:56:50PM -0500, Ben Myers wrote: > > > I'm posting this RFC for Unicode support in XFS on Olaf's behalf, as he > > > is busy with other projects. > > > > Patch 7 of each series is the trie generator and utf8 normalization > > module. Either it's just a little slow or it's over the message size > > limit on vger at a little over 100k. > > Probably, yeah: > > http://vger.kernel.org/majordomo-info.html > > " > * Message size exceeding 100 000 characters causes blocking. > " D'oh! I'll split it up. Thanks, Ben From mellow@szmellow.com Thu Sep 18 21:40:29 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.0 required=5.0 tests=DEAR_SOMETHING, HTML_FONT_FACE_BAD,HTML_MESSAGE autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 0EC427F37 for ; Thu, 18 Sep 2014 21:40:29 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 836DCAC003 for ; Thu, 18 Sep 2014 19:40:25 -0700 (PDT) X-ASG-Debug-ID: 1411094420-04cbb0730322650001-NocioJ Received: from smtpbg64.qq.com (smtpbg64.qq.com [103.7.28.238]) by cuda.sgi.com with ESMTP id gtneaNA8afVBKhpD (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 18 Sep 2014 19:40:22 -0700 (PDT) X-Barracuda-Envelope-From: mellow@szmellow.com X-Barracuda-Apparent-Source-IP: 103.7.28.238 X-QQ-GoodBg: 0 X-QQ-SSF: 0060000000000020 X-QQ-BUSINESS-ORIGIN: 2 X-Originating-IP: 183.12.114.67 X-QQ-STYLE: X-QQ-mid: bizmail66t1411094254t6839131 From: "=?utf-8?B?TWVsbG93IFRlY2hub2xvZ3k=?=" To: Subject: Re: Gsm module/gprs modem/ gsm modem/m2m modem Mime-Version: 1.0 X-ASG-Orig-Subj: Re: Gsm module/gprs modem/ gsm modem/m2m modem Content-Type: multipart/alternative; boundary="----=_NextPart_541B96EE_0A0B5BA8_5C1C39D2" Content-Transfer-Encoding: 8Bit Date: Fri, 19 Sep 2014 10:37:34 +0800 X-Priority: 3 Message-ID: X-QQ-MIME: TCMime 1.0 by Tencent X-Mailer: QQMail 2.x X-QQ-Mailer: QQMail 2.x X-QQ-SENDSIZE: 520 X-Barracuda-Connect: smtpbg64.qq.com[103.7.28.238] X-Barracuda-Start-Time: 1411094421 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-BRTS-Evidence: szmellow.com X-Barracuda-Spam-Score: 1.67 X-Barracuda-Spam-Status: No, SCORE=1.67 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=FROM_EXCESS_BASE64, FROM_EXCESS_BASE64_2, HTML_FONT_FACE_BAD, HTML_MESSAGE, TO_CC_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9635 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 0.61 HTML_FONT_FACE_BAD BODY: HTML font face is not a word 0.01 FROM_EXCESS_BASE64 From: base64 encoded unnecessarily 0.00 TO_CC_NONE No To: or Cc: header 1.05 FROM_EXCESS_BASE64_2 From: base64 encoded unnecessarily This is a multi-part message in MIME format. ------=_NextPart_541B96EE_0A0B5BA8_5C1C39D2 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 RGVhciBTaXIsDQogIA0KIFdlIGFyZSAgYSBoaWdoLXRlY2ggZW50ZXJwcmlzZSB3aGljaCBz cGVjaWFsaXplcyBpbiB0aGUgZGVzaWduLCByZXNlYXJjaCAmICBkZXZlbG9wbWVudCwgbWFu dWZhY3R1cmUgYW5kIHNhbGVzIG9mIHdpcmVsZXNzIGNvbW11bmljYXRpb24gcHJvZHVjdHMs IHN1Y2ggYXMgIE0yTSBHUFJTIE1vZGVtLCBHU00gTW9kZW0sIEdTTSBNb2R1bGUsIEdQUlMg TW9kZW0sU01TIE1vZGVtLiANCiANCiANCg0KIA0KSWYgIHlvdSBhcmUgaW50ZXJlc3RlZCBp biwgSSAnbGwgc2VuZCB5b3Ugb3VyIGNhdGFsb2d1ZSwgeW91IGFsc28gY2FuIHZpc2l0IG91 ciAgd2Vic2l0ZSwgdGhhbmtzIGZvciB5b3VyIHZhbHVhYmxlIHRpbWUuDQoNCiANCiANCiAN CiANCkJlc3QgUmVnYXJkcyAgJiBLZWxseQ0KDQogDQoNCiANCiANClNoZW56aGVuIE1lbGxv dyAgVGVjaG5vbG9neSBDby4sIExpbWl0ZWQgDQogDQpUZWw6ICArODYtNzU1LTg2NTA3MDU5 IA0KIA0KTW9iOiAgKzg2LTEzNjQwOTI3MDI2DQogDQpTa3lwZSBJRDogIG1lbGxvd3NhbGVz IA0KIA0KRS1tYWlsOiAgc2FsZXNAc3ptZWxsb3cuY29tDQogDQpXZWJzaXRlOiB3d3cuc3pt ZWxsb3cuY29t ------=_NextPart_541B96EE_0A0B5BA8_5C1C39D2 Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: base64 PGRpdj48ZGl2Pjxmb250IGNvbG9yPSIjMDAwMDgwIiBzaXplPSIyIiBmYWNlPSJWZXJkYW5h Ij4NCjxkaXY+PGZvbnQgY29sb3I9IiMwMDAwODAiIHNpemU9IjIiIGZhY2U9IlZlcmRhbmEi Pjxmb250IGNvbG9yPSIjMDAwMDAwIiBzaXplPSIzIiBmYWNlPSJAQXJpYWwgVW5pY29kZSBN UyI+RGVhciBTaXIsPC9mb250PjwvZm9udD48L2Rpdj4NCjxkaXY+Jm5ic3A7PC9kaXY+DQo8 ZGl2PjxzcGFuIGxhbmc9IkVOLVVTIj48Zm9udCBjb2xvcj0iIzAwMDAwMCIgc2l6ZT0iMyIg ZmFjZT0iQEFyaWFsIFVuaWNvZGUgTVMiPldlIGFyZSANCmEgaGlnaC10ZWNoIGVudGVycHJp c2Ugd2hpY2ggc3BlY2lhbGl6ZXMgaW4gdGhlIGRlc2lnbiwgcmVzZWFyY2ggJmFtcDsgDQpk ZXZlbG9wbWVudCwgbWFudWZhY3R1cmUgYW5kIHNhbGVzIG9mIHdpcmVsZXNzIGNvbW11bmlj YXRpb24gcHJvZHVjdHMsIHN1Y2ggYXMgDQo8c3Ryb25nPk08dT48L3U+PHU+PC91PjJNPHU+ PC91PiBHUFJTIE1vZGVtLCBHU00gTW9kZW0sIEdTTSBNb2R1bGUsIEdQUlMgTW9kZW0sU01T IE1vZGVtPC9zdHJvbmc+LiA8L2ZvbnQ+PC9zcGFuPjwvZGl2PjxkaXY+PHNwYW4gbGFuZz0i RU4tVVMiPjxmb250IGNvbG9yPSIjMDAwMDAwIiBzaXplPSIzIiBmYWNlPSJAQXJpYWwgVW5p Y29kZSBNUyI+PC9mb250Pjwvc3Bhbj4mbmJzcDs8L2Rpdj4NCjxwIHN0eWxlPSJtYXJnaW46 IDBjbSAwY20gMHB0OyIgY2xhc3M9Ik1zb05vcm1hbCI+PGZvbnQgY29sb3I9IiMwMDAwMDAi IHNpemU9IjMiIGZhY2U9IuWui+S9kyI+PC9mb250PjwvcD4NCjxwIHN0eWxlPSJtYXJnaW46 IDBjbSAwY20gMHB0OyB0ZXh0LWFsaWduOiBsZWZ0OyBtc28tcGFnaW5hdGlvbjogd2lkb3ct b3JwaGFuOyIgY2xhc3M9Ik1zb05vcm1hbCIgYWxpZ249ImxlZnQiPjxzcGFuIHN0eWxlPSdj b2xvcjogYmxhY2s7IGZvbnQtZmFtaWx5OiAiQEFyaWFsIFVuaWNvZGUgTVMiLCAic2Fucy1z ZXJpZiI7IGZvbnQtc2l6ZTogMTJwdDsgbXNvLWZvbnQta2VybmluZzogMHB0OycgbGFuZz0i RU4tVVMiPklmIA0KeW91IGFyZSBpbnRlcmVzdGVkIGluLCBJICdsbCBzZW5kIHlvdSBvdXIg Y2F0YWxvZ3VlLCB5b3UgYWxzbyBjYW4gdmlzaXQgb3VyIA0Kd2Vic2l0ZSwgdGhhbmtzIGZv ciB5b3VyIHZhbHVhYmxlIHRpbWUuPC9zcGFuPjwvcD48cCBzdHlsZT0ibWFyZ2luOiAwY20g MGNtIDBwdDsgdGV4dC1hbGlnbjogbGVmdDsgbXNvLXBhZ2luYXRpb246IHdpZG93LW9ycGhh bjsiIGNsYXNzPSJNc29Ob3JtYWwiIGFsaWduPSJsZWZ0Ij48c3BhbiBzdHlsZT0nY29sb3I6 IGJsYWNrOyBmb250LWZhbWlseTogIkBBcmlhbCBVbmljb2RlIE1TIiwgInNhbnMtc2VyaWYi OyBmb250LXNpemU6IDEycHQ7IG1zby1mb250LWtlcm5pbmc6IDBwdDsnIGxhbmc9IkVOLVVT Ij48L3NwYW4+Jm5ic3A7PC9wPg0KPHAgc3R5bGU9Im1hcmdpbjogMGNtIDBjbSAwcHQ7IGxp bmUtaGVpZ2h0OiAxNi44cHQ7IiBjbGFzcz0iTXNvTm9ybWFsIj48Zm9udCBjb2xvcj0iIzAw MDAwMCI+PGZvbnQgc2l6ZT0iMyI+PGZvbnQgZmFjZT0iQEFyaWFsIFVuaWNvZGUgTVMiPjxz cGFuIGxhbmc9IkVOLVVTIj48L3NwYW4+PC9mb250PjwvZm9udD48L2ZvbnQ+Jm5ic3A7PC9w Pg0KPHAgc3R5bGU9Im1hcmdpbjogMGNtIDBjbSAwcHQ7IGxpbmUtaGVpZ2h0OiAxNi44cHQ7 IiBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBsYW5nPSJFTi1VUyI+PGZvbnQgY29sb3I9IiMw MDAwMDAiIHNpemU9IjMiIGZhY2U9IkBBcmlhbCBVbmljb2RlIE1TIj5CZXN0IFJlZ2FyZHMg DQomYW1wOyBLZWxseTwvZm9udD48L3NwYW4+PC9wPjxwIHN0eWxlPSJtYXJnaW46IDBjbSAw Y20gMHB0OyBsaW5lLWhlaWdodDogMTYuOHB0OyIgY2xhc3M9Ik1zb05vcm1hbCI+PHNwYW4g bGFuZz0iRU4tVVMiPjwvc3Bhbj4mbmJzcDs8L3A+PHAgc3R5bGU9Im1hcmdpbjogMGNtIDBj bSAwcHQ7IGxpbmUtaGVpZ2h0OiAxNi44cHQ7IiBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBs YW5nPSJFTi1VUyI+PC9zcGFuPiZuYnNwOzwvcD4NCjxwIHN0eWxlPSJtYXJnaW46IDBjbSAw Y20gMHB0OyIgY2xhc3M9Ik1zb05vcm1hbCI+PGZvbnQgY29sb3I9IiMwMDAwMDAiPjxmb250 IHNpemU9IjMiPjxmb250IGZhY2U9IkBBcmlhbCBVbmljb2RlIE1TIj48c3BhbiBsYW5nPSJF Ti1VUyI+U2hlbnpoZW4gTWVsbG93IA0KVGVjaG5vbG9neSBDby4sIExpbWl0ZWQgPC9zcGFu PjwvZm9udD48L2ZvbnQ+PC9mb250PjwvcD4NCjxwIHN0eWxlPSJtYXJnaW46IDBjbSAwY20g MHB0OyIgY2xhc3M9Ik1zb05vcm1hbCI+PGZvbnQgY29sb3I9IiMwMDAwMDAiPjxmb250IHNp emU9IjMiPjxmb250IGZhY2U9IkBBcmlhbCBVbmljb2RlIE1TIj48c3BhbiBsYW5nPSJFTi1V UyI+VGVsOiANCis4Ni03NTUtODY1MDcwNTk8L3NwYW4+PHNwYW4gbGFuZz0iRU4tVVMiPiA8 L3NwYW4+PC9mb250PjwvZm9udD48L2ZvbnQ+PC9wPg0KPHAgc3R5bGU9Im1hcmdpbjogMGNt IDBjbSAwcHQ7IiBjbGFzcz0iTXNvTm9ybWFsIj48Zm9udCBjb2xvcj0iIzAwMDAwMCI+PGZv bnQgc2l6ZT0iMyI+PGZvbnQgZmFjZT0iQEFyaWFsIFVuaWNvZGUgTVMiPjxzcGFuIGxhbmc9 IkVOLVVTIj5Nb2I6IA0KKzg2LTEzNjQwOTI3MDI2PC9zcGFuPjwvZm9udD48L2ZvbnQ+PC9m b250PjwvcD48Zm9udCBjb2xvcj0iIzAwMDAwMCI+PC9mb250Pg0KPHAgc3R5bGU9Im1hcmdp bjogMGNtIDBjbSAwcHQ7IiBjbGFzcz0iTXNvTm9ybWFsIj48Zm9udCBzaXplPSIzIj48Zm9u dCBmYWNlPSJAQXJpYWwgVW5pY29kZSBNUyI+PGZvbnQgY29sb3I9IiMwMDAwMDAiPjxzcGFu IGxhbmc9IkVOLVVTIj5Ta3lwZSBJRDogDQptZWxsb3dzYWxlcyA8L3NwYW4+PHNwYW4gbGFu Zz0iRU4tVVMiPjx1PjwvdT48dT48L3U+PC9zcGFuPjwvZm9udD48L2ZvbnQ+PC9mb250Pjwv cD48Zm9udCBjb2xvcj0iIzAwMDAwMCI+PC9mb250Pg0KPHAgc3R5bGU9Im1hcmdpbjogMGNt IDBjbSAwcHQ7IiBjbGFzcz0iTXNvTm9ybWFsIj48Zm9udCBzaXplPSIzIj48Zm9udCBmYWNl PSJAQXJpYWwgVW5pY29kZSBNUyI+PGZvbnQgY29sb3I9IiMwMDAwMDAiPjxzcGFuIGxhbmc9 IkVOLVVTIj5FLW1haWw6IA0KPC9zcGFuPjxzcGFuIGxhbmc9IkVOLVVTIj48YSBocmVmPSJt YWlsdG86c2FsZXNAc3ptZWxsb3cuY29tIiB0YXJnZXQ9Il9ibGFuayI+PGZvbnQgY29sb3I9 IiMwMDAwMDAiPnNhbGVzQHN6bWVsbG93LmNvbTwvZm9udD48L2E+PC9zcGFuPjxzcGFuIGxh bmc9IkVOLVVTIj48dT48L3U+PHU+PC91Pjwvc3Bhbj48L2ZvbnQ+PC9mb250PjwvZm9udD48 L3A+PGZvbnQgY29sb3I9IiMwMDAwMDAiPjwvZm9udD4NCjxwIHN0eWxlPSJtYXJnaW46IDBj bSAwY20gMHB0OyIgY2xhc3M9Ik1zb05vcm1hbCI+PHNwYW4gbGFuZz0iRU4tVVMiPjxmb250 IGNvbG9yPSIjMDAwMDAwIiBzaXplPSIzIiBmYWNlPSJAQXJpYWwgVW5pY29kZSBNUyI+V2Vi c2l0ZTogPC9mb250PjxhIGhyZWY9Imh0dHA6Ly93d3cuc3ptZWxsb3cuY29tLyIgdGFyZ2V0 PSJfYmxhbmsiPjxzdHJvbmc+PGZvbnQgY29sb3I9IiMwMDAwMDAiIHNpemU9IjMiIGZhY2U9 IkBBcmlhbCBVbmljb2RlIE1TIj53d3cuc3ptZWxsb3cuY29tPC9mb250Pjwvc3Ryb25nPjwv YT48L3NwYW4+PHNwYW4gbGFuZz0iRU4tVVMiPjx1PjwvdT48dT48L3U+PC9zcGFuPjwvcD48 cCBzdHlsZT0ibWFyZ2luOiAwY20gMGNtIDBwdDsiIGNsYXNzPSJNc29Ob3JtYWwiPjxzcGFu IGxhbmc9IkVOLVVTIj48L3NwYW4+Jm5ic3A7PC9wPjwvZm9udD48Zm9udD48L2ZvbnQ+PGZv bnQ+PC9mb250PjwvZGl2PjwvZGl2Pg== ------=_NextPart_541B96EE_0A0B5BA8_5C1C39D2-- From guaneryu@gmail.com Fri Sep 19 01:38:01 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 477BC7F3F for ; Fri, 19 Sep 2014 01:38:01 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id B9A34AC002 for ; Thu, 18 Sep 2014 23:37:57 -0700 (PDT) X-ASG-Debug-ID: 1411108672-04cbb073032c720001-NocioJ Received: from mail-pd0-f177.google.com (mail-pd0-f177.google.com [209.85.192.177]) by cuda.sgi.com with ESMTP id SGtn38TxfUp9dbCu (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Thu, 18 Sep 2014 23:37:52 -0700 (PDT) X-Barracuda-Envelope-From: guaneryu@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.192.177 Received: by mail-pd0-f177.google.com with SMTP id y10so1939795pdj.22 for ; Thu, 18 Sep 2014 23:37:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=Ft1dbo18sjKT/yu4sO+QtQjY3u+PIsDSP/DttCoiX6I=; b=SbRYwwRsQcmz3AdjE/hJ00dm+tVCNkdin5CGayBBDft3dYgqeaUrqVwEIa1+VXQXXR HQTCDIM8vGwjgl2Wuf/Hd1exO+DglzxT7IfORcRpQSLXDKE/md5OfvLfyMQ8aIS8vxrj bCUKYY8j1zEwKNI1NUb9rb2t05L2Xj3k+w5WqY++szTuWA/mn6EvkkZofuvj14NWz4vv lyVZVSqgmHE9S+G2H02OzGKrS9hODj8txPWhHwgON3ZysHoF01XzhpSPcCCBWqISskTA 5uMwnmlCk1REPCyh2yxFD4dGxpIlZuLUtH4qA/YTzWXQlCIajlY3Phr/xf5sBw+vZi8j m/OQ== X-Barracuda-BBL-IP: nil X-Received: by 10.68.111.99 with SMTP id ih3mr13125066pbb.124.1411108672192; Thu, 18 Sep 2014 23:37:52 -0700 (PDT) Received: from localhost ([203.114.244.88]) by mx.google.com with ESMTPSA id f1sm855272pdf.43.2014.09.18.23.37.50 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 18 Sep 2014 23:37:51 -0700 (PDT) Date: Fri, 19 Sep 2014 14:37:48 +0800 X-Barracuda-Apparent-Source-IP: 203.114.244.88 From: Eryu Guan To: Liu Bo Cc: xfs@oss.sgi.com, linux-btrfs Subject: Re: [PATCH] xfstests: remove check_scratch_fs in btrfs/012 Message-ID: <20140919063748.GA13950@dhcp-13-216.nay.redhat.com> X-ASG-Orig-Subj: Re: [PATCH] xfstests: remove check_scratch_fs in btrfs/012 References: <1409714759-9805-1-git-send-email-bo.li.liu@oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1409714759-9805-1-git-send-email-bo.li.liu@oracle.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: mail-pd0-f177.google.com[209.85.192.177] X-Barracuda-Start-Time: 1411108672 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9641 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Wed, Sep 03, 2014 at 11:25:59AM +0800, Liu Bo wrote: > From: Liu Bo > > btrfs/012 is a case to verify btrfs-convert feature, it converts an ext4 to > btrfs firstly and do something, then rolls back to ext4. > > So at last we have a ext4 on the scratch device, but setting _require_scratch > will force a btrfsck on a ext4 fs because $FSTYP here is btrfs, and it ends up > with a failure report of _check_btrfs_filesystem. > > Now that we have deliberately check the final ext4 fs in btrfs/012, just do not > set _require_scratch in this case. > > Signed-off-by: Liu Bo > --- > tests/btrfs/012 | 1 - > 1 file changed, 1 deletion(-) > > diff --git a/tests/btrfs/012 b/tests/btrfs/012 > index f7e5da5..12f6462 100755 > --- a/tests/btrfs/012 > +++ b/tests/btrfs/012 > @@ -52,7 +52,6 @@ _cleanup() > # Modify as appropriate. > _supported_fs btrfs > _supported_os Linux > -_require_scratch The test still requires a scratch device, so we cannot simply remove this line. Now we can use _require_scratch_nocheck helper, and it works fine based on my test. Thanks, Eryu > > BTRFS_CONVERT_PROG="`set_prog_path btrfs-convert`" > MKFS_EXT4_PROG="`set_prog_path mkfs.ext4`" > -- > 1.8.1.4 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From prvs=4339409777=jbacik@fb.com Fri Sep 19 10:02:51 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id EFC777F3F for ; Fri, 19 Sep 2014 10:02:50 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8D9B0AC006 for ; Fri, 19 Sep 2014 08:02:47 -0700 (PDT) X-ASG-Debug-ID: 1411138963-04bdf003a13eb70001-NocioJ Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by cuda.sgi.com with ESMTP id Ee9bHBlwGCQUGlhD for ; Fri, 19 Sep 2014 08:02:43 -0700 (PDT) X-Barracuda-Envelope-From: prvs=4339409777=jbacik@fb.com X-Barracuda-Apparent-Source-IP: 67.231.153.30 X-Barracuda-IPDD: Level2 [fb.com/67.231.153.30] Received: from pps.filterd (m0004060 [127.0.0.1]) by mx0b-00082601.pphosted.com (8.14.5/8.14.5) with SMTP id s8JEpOgd021039; Fri, 19 Sep 2014 08:02:41 -0700 X-Barracuda-IPDD: Level2 [fb.com/67.231.153.30] X-Barracuda-IPDD: Level2 [fb.com/67.231.153.30] X-Barracuda-IPDD: Level2 [fb.com/67.231.153.30] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=fb.com; h=message-id : date : from : mime-version : to : cc : subject : references : in-reply-to : content-type : content-transfer-encoding; s=facebook; bh=+GiEpT3TmwYoX5PR8OuC34466MeevyUVg04YR69oOFs=; b=KQRm402J7DDcuw/eYwsnlZVvTfu9WVfLtmT+Kh0+x5nDQPRAuDMbrKZVPOpwKqO663Wo 5nCBSdnAV1xeX+UqLOnYVXeZVAK7AF7Mma0LiWrXv8gf72KhQEdognoqT9zf7xzcBXOX Bx1ojHtTlO5mZxknm95jSSj6N1eDt7Eihuo= Received: from mail.thefacebook.com (mailwest.thefacebook.com [173.252.71.148]) by mx0b-00082601.pphosted.com with ESMTP id 1pg4rpbf7j-1 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=OK); Fri, 19 Sep 2014 08:02:41 -0700 Received: from localhost.localdomain (192.168.16.4) by mail.thefacebook.com (192.168.16.13) with Microsoft SMTP Server (TLS) id 14.3.195.1; Fri, 19 Sep 2014 08:02:39 -0700 Message-ID: <541C458E.3080406@fb.com> Date: Fri, 19 Sep 2014 11:02:38 -0400 From: Josef Bacik User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.0 MIME-Version: 1.0 To: Liu Bo , CC: linux-btrfs Subject: Re: [PATCH] xfstests: remove check_scratch_fs in btrfs/012 References: <1409714759-9805-1-git-send-email-bo.li.liu@oracle.com> X-ASG-Orig-Subj: Re: [PATCH] xfstests: remove check_scratch_fs in btrfs/012 In-Reply-To: <1409714759-9805-1-git-send-email-bo.li.liu@oracle.com> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [192.168.16.4] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.12.52,1.0.28,0.0.0000 definitions=2014-09-19_06:2014-09-19,2014-09-19,1970-01-01 signatures=0 X-Proofpoint-Spam-Details: rule=fb_default_notspam policy=fb_default score=0 kscore.is_bulkscore=1.1335610228258e-09 kscore.compositescore=0 circleOfTrustscore=222.879571347525 compositescore=0.999738115633958 urlsuspect_oldscore=0.999738115633958 suspectscore=0 recipient_domain_to_sender_totalscore=0 phishscore=0 bulkscore=0 kscore.is_spamscore=0 recipient_to_sender_totalscore=0 recipient_domain_to_sender_domain_totalscore=64355 rbsscore=0.999738115633958 spamscore=0 recipient_to_sender_domain_totalscore=0 urlsuspectscore=0.9 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=7.0.1-1402240000 definitions=main-1409190131 X-FB-Internal: deliver X-Barracuda-Connect: mx0b-00082601.pphosted.com[67.231.153.30] X-Barracuda-Start-Time: 1411138963 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On 09/02/2014 11:25 PM, Liu Bo wrote: > From: Liu Bo > > btrfs/012 is a case to verify btrfs-convert feature, it converts an ext4 to > btrfs firstly and do something, then rolls back to ext4. > > So at last we have a ext4 on the scratch device, but setting _require_scratch > will force a btrfsck on a ext4 fs because $FSTYP here is btrfs, and it ends up > with a failure report of _check_btrfs_filesystem. > > Now that we have deliberately check the final ext4 fs in btrfs/012, just do not > set _require_scratch in this case. > > Signed-off-by: Liu Bo I sent a patch for this already, it's on the fs-tests list. Thanks, Josef From bpm@sgi.com Fri Sep 19 11:03:54 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD, T_FILL_THIS_FORM_SHORT autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B7B9D7F4E for ; Fri, 19 Sep 2014 11:03:54 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6B952304043; Fri, 19 Sep 2014 09:03:51 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id AE2484266DC; Fri, 19 Sep 2014 11:03:50 -0500 (CDT) Date: Fri, 19 Sep 2014 11:03:50 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 07a/10] xfs: add trie generator for UTF-8. Message-ID: <20140919160350.GD4482@sgi.com> References: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918195650.GI19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber mkutf8data.c is the source for a program that generates utf8data.h, which contains the trie that utf8norm.c uses. The trie is generated from the Unicode 7.0.0 data files. The format of the utf8data[] table is described in utf8norm.c, which is added in the next patch. Signed-off-by: Olaf Weber --- [v2: the trie is now separated into utf8norm.ko; utf8version is now a function and exported; introduced CONFIG_XFS_UTF8; removed supporting code due to vger size constraint. --bpm] --- fs/xfs/Kconfig | 8 + fs/xfs/Makefile | 2 +- fs/xfs/utf8norm/Makefile | 33 + fs/xfs/utf8norm/mkutf8data.c | 3239 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 3281 insertions(+), 1 deletion(-) create mode 100644 fs/xfs/utf8norm/Makefile create mode 100644 fs/xfs/utf8norm/mkutf8data.c diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig index 5d47b4d..a847857 100644 --- a/fs/xfs/Kconfig +++ b/fs/xfs/Kconfig @@ -95,3 +95,11 @@ config XFS_DEBUG not useful unless you are debugging a particular problem. Say N unless you are an XFS developer, or you play one on TV. + +config XFS_UTF8 + bool "XFS UTF-8 support" + depends on XFS_FS + help + Say Y here to enable utf8 normalization support in XFS. You + will be able to mount and use filesystems created with the + utf8 mkfs.xfs option. diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index d617999..6d000d3 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -21,7 +21,7 @@ ccflags-y += -I$(src)/libxfs ccflags-$(CONFIG_XFS_DEBUG) += -g -obj-$(CONFIG_XFS_FS) += xfs.o +obj-$(CONFIG_XFS_FS) += xfs.o utf8norm/ # this one should be compiled first, as the tracing macros can easily blow up xfs-y += xfs_trace.o diff --git a/fs/xfs/utf8norm/Makefile b/fs/xfs/utf8norm/Makefile new file mode 100644 index 0000000..9b2efa9 --- /dev/null +++ b/fs/xfs/utf8norm/Makefile @@ -0,0 +1,33 @@ +# +# Copyright (c) 2014 SGI. +# All rights reserved. +# +# This program 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. +# +# This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +hostprogs-y := mkutf8data +$(obj)/utf8norm.o: $(obj)/utf8data.h +$(obj)/utf8data.h: $(src)/ucd/*.txt +$(obj)/utf8data.h: $(obj)/mkutf8data FORCE + $(call if_changed,mkutf8data) +quiet_cmd_mkutf8data = MKUTF8DATA $@ + cmd_mkutf8data = $(obj)/mkutf8data \ + -a $(src)/ucd/DerivedAge-7.0.0.txt \ + -c $(src)/ucd/DerivedCombiningClass-7.0.0.txt \ + -p $(src)/ucd/DerivedCoreProperties-7.0.0.txt \ + -d $(src)/ucd/UnicodeData-7.0.0.txt \ + -f $(src)/ucd/CaseFolding-7.0.0.txt \ + -n $(src)/ucd/NormalizationCorrections-7.0.0.txt \ + -t $(src)/ucd/NormalizationTest-7.0.0.txt \ + -o $@ diff --git a/fs/xfs/utf8norm/mkutf8data.c b/fs/xfs/utf8norm/mkutf8data.c new file mode 100644 index 0000000..1d6ec02 --- /dev/null +++ b/fs/xfs/utf8norm/mkutf8data.c @@ -0,0 +1,3239 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Generator for a compact trie for unicode normalization */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Default names of the in- and output files. */ + +#define AGE_NAME "DerivedAge.txt" +#define CCC_NAME "DerivedCombiningClass.txt" +#define PROP_NAME "DerivedCoreProperties.txt" +#define DATA_NAME "UnicodeData.txt" +#define FOLD_NAME "CaseFolding.txt" +#define NORM_NAME "NormalizationCorrections.txt" +#define TEST_NAME "NormalizationTest.txt" +#define UTF8_NAME "utf8data.h" + +const char *age_name = AGE_NAME; +const char *ccc_name = CCC_NAME; +const char *prop_name = PROP_NAME; +const char *data_name = DATA_NAME; +const char *fold_name = FOLD_NAME; +const char *norm_name = NORM_NAME; +const char *test_name = TEST_NAME; +const char *utf8_name = UTF8_NAME; + +int verbose = 0; + +/* An arbitrary line size limit on input lines. */ + +#define LINESIZE 1024 +char line[LINESIZE]; +char buf0[LINESIZE]; +char buf1[LINESIZE]; +char buf2[LINESIZE]; +char buf3[LINESIZE]; + +const char *argv0; + +/* ------------------------------------------------------------------ */ + +/* + * Unicode version numbers consist of three parts: major, minor, and a + * revision. These numbers are packed into an unsigned int to obtain + * a single version number. + * + * To save space in the generated trie, the unicode version is not + * stored directly, instead we calculate a generation number from the + * unicode versions seen in the DerivedAge file, and use that as an + * index into a table of unicode versions. + */ +#define UNICODE_MAJ_SHIFT (16) +#define UNICODE_MIN_SHIFT (8) + +#define UNICODE_MAJ_MAX ((unsigned short)-1) +#define UNICODE_MIN_MAX ((unsigned char)-1) +#define UNICODE_REV_MAX ((unsigned char)-1) + +#define UNICODE_AGE(MAJ,MIN,REV) \ + (((unsigned int)(MAJ) << UNICODE_MAJ_SHIFT) | \ + ((unsigned int)(MIN) << UNICODE_MIN_SHIFT) | \ + ((unsigned int)(REV))) + +unsigned int *ages; +int ages_count; + +unsigned int unicode_maxage; + +static int +age_valid(unsigned int major, unsigned int minor, unsigned int revision) +{ + if (major > UNICODE_MAJ_MAX) + return 0; + if (minor > UNICODE_MIN_MAX) + return 0; + if (revision > UNICODE_REV_MAX) + return 0; + return 1; +} + +/* ------------------------------------------------------------------ */ + +/* + * utf8trie_t + * + * A compact binary tree, used to decode UTF-8 characters. + * + * Internal nodes are one byte for the node itself, and up to three + * bytes for an offset into the tree. The first byte contains the + * following information: + * NEXTBYTE - flag - advance to next byte if set + * BITNUM - 3 bit field - the bit number to tested + * OFFLEN - 2 bit field - number of bytes in the offset + * if offlen == 0 (non-branching node) + * RIGHTPATH - 1 bit field - set if the following node is for the + * right-hand path (tested bit is set) + * TRIENODE - 1 bit field - set if the following node is an internal + * node, otherwise it is a leaf node + * if offlen != 0 (branching node) + * LEFTNODE - 1 bit field - set if the left-hand node is internal + * RIGHTNODE - 1 bit field - set if the right-hand node is internal + * + * Due to the way utf8 works, there cannot be branching nodes with + * NEXTBYTE set, and moreover those nodes always have a righthand + * descendant. + */ +typedef unsigned char utf8trie_t; +#define BITNUM 0x07 +#define NEXTBYTE 0x08 +#define OFFLEN 0x30 +#define OFFLEN_SHIFT 4 +#define RIGHTPATH 0x40 +#define TRIENODE 0x80 +#define RIGHTNODE 0x40 +#define LEFTNODE 0x80 + +/* + * utf8leaf_t + * + * The leaves of the trie are embedded in the trie, and so the same + * underlying datatype, unsigned char. + * + * leaf[0]: The unicode version, stored as a generation number that is + * an index into utf8agetab[]. With this we can filter code + * points based on the unicode version in which they were + * defined. The CCC of a non-defined code point is 0. + * leaf[1]: Canonical Combining Class. During normalization, we need + * to do a stable sort into ascending order of all characters + * with a non-zero CCC that occur between two characters with + * a CCC of 0, or at the begin or end of a string. + * The unicode standard guarantees that all CCC values are + * between 0 and 254 inclusive, which leaves 255 available as + * a special value. + * Code points with CCC 0 are known as stoppers. + * leaf[2]: Decomposition. If leaf[1] == 255, then leaf[2] is the + * start of a NUL-terminated string that is the decomposition + * of the character. + * The CCC of a decomposable character is the same as the CCC + * of the first character of its decomposition. + * Some characters decompose as the empty string: these are + * characters with the Default_Ignorable_Code_Point property. + * These do affect normalization, as they all have CCC 0. + * + * The decompositions in the trie have been fully expanded. + * + * Casefolding, if applicable, is also done using decompositions. + */ +typedef unsigned char utf8leaf_t; + +#define LEAF_GEN(LEAF) ((LEAF)[0]) +#define LEAF_CCC(LEAF) ((LEAF)[1]) +#define LEAF_STR(LEAF) ((const char*)((LEAF) + 2)) + +#define MAXGEN (255) + +#define MINCCC (0) +#define MAXCCC (254) +#define STOPPER (0) +#define DECOMPOSE (255) + +struct tree; +static utf8leaf_t *utf8nlookup(struct tree *, const char *, size_t); +static utf8leaf_t *utf8lookup(struct tree *, const char *); + +unsigned char *utf8data; +size_t utf8data_size; + +utf8trie_t *nfkdi; +utf8trie_t *nfkdicf; + +/* ------------------------------------------------------------------ */ + +/* + * UTF8 valid ranges. + * + * The UTF-8 encoding spreads the bits of a 32bit word over several + * bytes. This table gives the ranges that can be held and how they'd + * be represented. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000000 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000000 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * There is an additional requirement on UTF-8, in that only the + * shortest representation of a 32bit value is to be used. A decoder + * must not decode sequences that do not satisfy this requirement. + * Thus the allowed ranges have a lower bound. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000080 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000800 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00010000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00200000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x04000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Actual unicode characters are limited to the range 0x0 - 0x10FFFF, + * 17 planes of 65536 values. This limits the sequences actually seen + * even more, to just the following. + * + * 0 - 0x7f: 0 0x7f + * 0x80 - 0x7ff: 0xc2 0x80 0xdf 0xbf + * 0x800 - 0xffff: 0xe0 0xa0 0x80 0xef 0xbf 0xbf + * 0x10000 - 0x10ffff: 0xf0 0x90 0x80 0x80 0xf4 0x8f 0xbf 0xbf + * + * Even within those ranges not all values are allowed: the surrogates + * 0xd800 - 0xdfff should never be seen. + * + * Note that the longest sequence seen with valid usage is 4 bytes, + * the same a single UTF-32 character. This makes the UTF-8 + * representation of Unicode strictly smaller than UTF-32. + * + * The shortest sequence requirement was introduced by: + * Corrigendum #1: UTF-8 Shortest Form + * It can be found here: + * http://www.unicode.org/versions/corrigendum1.html + * + */ + +#define UTF8_2_BITS 0xC0 +#define UTF8_3_BITS 0xE0 +#define UTF8_4_BITS 0xF0 +#define UTF8_N_BITS 0x80 +#define UTF8_2_MASK 0xE0 +#define UTF8_3_MASK 0xF0 +#define UTF8_4_MASK 0xF8 +#define UTF8_N_MASK 0xC0 +#define UTF8_V_MASK 0x3F +#define UTF8_V_SHIFT 6 + +static int +utf8key(unsigned int key, char keyval[]) +{ + int keylen; + + if (key < 0x80) { + keyval[0] = key; + keylen = 1; + } else if (key < 0x800) { + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_2_BITS; + keylen = 2; + } else if (key < 0x10000) { + keyval[2] = key & UTF8_V_MASK; + keyval[2] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_3_BITS; + keylen = 3; + } else if (key < 0x110000) { + keyval[3] = key & UTF8_V_MASK; + keyval[3] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[2] = key & UTF8_V_MASK; + keyval[2] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_4_BITS; + keylen = 4; + } else { + printf("%#x: illegal key\n", key); + keylen = 0; + } + return keylen; +} + +static unsigned int +utf8code(const char *str) +{ + const unsigned char *s = (const unsigned char*)str; + unsigned int unichar = 0; + + if (*s < 0x80) { + unichar = *s; + } else if (*s < UTF8_3_BITS) { + unichar = *s++ & 0x1F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } else if (*s < UTF8_4_BITS) { + unichar = *s++ & 0x0F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } else { + unichar = *s++ & 0x0F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } + return unichar; +} + +static int +utf32valid(unsigned int unichar) +{ + return unichar < 0x110000; +} + +#define NODE 1 +#define LEAF 0 + +struct tree { + void *root; + int childnode; + const char *type; + unsigned int maxage; + struct tree *next; + int (*leaf_equal)(void *, void *); + void (*leaf_print)(void *, int); + int (*leaf_mark)(void *); + int (*leaf_size)(void *); + int *(*leaf_index)(struct tree *, void *); + unsigned char *(*leaf_emit)(void *, unsigned char *); + int leafindex[0x110000]; + int index; +}; + +struct node { + int index; + int offset; + int mark; + int size; + struct node *parent; + void *left; + void *right; + unsigned char bitnum; + unsigned char nextbyte; + unsigned char leftnode; + unsigned char rightnode; + unsigned int keybits; + unsigned int keymask; +}; + +/* + * Example lookup function for a tree. + */ +static void * +lookup(struct tree *tree, const char *key) +{ + struct node *node; + void *leaf = NULL; + + node = tree->root; + while (!leaf && node) { + if (node->nextbyte) + key++; + if (*key & (1 << (node->bitnum & 7))) { + /* Right leg */ + if (node->rightnode == NODE) { + node = node->right; + } else if (node->rightnode == LEAF) { + leaf = node->right; + } else { + node = NULL; + } + } else { + /* Left leg */ + if (node->leftnode == NODE) { + node = node->left; + } else if (node->leftnode == LEAF) { + leaf = node->left; + } else { + node = NULL; + } + } + } + + return leaf; +} + +/* + * A simple non-recursive tree walker: keep track of visits to the + * left and right branches in the leftmask and rightmask. + */ +static void +tree_walk(struct tree *tree) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int indent = 1; + int nodes, singletons, leaves; + + nodes = singletons = leaves = 0; + + printf("%s_%x root %p\n", tree->type, tree->maxage, tree->root); + if (tree->childnode == LEAF) { + assert(tree->root); + tree->leaf_print(tree->root, indent); + leaves = 1; + } else { + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + printf("%*snode @ %p bitnum %d nextbyte %d" + " left %p right %p mask %x bits %x\n", + indent, "", node, + node->bitnum, node->nextbyte, + node->left, node->right, + node->keymask, node->keybits); + nodes += 1; + if (!(node->left && node->right)) + singletons += 1; + + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + tree->leaf_print(node->left, + indent+1); + leaves += 1; + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + tree->leaf_print(node->right, + indent+1); + leaves += 1; + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } + } + printf("nodes %d leaves %d singletons %d\n", + nodes, leaves, singletons); +} + +/* + * Allocate an initialize a new internal node. + */ +static struct node * +alloc_node(struct node *parent) +{ + struct node *node; + int bitnum; + + node = malloc(sizeof(*node)); + node->left = node->right = NULL; + node->parent = parent; + node->leftnode = NODE; + node->rightnode = NODE; + node->keybits = 0; + node->keymask = 0; + node->mark = 0; + node->index = 0; + node->offset = -1; + node->size = 4; + + if (node->parent) { + bitnum = parent->bitnum; + if ((bitnum & 7) == 0) { + node->bitnum = bitnum + 7 + 8; + node->nextbyte = 1; + } else { + node->bitnum = bitnum - 1; + node->nextbyte = 0; + } + } else { + node->bitnum = 7; + node->nextbyte = 0; + } + + return node; +} + +/* + * Insert a new leaf into the tree, and collapse any subtrees that are + * fully populated and end in identical leaves. A nextbyte tagged + * internal node will not be removed to preserve the tree's integrity. + * Note that due to the structure of utf8, no nextbyte tagged node + * will be a candidate for removal. + */ +static int +insert(struct tree *tree, char *key, int keylen, void *leaf) +{ + struct node *node; + struct node *parent; + void **cursor; + int keybits; + + assert(keylen >= 1 && keylen <= 4); + + node = NULL; + cursor = &tree->root; + keybits = 8 * keylen; + + /* Insert, creating path along the way. */ + while (keybits) { + if (!*cursor) + *cursor = alloc_node(node); + node = *cursor; + if (node->nextbyte) + key++; + if (*key & (1 << (node->bitnum & 7))) + cursor = &node->right; + else + cursor = &node->left; + keybits--; + } + *cursor = leaf; + + /* Merge subtrees if possible. */ + while (node) { + if (*key & (1 << (node->bitnum & 7))) + node->rightnode = LEAF; + else + node->leftnode = LEAF; + if (node->nextbyte) + break; + if (node->leftnode == NODE || node->rightnode == NODE) + break; + assert(node->left); + assert(node->right); + /* Compare */ + if (! tree->leaf_equal(node->left, node->right)) + break; + /* Keep left, drop right leaf. */ + leaf = node->left; + /* Check in parent */ + parent = node->parent; + if (!parent) { + /* root of tree! */ + tree->root = leaf; + tree->childnode = LEAF; + } else if (parent->left == node) { + parent->left = leaf; + parent->leftnode = LEAF; + if (parent->right) { + parent->keymask = 0; + parent->keybits = 0; + } else { + parent->keymask |= (1 << node->bitnum); + } + } else if (parent->right == node) { + parent->right = leaf; + parent->rightnode = LEAF; + if (parent->left) { + parent->keymask = 0; + parent->keybits = 0; + } else { + parent->keymask |= (1 << node->bitnum); + parent->keybits |= (1 << node->bitnum); + } + } else { + /* internal tree error */ + assert(0); + } + free(node); + node = parent; + } + + /* Propagate keymasks up along singleton chains. */ + while (node) { + parent = node->parent; + if (!parent) + break; + /* Nix the mask for parents with two children. */ + if (node->keymask == 0) { + parent->keymask = 0; + parent->keybits = 0; + } else if (parent->left && parent->right) { + parent->keymask = 0; + parent->keybits = 0; + } else { + assert((parent->keymask & node->keymask) == 0); + parent->keymask |= node->keymask; + parent->keymask |= (1 << parent->bitnum); + parent->keybits |= node->keybits; + if (parent->right) + parent->keybits |= (1 << parent->bitnum); + } + node = parent; + } + + return 0; +} + +/* + * Prune internal nodes. + * + * Fully populated subtrees that end at the same leaf have already + * been collapsed. There are still internal nodes that have for both + * their left and right branches a sequence of singletons that make + * identical choices and end in identical leaves. The keymask and + * keybits collected in the nodes describe the choices made in these + * singleton chains. When they are identical for the left and right + * branch of a node, and the two leaves comare identical, the node in + * question can be removed. + * + * Note that nodes with the nextbyte tag set will not be removed by + * this to ensure tree integrity. Note as well that the structure of + * utf8 ensures that these nodes would not have been candidates for + * removal in any case. + */ +static void +prune(struct tree *tree) +{ + struct node *node; + struct node *left; + struct node *right; + struct node *parent; + void *leftleaf; + void *rightleaf; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int count; + + if (verbose > 0) + printf("Pruning %s_%x\n", tree->type, tree->maxage); + + count = 0; + if (tree->childnode == LEAF) + return; + if (!tree->root) + return; + + leftmask = rightmask = 0; + node = tree->root; + while (node) { + if (node->nextbyte) + goto advance; + if (node->leftnode == LEAF) + goto advance; + if (node->rightnode == LEAF) + goto advance; + if (!node->left) + goto advance; + if (!node->right) + goto advance; + left = node->left; + right = node->right; + if (left->keymask == 0) + goto advance; + if (right->keymask == 0) + goto advance; + if (left->keymask != right->keymask) + goto advance; + if (left->keybits != right->keybits) + goto advance; + leftleaf = NULL; + while (!leftleaf) { + assert(left->left || left->right); + if (left->leftnode == LEAF) + leftleaf = left->left; + else if (left->rightnode == LEAF) + leftleaf = left->right; + else if (left->left) + left = left->left; + else if (left->right) + left = left->right; + else + assert(0); + } + rightleaf = NULL; + while (!rightleaf) { + assert(right->left || right->right); + if (right->leftnode == LEAF) + rightleaf = right->left; + else if (right->rightnode == LEAF) + rightleaf = right->right; + else if (right->left) + right = right->left; + else if (right->right) + right = right->right; + else + assert(0); + } + if (! tree->leaf_equal(leftleaf, rightleaf)) + goto advance; + /* + * This node has identical singleton-only subtrees. + * Remove it. + */ + parent = node->parent; + left = node->left; + right = node->right; + if (parent->left == node) + parent->left = left; + else if (parent->right == node) + parent->right = left; + else + assert(0); + left->parent = parent; + left->keymask |= (1 << node->bitnum); + node->left = NULL; + while (node) { + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + if (node->leftnode == NODE && node->left) { + left = node->left; + free(node); + count++; + node = left; + } else if (node->rightnode == NODE && node->right) { + right = node->right; + free(node); + count++; + node = right; + } else { + node = NULL; + } + } + /* Propagate keymasks up along singleton chains. */ + node = parent; + /* Force re-check */ + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + for (;;) { + if (node->left && node->right) + break; + if (node->left) { + left = node->left; + node->keymask |= left->keymask; + node->keybits |= left->keybits; + } + if (node->right) { + right = node->right; + node->keymask |= right->keymask; + node->keybits |= right->keybits; + } + node->keymask |= (1 << node->bitnum); + node = node->parent; + /* Force re-check */ + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + } + advance: + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0 && + node->leftnode == NODE && + node->left) { + leftmask |= bitmask; + node = node->left; + } else if ((rightmask & bitmask) == 0 && + node->rightnode == NODE && + node->right) { + rightmask |= bitmask; + node = node->right; + } else { + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } + } + if (verbose > 0) + printf("Pruned %d nodes\n", count); +} + +/* + * Mark the nodes in the tree that lead to leaves that must be + * emitted. + */ +static void +mark_nodes(struct tree *tree) +{ + struct node *node; + struct node *n; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int marked; + + marked = 0; + if (verbose > 0) + printf("Marking %s_%x\n", tree->type, tree->maxage); + if (tree->childnode == LEAF) + goto done; + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + if (tree->leaf_mark(node->left)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->left) { + assert(node->leftnode == NODE); + node = node->left; + continue; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + if (tree->leaf_mark(node->right)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->right) { + assert(node->rightnode==NODE); + node = node->right; + continue; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } + + /* second pass: left siblings and singletons */ + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + if (tree->leaf_mark(node->left)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->left) { + assert(node->leftnode == NODE); + node = node->left; + if (!node->mark && node->parent->mark) { + marked++; + node->mark = 1; + } + continue; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + if (tree->leaf_mark(node->right)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->right) { + assert(node->rightnode==NODE); + node = node->right; + if (!node->mark && node->parent->mark && + !node->parent->left) { + marked++; + node->mark = 1; + } + continue; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } +done: + if (verbose > 0) + printf("Marked %d nodes\n", marked); +} + +/* + * Compute the index of each node and leaf, which is the offset in the + * emitted trie. These value must be pre-computed because relative + * offsets between nodes are used to navigate the tree. + */ +static int +index_nodes(struct tree *tree, int index) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int count; + int indent; + + /* Align to a cache line (or half a cache line?). */ + while (index % 64) + index++; + tree->index = index; + indent = 1; + count = 0; + + if (verbose > 0) + printf("Indexing %s_%x: %d", tree->type, tree->maxage, index); + if (tree->childnode == LEAF) { + index += tree->leaf_size(tree->root); + goto done; + } + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + count++; + if (node->index != index) + node->index = index; + index += node->size; +skip: + while (node) { + bitmask = 1 << node->bitnum; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + *tree->leaf_index(tree, node->left) = + index; + index += tree->leaf_size(node->left); + count++; + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + *tree->leaf_index(tree, node->right) = index; + index += tree->leaf_size(node->right); + count++; + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +done: + /* Round up to a multiple of 16 */ + while (index % 16) + index++; + if (verbose > 0) + printf("Final index %d\n", index); + return index; +} + +/* + * Compute the size of nodes and leaves. We start by assuming that + * each node needs to store a three-byte offset. The indexes of the + * nodes are calculated based on that, and then this function is + * called to see if the sizes of some nodes can be reduced. This is + * repeated until no more changes are seen. + */ +static int +size_nodes(struct tree *tree) +{ + struct tree *next; + struct node *node; + struct node *right; + struct node *n; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + unsigned int pathbits; + unsigned int pathmask; + int changed; + int offset; + int size; + int indent; + + indent = 1; + changed = 0; + size = 0; + + if (verbose > 0) + printf("Sizing %s_%x", tree->type, tree->maxage); + if (tree->childnode == LEAF) + goto done; + + assert(tree->childnode == NODE); + pathbits = 0; + pathmask = 0; + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + offset = 0; + if (!node->left || !node->right) { + size = 1; + } else { + if (node->rightnode == NODE) { + right = node->right; + next = tree->next; + while (!right->mark) { + assert(next); + n = next->root; + while (n->bitnum != node->bitnum) { + if (pathbits & (1<bitnum)) + n = n->right; + else + n = n->left; + } + n = n->right; + assert(right->bitnum == n->bitnum); + right = n; + next = next->next; + } + offset = right->index - node->index; + } else { + offset = *tree->leaf_index(tree, node->right); + offset -= node->index; + } + assert(offset >= 0); + assert(offset <= 0xffffff); + if (offset <= 0xff) { + size = 2; + } else if (offset <= 0xffff) { + size = 3; + } else { /* offset <= 0xffffff */ + size = 4; + } + } + if (node->size != size || node->offset != offset) { + node->size = size; + node->offset = offset; + changed++; + } +skip: + while (node) { + bitmask = 1 << node->bitnum; + pathmask |= bitmask; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + pathbits |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + pathmask &= ~bitmask; + pathbits &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +done: + if (verbose > 0) + printf("Found %d changes\n", changed); + return changed; +} + +/* + * Emit a trie for the given tree into the data array. + */ +static void +emit(struct tree *tree, unsigned char *data) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int offlen; + int offset; + int index; + int indent; + unsigned char byte; + + index = tree->index; + data += index; + indent = 1; + if (verbose > 0) + printf("Emitting %s_%x\n", tree->type, tree->maxage); + if (tree->childnode == LEAF) { + assert(tree->root); + tree->leaf_emit(tree->root, data); + return; + } + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + assert(node->offset != -1); + assert(node->index == index); + + byte = 0; + if (node->nextbyte) + byte |= NEXTBYTE; + byte |= (node->bitnum & BITNUM); + if (node->left && node->right) { + if (node->leftnode == NODE) + byte |= LEFTNODE; + if (node->rightnode == NODE) + byte |= RIGHTNODE; + if (node->offset <= 0xff) + offlen = 1; + else if (node->offset <= 0xffff) + offlen = 2; + else + offlen = 3; + offset = node->offset; + byte |= offlen << OFFLEN_SHIFT; + *data++ = byte; + index++; + while (offlen--) { + *data++ = offset & 0xff; + index++; + offset >>= 8; + } + } else if (node->left) { + if (node->leftnode == NODE) + byte |= TRIENODE; + *data++ = byte; + index++; + } else if (node->right) { + byte |= RIGHTNODE; + if (node->rightnode == NODE) + byte |= TRIENODE; + *data++ = byte; + index++; + } else { + assert(0); + } +skip: + while (node) { + bitmask = 1 << node->bitnum; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + data = tree->leaf_emit(node->left, + data); + index += tree->leaf_size(node->left); + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + data = tree->leaf_emit(node->right, + data); + index += tree->leaf_size(node->right); + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +} + +/* ------------------------------------------------------------------ */ + +/* + * Unicode data. + * + * We need to keep track of the Canonical Combining Class, the Age, + * and decompositions for a code point. + * + * For the Age, we store the index into the ages table. Effectively + * this is a generation number that the table maps to a unicode + * version. + * + * The correction field is used to indicate that this entry is in the + * corrections array, which contains decompositions that were + * corrected in later revisions. The value of the correction field is + * the Unicode version in which the mapping was corrected. + */ +struct unicode_data { + unsigned int code; + int ccc; + int gen; + int correction; + unsigned int *utf32nfkdi; + unsigned int *utf32nfkdicf; + char *utf8nfkdi; + char *utf8nfkdicf; +}; + +struct unicode_data unicode_data[0x110000]; +struct unicode_data *corrections; +int corrections_count; + +struct tree *nfkdi_tree; +struct tree *nfkdicf_tree; + +struct tree *trees; +int trees_count; + +/* + * Check the corrections array to see if this entry was corrected at + * some point. + */ +static struct unicode_data * +corrections_lookup(struct unicode_data *u) +{ + int i; + + for (i = 0; i != corrections_count; i++) + if (u->code == corrections[i].code) + return &corrections[i]; + return u; +} + +static int +nfkdi_equal(void *l, void *r) +{ + struct unicode_data *left = l; + struct unicode_data *right = r; + + if (left->gen != right->gen) + return 0; + if (left->ccc != right->ccc) + return 0; + if (left->utf8nfkdi && right->utf8nfkdi && + strcmp(left->utf8nfkdi, right->utf8nfkdi) == 0) + return 1; + if (left->utf8nfkdi || right->utf8nfkdi) + return 0; + return 1; +} + +static int +nfkdicf_equal(void *l, void *r) +{ + struct unicode_data *left = l; + struct unicode_data *right = r; + + if (left->gen != right->gen) + return 0; + if (left->ccc != right->ccc) + return 0; + if (left->utf8nfkdicf && right->utf8nfkdicf && + strcmp(left->utf8nfkdicf, right->utf8nfkdicf) == 0) + return 1; + if (left->utf8nfkdicf && right->utf8nfkdicf) + return 0; + if (left->utf8nfkdicf || right->utf8nfkdicf) + return 0; + if (left->utf8nfkdi && right->utf8nfkdi && + strcmp(left->utf8nfkdi, right->utf8nfkdi) == 0) + return 1; + if (left->utf8nfkdi || right->utf8nfkdi) + return 0; + return 1; +} + +static void +nfkdi_print(void *l, int indent) +{ + struct unicode_data *leaf = l; + + printf("%*sleaf @ %p code %X ccc %d gen %d", indent, "", leaf, + leaf->code, leaf->ccc, leaf->gen); + if (leaf->utf8nfkdi) + printf(" nfkdi \"%s\"", (const char*)leaf->utf8nfkdi); + printf("\n"); +} + +static void +nfkdicf_print(void *l, int indent) +{ + struct unicode_data *leaf = l; + + printf("%*sleaf @ %p code %X ccc %d gen %d", indent, "", leaf, + leaf->code, leaf->ccc, leaf->gen); + if (leaf->utf8nfkdicf) + printf(" nfkdicf \"%s\"", (const char*)leaf->utf8nfkdicf); + else if (leaf->utf8nfkdi) + printf(" nfkdi \"%s\"", (const char*)leaf->utf8nfkdi); + printf("\n"); +} + +static int +nfkdi_mark(void *l) +{ + return 1; +} + +static int +nfkdicf_mark(void *l) +{ + struct unicode_data *leaf = l; + + if (leaf->utf8nfkdicf) + return 1; + return 0; +} + +static int +correction_mark(void *l) +{ + struct unicode_data *leaf = l; + + return leaf->correction; +} + +static int +nfkdi_size(void *l) +{ + struct unicode_data *leaf = l; + + int size = 2; + if (leaf->utf8nfkdi) + size += strlen(leaf->utf8nfkdi) + 1; + return size; +} + +static int +nfkdicf_size(void *l) +{ + struct unicode_data *leaf = l; + + int size = 2; + if (leaf->utf8nfkdicf) + size += strlen(leaf->utf8nfkdicf) + 1; + else if (leaf->utf8nfkdi) + size += strlen(leaf->utf8nfkdi) + 1; + return size; +} + +static int * +nfkdi_index(struct tree *tree, void *l) +{ + struct unicode_data *leaf = l; + + return &tree->leafindex[leaf->code]; +} + +static int * +nfkdicf_index(struct tree *tree, void *l) +{ + struct unicode_data *leaf = l; + + return &tree->leafindex[leaf->code]; +} + +static unsigned char * +nfkdi_emit(void *l, unsigned char *data) +{ + struct unicode_data *leaf = l; + unsigned char *s; + + *data++ = leaf->gen; + if (leaf->utf8nfkdi) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdi; + while ((*data++ = *s++) != 0) + ; + } else { + *data++ = leaf->ccc; + } + return data; +} + +static unsigned char * +nfkdicf_emit(void *l, unsigned char *data) +{ + struct unicode_data *leaf = l; + unsigned char *s; + + *data++ = leaf->gen; + if (leaf->utf8nfkdicf) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdicf; + while ((*data++ = *s++) != 0) + ; + } else if (leaf->utf8nfkdi) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdi; + while ((*data++ = *s++) != 0) + ; + } else { + *data++ = leaf->ccc; + } + return data; +} + +static void +utf8_create(struct unicode_data *data) +{ + char utf[18*4+1]; + char *u; + unsigned int *um; + int i; + + u = utf; + um = data->utf32nfkdi; + if (um) { + for (i = 0; um[i]; i++) + u += utf8key(um[i], u); + *u = '\0'; + data->utf8nfkdi = strdup((char*)utf); + } + u = utf; + um = data->utf32nfkdicf; + if (um) { + for (i = 0; um[i]; i++) + u += utf8key(um[i], u); + *u = '\0'; + if (!data->utf8nfkdi || strcmp(data->utf8nfkdi, (char*)utf)) + data->utf8nfkdicf = strdup((char*)utf); + } +} + +static void +utf8_init(void) +{ + unsigned int unichar; + int i; + + for (unichar = 0; unichar != 0x110000; unichar++) + utf8_create(&unicode_data[unichar]); + + for (i = 0; i != corrections_count; i++) + utf8_create(&corrections[i]); +} + +static void +trees_init(void) +{ + struct unicode_data *data; + unsigned int maxage; + unsigned int nextage; + int count; + int i; + int j; + + /* Count the number of different ages. */ + count = 0; + nextage = (unsigned int)-1; + do { + maxage = nextage; + nextage = 0; + for (i = 0; i <= corrections_count; i++) { + data = &corrections[i]; + if (nextage < data->correction && + data->correction < maxage) + nextage = data->correction; + } + count++; + } while (nextage); + + /* Two trees per age: nfkdi and nfkdicf */ + trees_count = count * 2; + trees = calloc(trees_count, sizeof(struct tree)); + + /* Assign ages to the trees. */ + count = trees_count; + nextage = (unsigned int)-1; + do { + maxage = nextage; + trees[--count].maxage = maxage; + trees[--count].maxage = maxage; + nextage = 0; + for (i = 0; i <= corrections_count; i++) { + data = &corrections[i]; + if (nextage < data->correction && + data->correction < maxage) + nextage = data->correction; + } + } while (nextage); + + /* The ages assigned above are off by one. */ + for (i = 0; i != trees_count; i++) { + j = 0; + while (ages[j] < trees[i].maxage) + j++; + trees[i].maxage = ages[j-1]; + } + + /* Set up the forwarding between trees. */ + trees[trees_count-2].next = &trees[trees_count-1]; + trees[trees_count-1].leaf_mark = nfkdi_mark; + trees[trees_count-2].leaf_mark = nfkdicf_mark; + for (i = 0; i != trees_count-2; i += 2) { + trees[i].next = &trees[trees_count-2]; + trees[i].leaf_mark = correction_mark; + trees[i+1].next = &trees[trees_count-1]; + trees[i+1].leaf_mark = correction_mark; + } + + /* Assign the callouts. */ + for (i = 0; i != trees_count; i += 2) { + trees[i].type = "nfkdicf"; + trees[i].leaf_equal = nfkdicf_equal; + trees[i].leaf_print = nfkdicf_print; + trees[i].leaf_size = nfkdicf_size; + trees[i].leaf_index = nfkdicf_index; + trees[i].leaf_emit = nfkdicf_emit; + + trees[i+1].type = "nfkdi"; + trees[i+1].leaf_equal = nfkdi_equal; + trees[i+1].leaf_print = nfkdi_print; + trees[i+1].leaf_size = nfkdi_size; + trees[i+1].leaf_index = nfkdi_index; + trees[i+1].leaf_emit = nfkdi_emit; + } + + /* Finish init. */ + for (i = 0; i != trees_count; i++) + trees[i].childnode = NODE; +} + +static void +trees_populate(void) +{ + struct unicode_data *data; + unsigned int unichar; + char keyval[4]; + int keylen; + int i; + + for (i = 0; i != trees_count; i++) { + if (verbose > 0) { + printf("Populating %s_%x\n", + trees[i].type, trees[i].maxage); + } + for (unichar = 0; unichar != 0x110000; unichar++) { + if (unicode_data[unichar].gen < 0) + continue; + keylen = utf8key(unichar, keyval); + data = corrections_lookup(&unicode_data[unichar]); + if (data->correction <= trees[i].maxage) + data = &unicode_data[unichar]; + insert(&trees[i], keyval, keylen, data); + } + } +} + +static void +trees_reduce(void) +{ + int i; + int size; + int changed; + + for (i = 0; i != trees_count; i++) + prune(&trees[i]); + for (i = 0; i != trees_count; i++) + mark_nodes(&trees[i]); + do { + size = 0; + for (i = 0; i != trees_count; i++) + size = index_nodes(&trees[i], size); + changed = 0; + for (i = 0; i != trees_count; i++) + changed += size_nodes(&trees[i]); + } while (changed); + + utf8data = calloc(size, 1); + utf8data_size = size; + for (i = 0; i != trees_count; i++) + emit(&trees[i], utf8data); + + if (verbose > 0) { + for (i = 0; i != trees_count; i++) { + printf("%s_%x idx %d\n", + trees[i].type, trees[i].maxage, trees[i].index); + } + } + + nfkdi = utf8data + trees[trees_count-1].index; + nfkdicf = utf8data + trees[trees_count-2].index; + + nfkdi_tree = &trees[trees_count-1]; + nfkdicf_tree = &trees[trees_count-2]; +} + +static void +verify(struct tree *tree) +{ + struct unicode_data *data; + utf8leaf_t *leaf; + unsigned int unichar; + char key[4]; + int report; + int nocf; + + if (verbose > 0) + printf("Verifying %s_%x\n", tree->type, tree->maxage); + nocf = strcmp(tree->type, "nfkdicf"); + + for (unichar = 0; unichar != 0x110000; unichar++) { + report = 0; + data = corrections_lookup(&unicode_data[unichar]); + if (data->correction <= tree->maxage) + data = &unicode_data[unichar]; + utf8key(unichar, key); + leaf = utf8lookup(tree, key); + if (!leaf) { + if (data->gen != -1) + report++; + if (unichar < 0xd800 || unichar > 0xdfff) + report++; + } else { + if (unichar >= 0xd800 && unichar <= 0xdfff) + report++; + if (data->gen == -1) + report++; + if (data->gen != LEAF_GEN(leaf)) + report++; + if (LEAF_CCC(leaf) == DECOMPOSE) { + if (nocf) { + if (!data->utf8nfkdi) { + report++; + } else if (strcmp(data->utf8nfkdi, + LEAF_STR(leaf))) { + report++; + } + } else { + if (!data->utf8nfkdicf && + !data->utf8nfkdi) { + report++; + } else if (data->utf8nfkdicf) { + if (strcmp(data->utf8nfkdicf, + LEAF_STR(leaf))) + report++; + } else if (strcmp(data->utf8nfkdi, + LEAF_STR(leaf))) { + report++; + } + } + } else if (data->ccc != LEAF_CCC(leaf)) { + report++; + } + } + if (report) { + printf("%X code %X gen %d ccc %d" + " nfdki -> \"%s\"", + unichar, data->code, data->gen, + data->ccc, + data->utf8nfkdi); + if (leaf) { + printf(" age %d ccc %d" + " nfdki -> \"%s\"\n", + LEAF_GEN(leaf), + LEAF_CCC(leaf), + LEAF_CCC(leaf) == DECOMPOSE ? + LEAF_STR(leaf) : ""); + } + printf("\n"); + } + } +} + +static void +trees_verify(void) +{ + int i; + + for (i = 0; i != trees_count; i++) + verify(&trees[i]); +} + +/* ------------------------------------------------------------------ */ + +static void +help(void) +{ + printf("Usage: %s [options]\n", argv0); + printf("\n"); + printf("This program creates an a data trie used for parsing and\n"); + printf("normalization of UTF-8 strings. The trie is derived from\n"); + printf("a set of input files from the Unicode character database\n"); + printf("found at: http://www.unicode.org/Public/UCD/latest/ucd/\n"); + printf("\n"); + printf("The generated tree supports two normalization forms:\n"); + printf("\n"); + printf("\tnfkdi:\n"); + printf("\t- Apply unicode normalization form NFKD.\n"); + printf("\t- Remove any Default_Ignorable_Code_Point.\n"); + printf("\n"); + printf("\tnfkdicf:\n"); + printf("\t- Apply unicode normalization form NFKD.\n"); + printf("\t- Remove any Default_Ignorable_Code_Point.\n"); + printf("\t- Apply a full casefold (C + F).\n"); + printf("\n"); + printf("These forms were chosen as being most useful when dealing\n"); + printf("with file names: NFKD catches most cases where characters\n"); + printf("should be considered equivalent. The ignorables are mostly\n"); + printf("invisible, making names hard to type.\n"); + printf("\n"); + printf("The options to specify the files to be used are listed\n"); + printf("below with their default values, which are the names used\n"); + printf("by version 7.0.0 of the Unicode Character Database.\n"); + printf("\n"); + printf("The input files:\n"); + printf("\t-a %s\n", AGE_NAME); + printf("\t-c %s\n", CCC_NAME); + printf("\t-p %s\n", PROP_NAME); + printf("\t-d %s\n", DATA_NAME); + printf("\t-f %s\n", FOLD_NAME); + printf("\t-n %s\n", NORM_NAME); + printf("\n"); + printf("Additionally, the generated tables are tested using:\n"); + printf("\t-t %s\n", TEST_NAME); + printf("\n"); + printf("Finally, the output file:\n"); + printf("\t-o %s\n", UTF8_NAME); + printf("\n"); +} + +static void +usage(void) +{ + help(); + exit(1); +} + +static void +open_fail(const char *name, int error) +{ + printf("Error %d opening %s: %s\n", error, name, strerror(error)); + exit(1); +} + +static void +file_fail(const char *filename) +{ + printf("Error parsing %s\n", filename); + exit(1); +} + +static void +line_fail(const char *filename, const char *line) +{ + printf("Error parsing %s:%s\n", filename, line); + exit(1); +} + +/* ------------------------------------------------------------------ */ + +static void +print_utf32(unsigned int *utf32str) +{ + int i; + + for (i = 0; utf32str[i]; i++) + printf(" %X", utf32str[i]); +} + +static void +print_utf32nfkdi(unsigned int unichar) +{ + printf(" %X ->", unichar); + print_utf32(unicode_data[unichar].utf32nfkdi); + printf("\n"); +} + +static void +print_utf32nfkdicf(unsigned int unichar) +{ + printf(" %X ->", unichar); + print_utf32(unicode_data[unichar].utf32nfkdicf); + printf("\n"); +} + +/* ------------------------------------------------------------------ */ + +static void +age_init(void) +{ + FILE *file; + unsigned int first; + unsigned int last; + unsigned int unichar; + unsigned int major; + unsigned int minor; + unsigned int revision; + int gen; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", age_name); + + file = fopen(age_name, "r"); + if (!file) + open_fail(age_name, errno); + count = 0; + + gen = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "# Age=V%d_%d_%d", + &major, &minor, &revision); + if (ret == 3) { + ages_count++; + if (verbose > 1) + printf(" Age V%d_%d_%d\n", + major, minor, revision); + if (!age_valid(major, minor, revision)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "# Age=V%d_%d", &major, &minor); + if (ret == 2) { + ages_count++; + if (verbose > 1) + printf(" Age V%d_%d\n", major, minor); + if (!age_valid(major, minor, 0)) + line_fail(age_name, line); + continue; + } + } + + /* We must have found something above. */ + if (verbose > 1) + printf("%d age entries\n", ages_count); + if (ages_count == 0 || ages_count > MAXGEN) + file_fail(age_name); + + /* There is a 0 entry. */ + ages_count++; + ages = calloc(ages_count + 1, sizeof(*ages)); + /* And a guard entry. */ + ages[ages_count] = (unsigned int)-1; + + rewind(file); + count = 0; + gen = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "# Age=V%d_%d_%d", + &major, &minor, &revision); + if (ret == 3) { + ages[++gen] = + UNICODE_AGE(major, minor, revision); + if (verbose > 1) + printf(" Age V%d_%d_%d = gen %d\n", + major, minor, revision, gen); + if (!age_valid(major, minor, revision)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "# Age=V%d_%d", &major, &minor); + if (ret == 2) { + ages[++gen] = UNICODE_AGE(major, minor, 0); + if (verbose > 1) + printf(" Age V%d_%d = %d\n", + major, minor, gen); + if (!age_valid(major, minor, 0)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "%X..%X ; %d.%d #", + &first, &last, &major, &minor); + if (ret == 4) { + for (unichar = first; unichar <= last; unichar++) + unicode_data[unichar].gen = gen; + count += 1 + last - first; + if (verbose > 1) + printf(" %X..%X gen %d\n", first, last, gen); + if (!utf32valid(first) || !utf32valid(last)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "%X ; %d.%d #", &unichar, &major, &minor); + if (ret == 3) { + unicode_data[unichar].gen = gen; + count++; + if (verbose > 1) + printf(" %X gen %d\n", unichar, gen); + if (!utf32valid(unichar)) + line_fail(age_name, line); + continue; + } + } + unicode_maxage = ages[gen]; + fclose(file); + + /* Nix surrogate block */ + if (verbose > 1) + printf(" Removing surrogate block D800..DFFF\n"); + for (unichar = 0xd800; unichar <= 0xdfff; unichar++) + unicode_data[unichar].gen = -1; + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(age_name); +} + +static void +ccc_init(void) +{ + FILE *file; + unsigned int first; + unsigned int last; + unsigned int unichar; + unsigned int value; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", ccc_name); + + file = fopen(ccc_name, "r"); + if (!file) + open_fail(ccc_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X..%X ; %d #", &first, &last, &value); + if (ret == 3) { + for (unichar = first; unichar <= last; unichar++) { + unicode_data[unichar].ccc = value; + count++; + } + if (verbose > 1) + printf(" %X..%X ccc %d\n", first, last, value); + if (!utf32valid(first) || !utf32valid(last)) + line_fail(ccc_name, line); + continue; + } + ret = sscanf(line, "%X ; %d #", &unichar, &value); + if (ret == 2) { + unicode_data[unichar].ccc = value; + count++; + if (verbose > 1) + printf(" %X ccc %d\n", unichar, value); + if (!utf32valid(unichar)) + line_fail(ccc_name, line); + continue; + } + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(ccc_name); +} + +static void +nfkdi_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char *s; + unsigned int *um; + int count; + int i; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", data_name); + file = fopen(data_name, "r"); + if (!file) + open_fail(data_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%*[^;];%*[^;];%*[^;];%*[^;];%[^;];", + &unichar, buf0); + if (ret != 2) + continue; + if (!utf32valid(unichar)) + line_fail(data_name, line); + + s = buf0; + /* skip over */ + if (*s == '<') + while (*s++ != ' ') + ; + /* decode the decomposition into UTF-32 */ + i = 0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(data_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + + if (verbose > 1) + print_utf32nfkdi(unichar); + count++; + } + fclose(file); + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(data_name); +} + +static void +nfkdicf_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char status; + char *s; + unsigned int *um; + int i; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", fold_name); + file = fopen(fold_name, "r"); + if (!file) + open_fail(fold_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X; %c; %[^;];", &unichar, &status, buf0); + if (ret != 3) + continue; + if (!utf32valid(unichar)) + line_fail(fold_name, line); + /* Use the C+F casefold. */ + if (status != 'C' && status != 'F') + continue; + s = buf0; + if (*s == '<') + while (*s++ != ' ') + ; + i = 0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(fold_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + + if (verbose > 1) + print_utf32nfkdicf(unichar); + count++; + } + fclose(file); + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(fold_name); +} + +static void +ignore_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int first; + unsigned int last; + unsigned int *um; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", prop_name); + file = fopen(prop_name, "r"); + if (!file) + open_fail(prop_name, errno); + assert(file); + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X..%X ; %s # ", &first, &last, buf0); + if (ret == 3) { + if (strcmp(buf0, "Default_Ignorable_Code_Point")) + continue; + if (!utf32valid(first) || !utf32valid(last)) + line_fail(prop_name, line); + for (unichar = first; unichar <= last; unichar++) { + free(unicode_data[unichar].utf32nfkdi); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdi = um; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdicf = um; + count++; + } + if (verbose > 1) + printf(" %X..%X Default_Ignorable_Code_Point\n", + first, last); + continue; + } + ret = sscanf(line, "%X ; %s # ", &unichar, buf0); + if (ret == 2) { + if (strcmp(buf0, "Default_Ignorable_Code_Point")) + continue; + if (!utf32valid(unichar)) + line_fail(prop_name, line); + free(unicode_data[unichar].utf32nfkdi); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdi = um; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdicf = um; + if (verbose > 1) + printf(" %X Default_Ignorable_Code_Point\n", + unichar); + count++; + continue; + } + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(prop_name); +} + +static void +corrections_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int major; + unsigned int minor; + unsigned int revision; + unsigned int age; + unsigned int *um; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char *s; + int i; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", norm_name); + file = fopen(norm_name, "r"); + if (!file) + open_fail(norm_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%[^;];%[^;];%d.%d.%d #", + &unichar, buf0, buf1, + &major, &minor, &revision); + if (ret != 6) + continue; + if (!utf32valid(unichar) || !age_valid(major, minor, revision)) + line_fail(norm_name, line); + count++; + } + corrections = calloc(count, sizeof(struct unicode_data)); + corrections_count = count; + rewind(file); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%[^;];%[^;];%d.%d.%d #", + &unichar, buf0, buf1, + &major, &minor, &revision); + if (ret != 6) + continue; + if (!utf32valid(unichar) || !age_valid(major, minor, revision)) + line_fail(norm_name, line); + corrections[count] = unicode_data[unichar]; + assert(corrections[count].code == unichar); + age = UNICODE_AGE(major, minor, revision); + corrections[count].correction = age; + + i = 0; + s = buf0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(norm_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + corrections[count].utf32nfkdi = um; + + if (verbose > 1) + printf(" %X -> %s -> %s V%d_%d_%d\n", + unichar, buf0, buf1, major, minor, revision); + count++; + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(norm_name); +} + +/* ------------------------------------------------------------------ */ + +/* + * Hangul decomposition (algorithm from Section 3.12 of Unicode 6.3.0) + * + * AC00;;Lo;0;L;;;;;N;;;;; + * D7A3;;Lo;0;L;;;;;N;;;;; + * + * SBase = 0xAC00 + * LBase = 0x1100 + * VBase = 0x1161 + * TBase = 0x11A7 + * LCount = 19 + * VCount = 21 + * TCount = 28 + * NCount = 588 (VCount * TCount) + * SCount = 11172 (LCount * NCount) + * + * Decomposition: + * SIndex = s - SBase + * + * LV (Canonical/Full) + * LIndex = SIndex / NCount + * VIndex = (Sindex % NCount) / TCount + * LPart = LBase + LIndex + * VPart = VBase + VIndex + * + * LVT (Canonical) + * LVIndex = (SIndex / TCount) * TCount + * TIndex = (Sindex % TCount + * LVPart = LBase + LVIndex + * TPart = TBase + TIndex + * + * LVT (Full) + * LIndex = SIndex / NCount + * VIndex = (Sindex % NCount) / TCount + * TIndex = (Sindex % TCount + * LPart = LBase + LIndex + * VPart = VBase + VIndex + * if (TIndex == 0) { + * d = + * } else { + * TPart = TBase + TIndex + * d = + * } + * + */ + +static void +hangul_decompose(void) +{ + unsigned int sb = 0xAC00; + unsigned int lb = 0x1100; + unsigned int vb = 0x1161; + unsigned int tb = 0x11a7; + /* unsigned int lc = 19; */ + unsigned int vc = 21; + unsigned int tc = 28; + unsigned int nc = (vc * tc); + /* unsigned int sc = (lc * nc); */ + unsigned int unichar; + unsigned int mapping[4]; + unsigned int *um; + int count; + int i; + + if (verbose > 0) + printf("Decomposing hangul\n"); + /* Hangul */ + count = 0; + for (unichar = 0xAC00; unichar <= 0xD7A3; unichar++) { + unsigned int si = unichar - sb; + unsigned int li = si / nc; + unsigned int vi = (si % nc) / tc; + unsigned int ti = si % tc; + + i = 0; + mapping[i++] = lb + li; + mapping[i++] = vb + vi; + if (ti) + mapping[i++] = tb + ti; + mapping[i++] = 0; + + assert(!unicode_data[unichar].utf32nfkdi); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + + assert(!unicode_data[unichar].utf32nfkdicf); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + + if (verbose > 1) + print_utf32nfkdi(unichar); + + count++; + } + if (verbose > 0) + printf("Created %d entries\n", count); +} + +static void +nfkdi_decompose(void) +{ + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + unsigned int *um; + unsigned int *dc; + int count; + int i; + int j; + int ret; + + if (verbose > 0) + printf("Decomposing nfkdi\n"); + + count = 0; + for (unichar = 0; unichar != 0x110000; unichar++) { + if (!unicode_data[unichar].utf32nfkdi) + continue; + for (;;) { + ret = 1; + i = 0; + um = unicode_data[unichar].utf32nfkdi; + while (*um) { + dc = unicode_data[*um].utf32nfkdi; + if (dc) { + for (j = 0; dc[j]; j++) + mapping[i++] = dc[j]; + ret = 0; + } else { + mapping[i++] = *um; + } + um++; + } + mapping[i++] = 0; + if (ret) + break; + free(unicode_data[unichar].utf32nfkdi); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + } + /* Add this decomposition to nfkdicf if there is no entry. */ + if (!unicode_data[unichar].utf32nfkdicf) { + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + } + if (verbose > 1) + print_utf32nfkdi(unichar); + count++; + } + if (verbose > 0) + printf("Processed %d entries\n", count); +} + +static void +nfkdicf_decompose(void) +{ + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + unsigned int *um; + unsigned int *dc; + int count; + int i; + int j; + int ret; + + if (verbose > 0) + printf("Decomposing nfkdicf\n"); + count = 0; + for (unichar = 0; unichar != 0x110000; unichar++) { + if (!unicode_data[unichar].utf32nfkdicf) + continue; + for (;;) { + ret = 1; + i = 0; + um = unicode_data[unichar].utf32nfkdicf; + while (*um) { + dc = unicode_data[*um].utf32nfkdicf; + if (dc) { + for (j = 0; dc[j]; j++) + mapping[i++] = dc[j]; + ret = 0; + } else { + mapping[i++] = *um; + } + um++; + } + mapping[i++] = 0; + if (ret) + break; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + } + if (verbose > 1) + print_utf32nfkdicf(unichar); + count++; + } + if (verbose > 0) + printf("Processed %d entries\n", count); +} + +/* ------------------------------------------------------------------ */ + +int utf8agemax(struct tree *, const char *); +int utf8nagemax(struct tree *, const char *, size_t); +int utf8agemin(struct tree *, const char *); +int utf8nagemin(struct tree *, const char *, size_t); +ssize_t utf8len(struct tree *, const char *); +ssize_t utf8nlen(struct tree *, const char *, size_t); +struct utf8cursor; +int utf8cursor(struct utf8cursor *, struct tree *, const char *); +int utf8ncursor(struct utf8cursor *, struct tree *, const char *, size_t); +int utf8byte(struct utf8cursor *); + +/* + * Use trie to scan s, touching at most len bytes. + * Returns the leaf if one exists, NULL otherwise. + * + * A non-NULL return guarantees that the UTF-8 sequence starting at s + * is well-formed and corresponds to a known unicode code point. The + * shorthand for this will be "is valid UTF-8 unicode". + */ +static utf8leaf_t * +utf8nlookup(struct tree *tree, const char *s, size_t len) +{ + utf8trie_t *trie = utf8data + tree->index; + int offlen; + int offset; + int mask; + int node; + + if (!tree) + return NULL; + if (len == 0) + return NULL; + node = 1; + while (node) { + offlen = (*trie & OFFLEN) >> OFFLEN_SHIFT; + if (*trie & NEXTBYTE) { + if (--len == 0) + return NULL; + s++; + } + mask = 1 << (*trie & BITNUM); + if (*s & mask) { + /* Right leg */ + if (offlen) { + /* Right node at offset of trie */ + node = (*trie & RIGHTNODE); + offset = trie[offlen]; + while (--offlen) { + offset <<= 8; + offset |= trie[offlen]; + } + trie += offset; + } else if (*trie & RIGHTPATH) { + /* Right node after this node */ + node = (*trie & TRIENODE); + trie++; + } else { + /* No right node. */ + node = 0; + trie = NULL; + } + } else { + /* Left leg */ + if (offlen) { + /* Left node after this node. */ + node = (*trie & LEFTNODE); + trie += offlen + 1; + } else if (*trie & RIGHTPATH) { + /* No left node. */ + node = 0; + trie = NULL; + } else { + /* Left node after this node */ + node = (*trie & TRIENODE); + trie++; + } + } + } + return trie; +} + +/* + * Use trie to scan s. + * Returns the leaf if one exists, NULL otherwise. + * + * Forwards to trie_nlookup(). + */ +static utf8leaf_t * +utf8lookup(struct tree *tree, const char *s) +{ + return utf8nlookup(tree, s, (size_t)-1); +} + +/* + * Return the number of bytes used by the current UTF-8 sequence. + * Assumes the input points to the first byte of a valid UTF-8 + * sequence. + */ +static inline int +utf8clen(const char *s) +{ + unsigned char c = *s; + return 1 + (c >= 0xC0) + (c >= 0xE0) + (c >= 0xF0); +} + +/* + * Maximum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if only non-assigned code points are used. + */ +int +utf8agemax(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age > age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Minimum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if non-assigned code points are used. + */ +int +utf8agemin(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + int age = tree->maxage; + int leaf_age; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age < age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemax(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age > age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemin(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int leaf_age; + int age = tree->maxage; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age < age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Length of the normalization of s. + * Return -1 if s is not valid UTF-8 unicode. + * + * A string of Default_Ignorable_Code_Point has length 0. + */ +ssize_t +utf8len(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + if (ages[LEAF_GEN(leaf)] > tree->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Length of the normalization of s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +ssize_t +utf8nlen(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + if (ages[LEAF_GEN(leaf)] > tree->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + len -= utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Cursor structure used by the normalizer. + */ +struct utf8cursor { + struct tree *tree; + const char *s; + const char *p; + const char *ss; + const char *sp; + unsigned int len; + unsigned int slen; + short int ccc; + short int nccc; + unsigned int unichar; +}; + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * s : string. + * len : length of s. + * u8c : pointer to cursor. + * trie : utf8trie_t to use for normalization. + * + * Returns -1 on error, 0 on success. + */ +int +utf8ncursor( + struct utf8cursor *u8c, + struct tree *tree, + const char *s, + size_t len) +{ + if (!tree) + return -1; + if (!s) + return -1; + u8c->tree = tree; + u8c->s = s; + u8c->p = NULL; + u8c->ss = NULL; + u8c->sp = NULL; + u8c->len = len; + u8c->slen = 0; + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->unichar = 0; + /* Check we didn't clobber the maximum length. */ + if (u8c->len != len) + return -1; + /* The first byte of s may not be an utf8 continuation. */ + if (len > 0 && (*s & 0xC0) == 0x80) + return -1; + return 0; +} + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * s : NUL-terminated string. + * u8c : pointer to cursor. + * trie : utf8trie_t to use for normalization. + * + * Returns -1 on error, 0 on success. + */ +int +utf8cursor( + struct utf8cursor *u8c, + struct tree *tree, + const char *s) +{ + return utf8ncursor(u8c, tree, s, (unsigned int)-1); +} + +/* + * Get one byte from the normalized form of the string described by u8c. + * + * Returns the byte cast to an unsigned char on succes, and -1 on failure. + * + * The cursor keeps track of the location in the string in u8c->s. + * When a character is decomposed, the current location is stored in + * u8c->p, and u8c->s is set to the start of the decomposition. Note + * that bytes from a decomposition do not count against u8c->len. + * + * Characters are emitted if they match the current CCC in u8c->ccc. + * Hitting end-of-string while u8c->ccc == STOPPER means we're done, + * and the function returns 0 in that case. + * + * Sorting by CCC is done by repeatedly scanning the string. The + * values of u8c->s and u8c->p are stored in u8c->ss and u8c->sp at + * the start of the scan. The first pass finds the lowest CCC to be + * emitted and stores it in u8c->nccc, the second pass emits the + * characters with this CCC and finds the next lowest CCC. This limits + * the number of passes to 1 + the number of different CCCs in the + * sequence being scanned. + * + * Therefore: + * u8c->p != NULL -> a decomposition is being scanned. + * u8c->ss != NULL -> this is a repeating scan. + * u8c->ccc == -1 -> this is the first scan of a repeating scan. + */ +int +utf8byte(struct utf8cursor *u8c) +{ + utf8leaf_t *leaf; + int ccc; + + for (;;) { + /* Check for the end of a decomposed character. */ + if (u8c->p && *u8c->s == '\0') { + u8c->s = u8c->p; + u8c->p = NULL; + } + + /* Check for end-of-string. */ + if (!u8c->p && (u8c->len == 0 || *u8c->s == '\0')) { + /* There is no next byte. */ + if (u8c->ccc == STOPPER) + return 0; + /* End-of-string during a scan counts as a stopper. */ + ccc = STOPPER; + goto ccc_mismatch; + } else if ((*u8c->s & 0xC0) == 0x80) { + /* This is a continuation of the current character. */ + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Look up the data for the current character. */ + if (u8c->p) + leaf = utf8lookup(u8c->tree, u8c->s); + else + leaf = utf8nlookup(u8c->tree, u8c->s, u8c->len); + + /* No leaf found implies that the input is a binary blob. */ + if (!leaf) + return -1; + + /* Characters that are too new have CCC 0. */ + if (ages[LEAF_GEN(leaf)] > u8c->tree->maxage) { + ccc = STOPPER; + } else if ((ccc = LEAF_CCC(leaf)) == DECOMPOSE) { + u8c->len -= utf8clen(u8c->s); + u8c->p = u8c->s + utf8clen(u8c->s); + u8c->s = LEAF_STR(leaf); + /* Empty decomposition implies CCC 0. */ + if (*u8c->s == '\0') { + if (u8c->ccc == STOPPER) + continue; + ccc = STOPPER; + goto ccc_mismatch; + } + leaf = utf8lookup(u8c->tree, u8c->s); + ccc = LEAF_CCC(leaf); + } + u8c->unichar = utf8code(u8c->s); + + /* + * If this is not a stopper, then see if it updates + * the next canonical class to be emitted. + */ + if (ccc != STOPPER && u8c->ccc < ccc && ccc < u8c->nccc) + u8c->nccc = ccc; + + /* + * Return the current byte if this is the current + * combining class. + */ + if (ccc == u8c->ccc) { + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Current combining class mismatch. */ + ccc_mismatch: + if (u8c->nccc == STOPPER) { + /* + * Scan forward for the first canonical class + * to be emitted. Save the position from + * which to restart. + */ + assert(u8c->ccc == STOPPER); + u8c->ccc = MINCCC - 1; + u8c->nccc = ccc; + u8c->sp = u8c->p; + u8c->ss = u8c->s; + u8c->slen = u8c->len; + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (ccc != STOPPER) { + /* Not a stopper, and not the ccc we're emitting. */ + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (u8c->nccc != MAXCCC + 1) { + /* At a stopper, restart for next ccc. */ + u8c->ccc = u8c->nccc; + u8c->nccc = MAXCCC + 1; + u8c->s = u8c->ss; + u8c->p = u8c->sp; + u8c->len = u8c->slen; + } else { + /* All done, proceed from here. */ + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->sp = NULL; + u8c->ss = NULL; + u8c->slen = 0; + } + } +} + +/* ------------------------------------------------------------------ */ + +static int +normalize_line(struct tree *tree) +{ + char *s; + char *t; + int c; + struct utf8cursor u8c; + + /* First test: null-terminated string. */ + s = buf2; + t = buf3; + if (utf8cursor(&u8c, tree, s)) + return -1; + while ((c = utf8byte(&u8c)) > 0) + if (c != (unsigned char)*t++) + return -1; + if (c < 0) + return -1; + if (*t != 0) + return -1; + + /* Second test: length-limited string. */ + s = buf2; + /* Replace NUL with a value that will cause an error if seen. */ + s[strlen(s) + 1] = -1; + t = buf3; + if (utf8cursor(&u8c, tree, s)) + return -1; + while ((c = utf8byte(&u8c)) > 0) + if (c != (unsigned char)*t++) + return -1; + if (c < 0) + return -1; + if (*t != 0) + return -1; + + return 0; +} + +static void +normalization_test(void) +{ + FILE *file; + unsigned int unichar; + struct unicode_data *data; + char *s; + char *t; + int ret; + int ignorables; + int tests = 0; + int failures = 0; + + if (verbose > 0) + printf("Parsing %s\n", test_name); + /* Step one, read data from file. */ + file = fopen(test_name, "r"); + if (!file) + open_fail(test_name, errno); + + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%[^;];%*[^;];%*[^;];%*[^;];%[^;];", + buf0, buf1); + if (ret != 2 || *line == '#') + continue; + s = buf0; + t = buf2; + while (*s) { + unichar = strtoul(s, &s, 16); + t += utf8key(unichar, t); + } + *t = '\0'; + + ignorables = 0; + s = buf1; + t = buf3; + while (*s) { + unichar = strtoul(s, &s, 16); + data = &unicode_data[unichar]; + if (data->utf8nfkdi && !*data->utf8nfkdi) + ignorables = 1; + else + t += utf8key(unichar, t); + } + *t = '\0'; + + tests++; + if (normalize_line(nfkdi_tree) < 0) { + printf("\nline %s -> %s", buf0, buf1); + if (ignorables) + printf(" (ignorables removed)"); + printf(" failure\n"); + failures++; + } + } + fclose(file); + if (verbose > 0) + printf("Ran %d tests with %d failures\n", tests, failures); + if (failures) + file_fail(test_name); +} + +/* ------------------------------------------------------------------ */ + +static void +write_file(void) +{ + FILE *file; + int i; + int j; + int t; + int gen; + + if (verbose > 0) + printf("Writing %s\n", utf8_name); + file = fopen(utf8_name, "w"); + if (!file) + open_fail(utf8_name, errno); + + fprintf(file, "/* This file is generated code, do not edit. */\n"); + fprintf(file, "#ifndef __INCLUDED_FROM_UTF8NORM_C__\n"); + fprintf(file, "#error Only xfs_utf8.c may include this file.\n"); + fprintf(file, "#endif\n"); + fprintf(file, "\n"); + fprintf(file, "static const unsigned int utf8vers = %#x;\n", + unicode_maxage); + fprintf(file, "\n"); + fprintf(file, "static const unsigned int utf8agetab[] = {\n"); + for (i = 0; i != ages_count; i++) + fprintf(file, "\t%#x%s\n", ages[i], + ages[i] == unicode_maxage ? "" : ","); + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const struct utf8data utf8nfkdicfdata[] = {\n"); + t = 0; + for (gen = 0; gen < ages_count; gen++) { + fprintf(file, "\t{ %#x, %d }%s\n", + ages[gen], trees[t].index, + ages[gen] == unicode_maxage ? "" : ","); + if (trees[t].maxage == ages[gen]) + t += 2; + } + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const struct utf8data utf8nfkdidata[] = {\n"); + t = 1; + for (gen = 0; gen < ages_count; gen++) { + fprintf(file, "\t{ %#x, %d }%s\n", + ages[gen], trees[t].index, + ages[gen] == unicode_maxage ? "" : ","); + if (trees[t].maxage == ages[gen]) + t += 2; + } + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const unsigned char utf8data[%zd] = {\n", + utf8data_size); + t = 0; + for (i = 0; i != utf8data_size; i += 16) { + if (i == trees[t].index) { + fprintf(file, "\t/* %s_%x */\n", + trees[t].type, trees[t].maxage); + if (t < trees_count-1) + t++; + } + fprintf(file, "\t"); + for (j = i; j != i + 16; j++) + fprintf(file, "0x%.2x%s", utf8data[j], + (j < utf8data_size -1 ? "," : "")); + fprintf(file, "\n"); + } + fprintf(file, "};\n"); + fclose(file); +} + +/* ------------------------------------------------------------------ */ + +int +main(int argc, char *argv[]) +{ + unsigned int unichar; + int opt; + + argv0 = argv[0]; + + while ((opt = getopt(argc, argv, "a:c:d:f:hn:o:p:t:v")) != -1) { + switch (opt) { + case 'a': + age_name = optarg; + break; + case 'c': + ccc_name = optarg; + break; + case 'd': + data_name = optarg; + break; + case 'f': + fold_name = optarg; + break; + case 'n': + norm_name = optarg; + break; + case 'o': + utf8_name = optarg; + break; + case 'p': + prop_name = optarg; + break; + case 't': + test_name = optarg; + break; + case 'v': + verbose++; + break; + case 'h': + help(); + exit(0); + default: + usage(); + } + } + + if (verbose > 1) + help(); + for (unichar = 0; unichar != 0x110000; unichar++) + unicode_data[unichar].code = unichar; + age_init(); + ccc_init(); + nfkdi_init(); + nfkdicf_init(); + ignore_init(); + corrections_init(); + hangul_decompose(); + nfkdi_decompose(); + nfkdicf_decompose(); + utf8_init(); + trees_init(); + trees_populate(); + trees_reduce(); + trees_verify(); + /* Prevent "unused function" warning. */ + (void)lookup(nfkdi_tree, " "); + if (verbose > 2) + tree_walk(nfkdi_tree); + if (verbose > 2) + tree_walk(nfkdicf_tree); + normalization_test(); + write_file(); + + return 0; +} -- 1.7.12.4 From bpm@sgi.com Fri Sep 19 11:04:40 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD, T_FILL_THIS_FORM_SHORT autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 216B67F52 for ; Fri, 19 Sep 2014 11:04:40 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay2.corp.sgi.com (Postfix) with ESMTP id CBF46304048; Fri, 19 Sep 2014 09:04:39 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 853714266DC; Fri, 19 Sep 2014 11:04:39 -0500 (CDT) Date: Fri, 19 Sep 2014 11:04:39 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 07b/10] xfs: add supporting code for UTF-8. Message-ID: <20140919160439.GE4482@sgi.com> References: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918195650.GI19952@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Supporting functions for UTF-8 normalization are in utf8norm.c with the header utf8norm.h. Two normalization forms are supported: nfkdi and nfkdicf. nfkdi: - Apply unicode normalization form NFKD. - Remove any Default_Ignorable_Code_Point. nfkdicf: - Apply unicode normalization form NFKD. - Remove any Default_Ignorable_Code_Point. - Apply a full casefold (C + F). For the purposes of the code, a string is valid UTF-8 if: - The values encoded are 0x1..0x10FFFF. - The surrogate codepoints 0xD800..0xDFFFF are not encoded. - The shortest possible encoding is used for all values. The supporting functions work on null-terminated strings (utf8 prefix) and on length-limited strings (utf8n prefix). Signed-off-by: Olaf Weber --- [v2: the trie is now separated into utf8norm.ko; utf8version is now a function and exported; introduced CONFIG_XFS_UTF8; removed trie generator due to vger size constraint. --bpm] --- fs/xfs/utf8norm/Makefile | 4 + fs/xfs/utf8norm/utf8norm.c | 649 +++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/utf8norm/utf8norm.h | 116 ++++++++ 3 files changed, 769 insertions(+) create mode 100644 fs/xfs/utf8norm/utf8norm.c create mode 100644 fs/xfs/utf8norm/utf8norm.h diff --git a/fs/xfs/utf8norm/Makefile b/fs/xfs/utf8norm/Makefile index 9b2efa9..f83f9b9 100644 --- a/fs/xfs/utf8norm/Makefile +++ b/fs/xfs/utf8norm/Makefile @@ -16,6 +16,10 @@ # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # +ifeq ($(CONFIG_XFS_UTF8),y) +obj-m += utf8norm.o +endif + hostprogs-y := mkutf8data $(obj)/utf8norm.o: $(obj)/utf8data.h $(obj)/utf8data.h: $(src)/ucd/*.txt diff --git a/fs/xfs/utf8norm/utf8norm.c b/fs/xfs/utf8norm/utf8norm.c new file mode 100644 index 0000000..995c4df --- /dev/null +++ b/fs/xfs/utf8norm/utf8norm.c @@ -0,0 +1,649 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "utf8norm.h" + +struct utf8data { + unsigned int maxage; + unsigned int offset; +}; + +#define __INCLUDED_FROM_UTF8NORM_C__ +#include "utf8data.h" +#undef __INCLUDED_FROM_UTF8NORM_C__ + +const unsigned int utf8version(void) +{ + return utf8vers; +} +EXPORT_SYMBOL(utf8version); + +/* + * UTF-8 valid ranges. + * + * The UTF-8 encoding spreads the bits of a 32bit word over several + * bytes. This table gives the ranges that can be held and how they'd + * be represented. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000000 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000000 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * There is an additional requirement on UTF-8, in that only the + * shortest representation of a 32bit value is to be used. A decoder + * must not decode sequences that do not satisfy this requirement. + * Thus the allowed ranges have a lower bound. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000080 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000800 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00010000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00200000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x04000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Actual unicode characters are limited to the range 0x0 - 0x10FFFF, + * 17 planes of 65536 values. This limits the sequences actually seen + * even more, to just the following. + * + * 0 - 0x7F: 0 - 0x7F + * 0x80 - 0x7FF: 0xC2 0x80 - 0xDF 0xBF + * 0x800 - 0xFFFF: 0xE0 0xA0 0x80 - 0xEF 0xBF 0xBF + * 0x10000 - 0x10FFFF: 0xF0 0x90 0x80 0x80 - 0xF4 0x8F 0xBF 0xBF + * + * Within those ranges the surrogates 0xD800 - 0xDFFF are not allowed. + * + * Note that the longest sequence seen with valid usage is 4 bytes, + * the same a single UTF-32 character. This makes the UTF-8 + * representation of Unicode strictly smaller than UTF-32. + * + * The shortest sequence requirement was introduced by: + * Corrigendum #1: UTF-8 Shortest Form + * It can be found here: + * http://www.unicode.org/versions/corrigendum1.html + * + */ + +/* + * Return the number of bytes used by the current UTF-8 sequence. + * Assumes the input points to the first byte of a valid UTF-8 + * sequence. + */ +static inline int +utf8clen(const char *s) +{ + unsigned char c = *s; + return 1 + (c >= 0xC0) + (c >= 0xE0) + (c >= 0xF0); +} + +/* + * utf8trie_t + * + * A compact binary tree, used to decode UTF-8 characters. + * + * Internal nodes are one byte for the node itself, and up to three + * bytes for an offset into the tree. The first byte contains the + * following information: + * NEXTBYTE - flag - advance to next byte if set + * BITNUM - 3 bit field - the bit number to tested + * OFFLEN - 2 bit field - number of bytes in the offset + * if offlen == 0 (non-branching node) + * RIGHTPATH - 1 bit field - set if the following node is for the + * right-hand path (tested bit is set) + * TRIENODE - 1 bit field - set if the following node is an internal + * node, otherwise it is a leaf node + * if offlen != 0 (branching node) + * LEFTNODE - 1 bit field - set if the left-hand node is internal + * RIGHTNODE - 1 bit field - set if the right-hand node is internal + * + * Due to the way utf8 works, there cannot be branching nodes with + * NEXTBYTE set, and moreover those nodes always have a righthand + * descendant. + */ +typedef const unsigned char utf8trie_t; +#define BITNUM 0x07 +#define NEXTBYTE 0x08 +#define OFFLEN 0x30 +#define OFFLEN_SHIFT 4 +#define RIGHTPATH 0x40 +#define TRIENODE 0x80 +#define RIGHTNODE 0x40 +#define LEFTNODE 0x80 + +/* + * utf8leaf_t + * + * The leaves of the trie are embedded in the trie, and so the same + * underlying datatype: unsigned char. + * + * leaf[0]: The unicode version, stored as a generation number that is + * an index into utf8agetab[]. With this we can filter code + * points based on the unicode version in which they were + * defined. The CCC of a non-defined code point is 0. + * leaf[1]: Canonical Combining Class. During normalization, we need + * to do a stable sort into ascending order of all characters + * with a non-zero CCC that occur between two characters with + * a CCC of 0, or at the begin or end of a string. + * The unicode standard guarantees that all CCC values are + * between 0 and 254 inclusive, which leaves 255 available as + * a special value. + * Code points with CCC 0 are known as stoppers. + * leaf[2]: Decomposition. If leaf[1] == 255, then leaf[2] is the + * start of a NUL-terminated string that is the decomposition + * of the character. + * The CCC of a decomposable character is the same as the CCC + * of the first character of its decomposition. + * Some characters decompose as the empty string: these are + * characters with the Default_Ignorable_Code_Point property. + * These do affect normalization, as they all have CCC 0. + * + * The decompositions in the trie have been fully expanded. + * + * Casefolding, if applicable, is also done using decompositions. + * + * The trie is constructed in such a way that leaves exist for all + * UTF-8 sequences that match the criteria from the "UTF-8 valid + * ranges" comment above, and only for those sequences. Therefore a + * lookup in the trie can be used to validate the UTF-8 input. + */ +typedef const unsigned char utf8leaf_t; + +#define LEAF_GEN(LEAF) ((LEAF)[0]) +#define LEAF_CCC(LEAF) ((LEAF)[1]) +#define LEAF_STR(LEAF) ((const char*)((LEAF) + 2)) + +#define MINCCC (0) +#define MAXCCC (254) +#define STOPPER (0) +#define DECOMPOSE (255) + +/* + * Use trie to scan s, touching at most len bytes. + * Returns the leaf if one exists, NULL otherwise. + * + * A non-NULL return guarantees that the UTF-8 sequence starting at s + * is well-formed and corresponds to a known unicode code point. The + * shorthand for this will be "is valid UTF-8 unicode". + */ +static utf8leaf_t * +utf8nlookup(utf8data_t data, const char *s, size_t len) +{ + utf8trie_t *trie = utf8data + data->offset; + int offlen; + int offset; + int mask; + int node; + + if (!data) + return NULL; + if (len == 0) + return NULL; + node = 1; + while (node) { + offlen = (*trie & OFFLEN) >> OFFLEN_SHIFT; + if (*trie & NEXTBYTE) { + if (--len == 0) + return NULL; + s++; + } + mask = 1 << (*trie & BITNUM); + if (*s & mask) { + /* Right leg */ + if (offlen) { + /* Right node at offset of trie */ + node = (*trie & RIGHTNODE); + offset = trie[offlen]; + while (--offlen) { + offset <<= 8; + offset |= trie[offlen]; + } + trie += offset; + } else if (*trie & RIGHTPATH) { + /* Right node after this node */ + node = (*trie & TRIENODE); + trie++; + } else { + /* No right node. */ + node = 0; + trie = NULL; + } + } else { + /* Left leg */ + if (offlen) { + /* Left node after this node. */ + node = (*trie & LEFTNODE); + trie += offlen + 1; + } else if (*trie & RIGHTPATH) { + /* No left node. */ + node = 0; + trie = NULL; + } else { + /* Left node after this node */ + node = (*trie & TRIENODE); + trie++; + } + } + } + return trie; +} + +/* + * Use trie to scan s. + * Returns the leaf if one exists, NULL otherwise. + * + * Forwards to utf8nlookup(). + */ +static utf8leaf_t * +utf8lookup(utf8data_t data, const char *s) +{ + return utf8nlookup(data, s, (size_t)-1); +} + +/* + * Maximum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if only non-assigned code points are used. + */ +int +utf8agemax(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!data) + return -1; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age > age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} +EXPORT_SYMBOL(utf8agemax); + +/* + * Minimum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if non-assigned code points are used. + */ +int +utf8agemin(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + int age; + int leaf_age; + + if (!data) + return -1; + age = data->maxage; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age < age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} +EXPORT_SYMBOL(utf8agemin); + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemax(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!data) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age > age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} +EXPORT_SYMBOL(utf8nagemax); + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemin(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int leaf_age; + int age; + + if (!data) + return -1; + age = data->maxage; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age < age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} +EXPORT_SYMBOL(utf8nagemin); + +/* + * Length of the normalization of s. + * Return -1 if s is not valid UTF-8 unicode. + * + * A string of Default_Ignorable_Code_Point has length 0. + */ +ssize_t +utf8len(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!data) + return -1; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + if (utf8agetab[LEAF_GEN(leaf)] > data->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + s += utf8clen(s); + } + return ret; +} +EXPORT_SYMBOL(utf8len); + +/* + * Length of the normalization of s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +ssize_t +utf8nlen(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!data) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + if (utf8agetab[LEAF_GEN(leaf)] > data->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + len -= utf8clen(s); + s += utf8clen(s); + } + return ret; +} +EXPORT_SYMBOL(utf8nlen); + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * u8c : pointer to cursor. + * data : utf8data_t to use for normalization. + * s : string. + * len : length of s. + * + * Returns -1 on error, 0 on success. + */ +int +utf8ncursor( + struct utf8cursor *u8c, + utf8data_t data, + const char *s, + size_t len) +{ + if (!data) + return -1; + if (!s) + return -1; + u8c->data = data; + u8c->s = s; + u8c->p = NULL; + u8c->ss = NULL; + u8c->sp = NULL; + u8c->len = len; + u8c->slen = 0; + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + /* Check we didn't clobber the maximum length. */ + if (u8c->len != len) + return -1; + /* The first byte of s may not be an utf8 continuation. */ + if (len > 0 && (*s & 0xC0) == 0x80) + return -1; + return 0; +} +EXPORT_SYMBOL(utf8ncursor); + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * u8c : pointer to cursor. + * data : utf8data_t to use for normalization. + * s : NUL-terminated string. + * + * Returns -1 on error, 0 on success. + */ +int +utf8cursor( + struct utf8cursor *u8c, + utf8data_t data, + const char *s) +{ + return utf8ncursor(u8c, data, s, (unsigned int)-1); +} +EXPORT_SYMBOL(utf8cursor); + +/* + * Get one byte from the normalized form of the string described by u8c. + * + * Returns the byte cast to an unsigned char on succes, and -1 on failure. + * + * The cursor keeps track of the location in the string in u8c->s. + * When a character is decomposed, the current location is stored in + * u8c->p, and u8c->s is set to the start of the decomposition. Note + * that bytes from a decomposition do not count against u8c->len. + * + * Characters are emitted if they match the current CCC in u8c->ccc. + * Hitting end-of-string while u8c->ccc == STOPPER means we're done, + * and the function returns 0 in that case. + * + * Sorting by CCC is done by repeatedly scanning the string. The + * values of u8c->s and u8c->p are stored in u8c->ss and u8c->sp at + * the start of the scan. The first pass finds the lowest CCC to be + * emitted and stores it in u8c->nccc, the second pass emits the + * characters with this CCC and finds the next lowest CCC. This limits + * the number of passes to 1 + the number of different CCCs in the + * sequence being scanned. + * + * Therefore: + * u8c->p != NULL -> a decomposition is being scanned. + * u8c->ss != NULL -> this is a repeating scan. + * u8c->ccc == -1 -> this is the first scan of a repeating scan. + */ +int +utf8byte(struct utf8cursor *u8c) +{ + utf8leaf_t *leaf; + int ccc; + + for (;;) { + /* Check for the end of a decomposed character. */ + if (u8c->p && *u8c->s == '\0') { + u8c->s = u8c->p; + u8c->p = NULL; + } + + /* Check for end-of-string. */ + if (!u8c->p && (u8c->len == 0 || *u8c->s == '\0')) { + /* There is no next byte. */ + if (u8c->ccc == STOPPER) + return 0; + /* End-of-string during a scan counts as a stopper. */ + ccc = STOPPER; + goto ccc_mismatch; + } else if ((*u8c->s & 0xC0) == 0x80) { + /* This is a continuation of the current character. */ + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Look up the data for the current character. */ + if (u8c->p) + leaf = utf8lookup(u8c->data, u8c->s); + else + leaf = utf8nlookup(u8c->data, u8c->s, u8c->len); + + /* No leaf found implies that the input is a binary blob. */ + if (!leaf) + return -1; + + /* Characters that are too new have CCC 0. */ + if (utf8agetab[LEAF_GEN(leaf)] > u8c->data->maxage) { + ccc = STOPPER; + } else if ((ccc = LEAF_CCC(leaf)) == DECOMPOSE) { + u8c->len -= utf8clen(u8c->s); + u8c->p = u8c->s + utf8clen(u8c->s); + u8c->s = LEAF_STR(leaf); + /* Empty decomposition implies CCC 0. */ + if (*u8c->s == '\0') { + if (u8c->ccc == STOPPER) + continue; + ccc = STOPPER; + goto ccc_mismatch; + } + leaf = utf8lookup(u8c->data, u8c->s); + ccc = LEAF_CCC(leaf); + } + + /* + * If this is not a stopper, then see if it updates + * the next canonical class to be emitted. + */ + if (ccc != STOPPER && u8c->ccc < ccc && ccc < u8c->nccc) + u8c->nccc = ccc; + + /* + * Return the current byte if this is the current + * combining class. + */ + if (ccc == u8c->ccc) { + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Current combining class mismatch. */ + ccc_mismatch: + if (u8c->nccc == STOPPER) { + /* + * Scan forward for the first canonical class + * to be emitted. Save the position from + * which to restart. + */ + u8c->ccc = MINCCC - 1; + u8c->nccc = ccc; + u8c->sp = u8c->p; + u8c->ss = u8c->s; + u8c->slen = u8c->len; + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (ccc != STOPPER) { + /* Not a stopper, and not the ccc we're emitting. */ + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (u8c->nccc != MAXCCC + 1) { + /* At a stopper, restart for next ccc. */ + u8c->ccc = u8c->nccc; + u8c->nccc = MAXCCC + 1; + u8c->s = u8c->ss; + u8c->p = u8c->sp; + u8c->len = u8c->slen; + } else { + /* All done, proceed from here. */ + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->sp = NULL; + u8c->ss = NULL; + u8c->slen = 0; + } + } +} +EXPORT_SYMBOL(utf8byte); + +const struct utf8data * +utf8nfkdi(unsigned int maxage) +{ + int i = sizeof(utf8nfkdidata)/sizeof(utf8nfkdidata[0]) - 1; + + while (maxage < utf8nfkdidata[i].maxage) + i--; + if (maxage > utf8nfkdidata[i].maxage) + return NULL; + return &utf8nfkdidata[i]; +} +EXPORT_SYMBOL(utf8nfkdi); + +const struct utf8data * +utf8nfkdicf(unsigned int maxage) +{ + int i = sizeof(utf8nfkdicfdata)/sizeof(utf8nfkdicfdata[0]) - 1; + + while (maxage < utf8nfkdicfdata[i].maxage) + i--; + if (maxage > utf8nfkdicfdata[i].maxage) + return NULL; + return &utf8nfkdicfdata[i]; +} +EXPORT_SYMBOL(utf8nfkdicf); + +MODULE_AUTHOR("SGI"); +MODULE_DESCRIPTION("utf8 normalization"); +MODULE_LICENSE("GPL"); diff --git a/fs/xfs/utf8norm/utf8norm.h b/fs/xfs/utf8norm/utf8norm.h new file mode 100644 index 0000000..44a9e53 --- /dev/null +++ b/fs/xfs/utf8norm/utf8norm.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef UTF8NORM_H +#define UTF8NORM_H + +#include +#include +#include +#include + +/* An opaque type used to determine the normalization in use. */ +typedef const struct utf8data *utf8data_t; + +/* Encoding a unicode version number as a single unsigned int. */ +#define UNICODE_MAJ_SHIFT (16) +#define UNICODE_MIN_SHIFT (8) + +#define UNICODE_AGE(MAJ,MIN,REV) \ + (((unsigned int)(MAJ) << UNICODE_MAJ_SHIFT) | \ + ((unsigned int)(MIN) << UNICODE_MIN_SHIFT) | \ + ((unsigned int)(REV))) + +/* Highest unicode version supported by the data tables. */ +extern const unsigned int utf8version(void); + +/* + * Look for the correct utf8data_t for a unicode version. + * Returns NULL if the version requested is too new. + * + * Two normalization forms are supported: nfkdi and nfkdicf. + * + * nfkdi: + * - Apply unicode normalization form NFKD. + * - Remove any Default_Ignorable_Code_Point. + * + * nfkdicf: + * - Apply unicode normalization form NFKD. + * - Remove any Default_Ignorable_Code_Point. + * - Apply a full casefold (C + F). + */ +extern utf8data_t utf8nfkdi(unsigned int); +extern utf8data_t utf8nfkdicf(unsigned int); + +/* + * Determine the maximum age of any unicode character in the string. + * Returns 0 if only unassigned code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern int utf8agemax(utf8data_t, const char *); +extern int utf8nagemax(utf8data_t, const char *, size_t); + +/* + * Determine the minimum age of any unicode character in the string. + * Returns 0 if any unassigned code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern int utf8agemin(utf8data_t, const char *); +extern int utf8nagemin(utf8data_t, const char *, size_t); + +/* + * Determine the length of the normalized from of the string, + * excluding any terminating NULL byte. + * Returns 0 if only ignorable code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern ssize_t utf8len(utf8data_t, const char *); +extern ssize_t utf8nlen(utf8data_t, const char *, size_t); + +/* + * Cursor structure used by the normalizer. + */ +struct utf8cursor { + utf8data_t data; + const char *s; + const char *p; + const char *ss; + const char *sp; + unsigned int len; + unsigned int slen; + short int ccc; + short int nccc; +}; + +/* + * Initialize a utf8cursor to normalize a string. + * Returns 0 on success. + * Returns -1 on failure. + */ +extern int utf8cursor(struct utf8cursor *, utf8data_t, const char *); +extern int utf8ncursor(struct utf8cursor *, utf8data_t, const char *, size_t); + +/* + * Get the next byte in the normalization. + * Returns a value > 0 && < 256 on success. + * Returns 0 when the end of the normalization is reached. + * Returns -1 if the string being normalized is not valid UTF-8. + */ +extern int utf8byte(struct utf8cursor *); + +#endif /* UTF8NORM_H */ -- 1.7.12.4 From bpm@sgi.com Fri Sep 19 11:06:13 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD, T_FILL_THIS_FORM_SHORT autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 2473929DF9 for ; Fri, 19 Sep 2014 11:06:13 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay2.corp.sgi.com (Postfix) with ESMTP id C606E304043; Fri, 19 Sep 2014 09:06:12 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 20ADA4266DC; Fri, 19 Sep 2014 11:06:12 -0500 (CDT) Date: Fri, 19 Sep 2014 11:06:12 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 07a/13] xfsprogs: add trie generator for UTF-8. Message-ID: <20140919160612.GF4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918203114.GN4482@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber mkutf8data.c is the source for a program that generates utf8data.h, which contains the trie that utf8norm.c uses. The trie is generated from the Unicode 7.0.0 data files. The format of the utf8data[] table is described in utf8norm.c, which is added in the next patch. Signed-off-by: Olaf Weber --- Makefile | 2 +- support/Makefile | 24 + support/mkutf8data.c | 3232 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 3257 insertions(+), 1 deletion(-) create mode 100644 support/Makefile create mode 100644 support/mkutf8data.c diff --git a/Makefile b/Makefile index f56aebd..c442da6 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ LDIRDIRT = $(SRCDIR) LDIRT += $(SRCTAR) endif -LIB_SUBDIRS = libxfs libxlog libxcmd libhandle libdisk +LIB_SUBDIRS = support libxfs libxlog libxcmd libhandle libdisk TOOL_SUBDIRS = copy db estimate fsck fsr growfs io logprint mkfs quota \ mdrestore repair rtcp m4 man doc po debian diff --git a/support/Makefile b/support/Makefile new file mode 100644 index 0000000..cade5fe --- /dev/null +++ b/support/Makefile @@ -0,0 +1,24 @@ +# +# Copyright (c) 2014 SGI. All Rights Reserved. +# + +TOPDIR = .. +include $(TOPDIR)/include/builddefs + +default = ../include/utf8data.h + +../include/utf8data.h: mkutf8data.c + cc -o mkutf8data mkutf8data.c + cd ucd-7.0.0 ; ../mkutf8data + mv ucd-7.0.0/utf8data.h ../include + +default clean: + rm -f mkutf8data ../include/utf8data.h + +default install: + +default install-dev: + +default install-qa: + +-include .ltdep diff --git a/support/mkutf8data.c b/support/mkutf8data.c new file mode 100644 index 0000000..e5c3507 --- /dev/null +++ b/support/mkutf8data.c @@ -0,0 +1,3232 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Generator for a compact trie for unicode normalization */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Default names of the in- and output files. */ + +#define AGE_NAME "DerivedAge.txt" +#define CCC_NAME "DerivedCombiningClass.txt" +#define PROP_NAME "DerivedCoreProperties.txt" +#define DATA_NAME "UnicodeData.txt" +#define FOLD_NAME "CaseFolding.txt" +#define NORM_NAME "NormalizationCorrections.txt" +#define TEST_NAME "NormalizationTest.txt" +#define UTF8_NAME "utf8data.h" + +const char *age_name = AGE_NAME; +const char *ccc_name = CCC_NAME; +const char *prop_name = PROP_NAME; +const char *data_name = DATA_NAME; +const char *fold_name = FOLD_NAME; +const char *norm_name = NORM_NAME; +const char *test_name = TEST_NAME; +const char *utf8_name = UTF8_NAME; + +int verbose = 0; + +/* An arbitrary line size limit on input lines. */ + +#define LINESIZE 1024 +char line[LINESIZE]; +char buf0[LINESIZE]; +char buf1[LINESIZE]; +char buf2[LINESIZE]; +char buf3[LINESIZE]; + +const char *argv0; + +/* ------------------------------------------------------------------ */ + +/* + * Unicode version numbers consist of three parts: major, minor, and a + * revision. These numbers are packed into an unsigned int to obtain + * a single version number. + * + * To save space in the generated trie, the unicode version is not + * stored directly, instead we calculate a generation number from the + * unicode versions seen in the DerivedAge file, and use that as an + * index into a table of unicode versions. + */ +#define UNICODE_MAJ_SHIFT (16) +#define UNICODE_MIN_SHIFT (8) + +#define UNICODE_MAJ_MAX ((unsigned short)-1) +#define UNICODE_MIN_MAX ((unsigned char)-1) +#define UNICODE_REV_MAX ((unsigned char)-1) + +#define UNICODE_AGE(MAJ,MIN,REV) \ + (((unsigned int)(MAJ) << UNICODE_MAJ_SHIFT) | \ + ((unsigned int)(MIN) << UNICODE_MIN_SHIFT) | \ + ((unsigned int)(REV))) + +unsigned int *ages; +int ages_count; + +unsigned int unicode_maxage; + +static int +age_valid(unsigned int major, unsigned int minor, unsigned int revision) +{ + if (major > UNICODE_MAJ_MAX) + return 0; + if (minor > UNICODE_MIN_MAX) + return 0; + if (revision > UNICODE_REV_MAX) + return 0; + return 1; +} + +/* ------------------------------------------------------------------ */ + +/* + * utf8trie_t + * + * A compact binary tree, used to decode UTF-8 characters. + * + * Internal nodes are one byte for the node itself, and up to three + * bytes for an offset into the tree. The first byte contains the + * following information: + * NEXTBYTE - flag - advance to next byte if set + * BITNUM - 3 bit field - the bit number to tested + * OFFLEN - 2 bit field - number of bytes in the offset + * if offlen == 0 (non-branching node) + * RIGHTPATH - 1 bit field - set if the following node is for the + * right-hand path (tested bit is set) + * TRIENODE - 1 bit field - set if the following node is an internal + * node, otherwise it is a leaf node + * if offlen != 0 (branching node) + * LEFTNODE - 1 bit field - set if the left-hand node is internal + * RIGHTNODE - 1 bit field - set if the right-hand node is internal + * + * Due to the way utf8 works, there cannot be branching nodes with + * NEXTBYTE set, and moreover those nodes always have a righthand + * descendant. + */ +typedef unsigned char utf8trie_t; +#define BITNUM 0x07 +#define NEXTBYTE 0x08 +#define OFFLEN 0x30 +#define OFFLEN_SHIFT 4 +#define RIGHTPATH 0x40 +#define TRIENODE 0x80 +#define RIGHTNODE 0x40 +#define LEFTNODE 0x80 + +/* + * utf8leaf_t + * + * The leaves of the trie are embedded in the trie, and so the same + * underlying datatype, unsigned char. + * + * leaf[0]: The unicode version, stored as a generation number that is + * an index into utf8agetab[]. With this we can filter code + * points based on the unicode version in which they were + * defined. The CCC of a non-defined code point is 0. + * leaf[1]: Canonical Combining Class. During normalization, we need + * to do a stable sort into ascending order of all characters + * with a non-zero CCC that occur between two characters with + * a CCC of 0, or at the begin or end of a string. + * The unicode standard guarantees that all CCC values are + * between 0 and 254 inclusive, which leaves 255 available as + * a special value. + * Code points with CCC 0 are known as stoppers. + * leaf[2]: Decomposition. If leaf[1] == 255, then leaf[2] is the + * start of a NUL-terminated string that is the decomposition + * of the character. + * The CCC of a decomposable character is the same as the CCC + * of the first character of its decomposition. + * Some characters decompose as the empty string: these are + * characters with the Default_Ignorable_Code_Point property. + * These do affect normalization, as they all have CCC 0. + * + * The decompositions in the trie have been fully expanded. + * + * Casefolding, if applicable, is also done using decompositions. + */ +typedef unsigned char utf8leaf_t; + +#define LEAF_GEN(LEAF) ((LEAF)[0]) +#define LEAF_CCC(LEAF) ((LEAF)[1]) +#define LEAF_STR(LEAF) ((const char*)((LEAF) + 2)) + +#define MAXGEN (255) + +#define MINCCC (0) +#define MAXCCC (254) +#define STOPPER (0) +#define DECOMPOSE (255) + +struct tree; +static utf8leaf_t *utf8nlookup(struct tree *, const char *, size_t); +static utf8leaf_t *utf8lookup(struct tree *, const char *); + +unsigned char *utf8data; +size_t utf8data_size; + +utf8trie_t *nfkdi; +utf8trie_t *nfkdicf; + +/* ------------------------------------------------------------------ */ + +/* + * UTF8 valid ranges. + * + * The UTF-8 encoding spreads the bits of a 32bit word over several + * bytes. This table gives the ranges that can be held and how they'd + * be represented. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000000 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000000 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * There is an additional requirement on UTF-8, in that only the + * shortest representation of a 32bit value is to be used. A decoder + * must not decode sequences that do not satisfy this requirement. + * Thus the allowed ranges have a lower bound. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000080 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000800 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00010000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00200000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x04000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Actual unicode characters are limited to the range 0x0 - 0x10FFFF, + * 17 planes of 65536 values. This limits the sequences actually seen + * even more, to just the following. + * + * 0 - 0x7f: 0 0x7f + * 0x80 - 0x7ff: 0xc2 0x80 0xdf 0xbf + * 0x800 - 0xffff: 0xe0 0xa0 0x80 0xef 0xbf 0xbf + * 0x10000 - 0x10ffff: 0xf0 0x90 0x80 0x80 0xf4 0x8f 0xbf 0xbf + * + * Even within those ranges not all values are allowed: the surrogates + * 0xd800 - 0xdfff should never be seen. + * + * Note that the longest sequence seen with valid usage is 4 bytes, + * the same a single UTF-32 character. This makes the UTF-8 + * representation of Unicode strictly smaller than UTF-32. + * + * The shortest sequence requirement was introduced by: + * Corrigendum #1: UTF-8 Shortest Form + * It can be found here: + * http://www.unicode.org/versions/corrigendum1.html + * + */ + +#define UTF8_2_BITS 0xC0 +#define UTF8_3_BITS 0xE0 +#define UTF8_4_BITS 0xF0 +#define UTF8_N_BITS 0x80 +#define UTF8_2_MASK 0xE0 +#define UTF8_3_MASK 0xF0 +#define UTF8_4_MASK 0xF8 +#define UTF8_N_MASK 0xC0 +#define UTF8_V_MASK 0x3F +#define UTF8_V_SHIFT 6 + +static int +utf8key(unsigned int key, char keyval[]) +{ + int keylen; + + if (key < 0x80) { + keyval[0] = key; + keylen = 1; + } else if (key < 0x800) { + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_2_BITS; + keylen = 2; + } else if (key < 0x10000) { + keyval[2] = key & UTF8_V_MASK; + keyval[2] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_3_BITS; + keylen = 3; + } else if (key < 0x110000) { + keyval[3] = key & UTF8_V_MASK; + keyval[3] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[2] = key & UTF8_V_MASK; + keyval[2] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[1] = key & UTF8_V_MASK; + keyval[1] |= UTF8_N_BITS; + key >>= UTF8_V_SHIFT; + keyval[0] = key; + keyval[0] |= UTF8_4_BITS; + keylen = 4; + } else { + printf("%#x: illegal key\n", key); + keylen = 0; + } + return keylen; +} + +static unsigned int +utf8code(const char *str) +{ + const unsigned char *s = (const unsigned char*)str; + unsigned int unichar = 0; + + if (*s < 0x80) { + unichar = *s; + } else if (*s < UTF8_3_BITS) { + unichar = *s++ & 0x1F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } else if (*s < UTF8_4_BITS) { + unichar = *s++ & 0x0F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } else { + unichar = *s++ & 0x0F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s++ & 0x3F; + unichar <<= UTF8_V_SHIFT; + unichar |= *s & 0x3F; + } + return unichar; +} + +static int +utf32valid(unsigned int unichar) +{ + return unichar < 0x110000; +} + +#define NODE 1 +#define LEAF 0 + +struct tree { + void *root; + int childnode; + const char *type; + unsigned int maxage; + struct tree *next; + int (*leaf_equal)(void *, void *); + void (*leaf_print)(void *, int); + int (*leaf_mark)(void *); + int (*leaf_size)(void *); + int *(*leaf_index)(struct tree *, void *); + unsigned char *(*leaf_emit)(void *, unsigned char *); + int leafindex[0x110000]; + int index; +}; + +struct node { + int index; + int offset; + int mark; + int size; + struct node *parent; + void *left; + void *right; + unsigned char bitnum; + unsigned char nextbyte; + unsigned char leftnode; + unsigned char rightnode; + unsigned int keybits; + unsigned int keymask; +}; + +/* + * Example lookup function for a tree. + */ +static void * +lookup(struct tree *tree, const char *key) +{ + struct node *node; + void *leaf = NULL; + + node = tree->root; + while (!leaf && node) { + if (node->nextbyte) + key++; + if (*key & (1 << (node->bitnum & 7))) { + /* Right leg */ + if (node->rightnode == NODE) { + node = node->right; + } else if (node->rightnode == LEAF) { + leaf = node->right; + } else { + node = NULL; + } + } else { + /* Left leg */ + if (node->leftnode == NODE) { + node = node->left; + } else if (node->leftnode == LEAF) { + leaf = node->left; + } else { + node = NULL; + } + } + } + + return leaf; +} + +/* + * A simple non-recursive tree walker: keep track of visits to the + * left and right branches in the leftmask and rightmask. + */ +static void +tree_walk(struct tree *tree) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int indent = 1; + int nodes, singletons, leaves; + + nodes = singletons = leaves = 0; + + printf("%s_%x root %p\n", tree->type, tree->maxage, tree->root); + if (tree->childnode == LEAF) { + assert(tree->root); + tree->leaf_print(tree->root, indent); + leaves = 1; + } else { + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + printf("%*snode @ %p bitnum %d nextbyte %d" + " left %p right %p mask %x bits %x\n", + indent, "", node, + node->bitnum, node->nextbyte, + node->left, node->right, + node->keymask, node->keybits); + nodes += 1; + if (!(node->left && node->right)) + singletons += 1; + + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + tree->leaf_print(node->left, + indent+1); + leaves += 1; + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + tree->leaf_print(node->right, + indent+1); + leaves += 1; + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } + } + printf("nodes %d leaves %d singletons %d\n", + nodes, leaves, singletons); +} + +/* + * Allocate an initialize a new internal node. + */ +static struct node * +alloc_node(struct node *parent) +{ + struct node *node; + int bitnum; + + node = malloc(sizeof(*node)); + node->left = node->right = NULL; + node->parent = parent; + node->leftnode = NODE; + node->rightnode = NODE; + node->keybits = 0; + node->keymask = 0; + node->mark = 0; + node->index = 0; + node->offset = -1; + node->size = 4; + + if (node->parent) { + bitnum = parent->bitnum; + if ((bitnum & 7) == 0) { + node->bitnum = bitnum + 7 + 8; + node->nextbyte = 1; + } else { + node->bitnum = bitnum - 1; + node->nextbyte = 0; + } + } else { + node->bitnum = 7; + node->nextbyte = 0; + } + + return node; +} + +/* + * Insert a new leaf into the tree, and collapse any subtrees that are + * fully populated and end in identical leaves. A nextbyte tagged + * internal node will not be removed to preserve the tree's integrity. + * Note that due to the structure of utf8, no nextbyte tagged node + * will be a candidate for removal. + */ +static int +insert(struct tree *tree, char *key, int keylen, void *leaf) +{ + struct node *node; + struct node *parent; + void **cursor; + int keybits; + + assert(keylen >= 1 && keylen <= 4); + + node = NULL; + cursor = &tree->root; + keybits = 8 * keylen; + + /* Insert, creating path along the way. */ + while (keybits) { + if (!*cursor) + *cursor = alloc_node(node); + node = *cursor; + if (node->nextbyte) + key++; + if (*key & (1 << (node->bitnum & 7))) + cursor = &node->right; + else + cursor = &node->left; + keybits--; + } + *cursor = leaf; + + /* Merge subtrees if possible. */ + while (node) { + if (*key & (1 << (node->bitnum & 7))) + node->rightnode = LEAF; + else + node->leftnode = LEAF; + if (node->nextbyte) + break; + if (node->leftnode == NODE || node->rightnode == NODE) + break; + assert(node->left); + assert(node->right); + /* Compare */ + if (! tree->leaf_equal(node->left, node->right)) + break; + /* Keep left, drop right leaf. */ + leaf = node->left; + /* Check in parent */ + parent = node->parent; + if (!parent) { + /* root of tree! */ + tree->root = leaf; + tree->childnode = LEAF; + } else if (parent->left == node) { + parent->left = leaf; + parent->leftnode = LEAF; + if (parent->right) { + parent->keymask = 0; + parent->keybits = 0; + } else { + parent->keymask |= (1 << node->bitnum); + } + } else if (parent->right == node) { + parent->right = leaf; + parent->rightnode = LEAF; + if (parent->left) { + parent->keymask = 0; + parent->keybits = 0; + } else { + parent->keymask |= (1 << node->bitnum); + parent->keybits |= (1 << node->bitnum); + } + } else { + /* internal tree error */ + assert(0); + } + free(node); + node = parent; + } + + /* Propagate keymasks up along singleton chains. */ + while (node) { + parent = node->parent; + if (!parent) + break; + /* Nix the mask for parents with two children. */ + if (node->keymask == 0) { + parent->keymask = 0; + parent->keybits = 0; + } else if (parent->left && parent->right) { + parent->keymask = 0; + parent->keybits = 0; + } else { + assert((parent->keymask & node->keymask) == 0); + parent->keymask |= node->keymask; + parent->keymask |= (1 << parent->bitnum); + parent->keybits |= node->keybits; + if (parent->right) + parent->keybits |= (1 << parent->bitnum); + } + node = parent; + } + + return 0; +} + +/* + * Prune internal nodes. + * + * Fully populated subtrees that end at the same leaf have already + * been collapsed. There are still internal nodes that have for both + * their left and right branches a sequence of singletons that make + * identical choices and end in identical leaves. The keymask and + * keybits collected in the nodes describe the choices made in these + * singleton chains. When they are identical for the left and right + * branch of a node, and the two leaves comare identical, the node in + * question can be removed. + * + * Note that nodes with the nextbyte tag set will not be removed by + * this to ensure tree integrity. Note as well that the structure of + * utf8 ensures that these nodes would not have been candidates for + * removal in any case. + */ +static void +prune(struct tree *tree) +{ + struct node *node; + struct node *left; + struct node *right; + struct node *parent; + void *leftleaf; + void *rightleaf; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int count; + + if (verbose > 0) + printf("Pruning %s_%x\n", tree->type, tree->maxage); + + count = 0; + if (tree->childnode == LEAF) + return; + if (!tree->root) + return; + + leftmask = rightmask = 0; + node = tree->root; + while (node) { + if (node->nextbyte) + goto advance; + if (node->leftnode == LEAF) + goto advance; + if (node->rightnode == LEAF) + goto advance; + if (!node->left) + goto advance; + if (!node->right) + goto advance; + left = node->left; + right = node->right; + if (left->keymask == 0) + goto advance; + if (right->keymask == 0) + goto advance; + if (left->keymask != right->keymask) + goto advance; + if (left->keybits != right->keybits) + goto advance; + leftleaf = NULL; + while (!leftleaf) { + assert(left->left || left->right); + if (left->leftnode == LEAF) + leftleaf = left->left; + else if (left->rightnode == LEAF) + leftleaf = left->right; + else if (left->left) + left = left->left; + else if (left->right) + left = left->right; + else + assert(0); + } + rightleaf = NULL; + while (!rightleaf) { + assert(right->left || right->right); + if (right->leftnode == LEAF) + rightleaf = right->left; + else if (right->rightnode == LEAF) + rightleaf = right->right; + else if (right->left) + right = right->left; + else if (right->right) + right = right->right; + else + assert(0); + } + if (! tree->leaf_equal(leftleaf, rightleaf)) + goto advance; + /* + * This node has identical singleton-only subtrees. + * Remove it. + */ + parent = node->parent; + left = node->left; + right = node->right; + if (parent->left == node) + parent->left = left; + else if (parent->right == node) + parent->right = left; + else + assert(0); + left->parent = parent; + left->keymask |= (1 << node->bitnum); + node->left = NULL; + while (node) { + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + if (node->leftnode == NODE && node->left) { + left = node->left; + free(node); + count++; + node = left; + } else if (node->rightnode == NODE && node->right) { + right = node->right; + free(node); + count++; + node = right; + } else { + node = NULL; + } + } + /* Propagate keymasks up along singleton chains. */ + node = parent; + /* Force re-check */ + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + for (;;) { + if (node->left && node->right) + break; + if (node->left) { + left = node->left; + node->keymask |= left->keymask; + node->keybits |= left->keybits; + } + if (node->right) { + right = node->right; + node->keymask |= right->keymask; + node->keybits |= right->keybits; + } + node->keymask |= (1 << node->bitnum); + node = node->parent; + /* Force re-check */ + bitmask = 1 << node->bitnum; + leftmask &= ~bitmask; + rightmask &= ~bitmask; + } + advance: + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0 && + node->leftnode == NODE && + node->left) { + leftmask |= bitmask; + node = node->left; + } else if ((rightmask & bitmask) == 0 && + node->rightnode == NODE && + node->right) { + rightmask |= bitmask; + node = node->right; + } else { + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } + } + if (verbose > 0) + printf("Pruned %d nodes\n", count); +} + +/* + * Mark the nodes in the tree that lead to leaves that must be + * emitted. + */ +static void +mark_nodes(struct tree *tree) +{ + struct node *node; + struct node *n; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int marked; + + marked = 0; + if (verbose > 0) + printf("Marking %s_%x\n", tree->type, tree->maxage); + if (tree->childnode == LEAF) + goto done; + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + if (tree->leaf_mark(node->left)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->left) { + assert(node->leftnode == NODE); + node = node->left; + continue; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + if (tree->leaf_mark(node->right)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->right) { + assert(node->rightnode==NODE); + node = node->right; + continue; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } + + /* second pass: left siblings and singletons */ + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + bitmask = 1 << node->bitnum; + if ((leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + if (tree->leaf_mark(node->left)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->left) { + assert(node->leftnode == NODE); + node = node->left; + if (!node->mark && node->parent->mark) { + marked++; + node->mark = 1; + } + continue; + } + } + if ((rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + if (tree->leaf_mark(node->right)) { + n = node; + while (n && !n->mark) { + marked++; + n->mark = 1; + n = n->parent; + } + } + } else if (node->right) { + assert(node->rightnode==NODE); + node = node->right; + if (!node->mark && node->parent->mark && + !node->parent->left) { + marked++; + node->mark = 1; + } + continue; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + } +done: + if (verbose > 0) + printf("Marked %d nodes\n", marked); +} + +/* + * Compute the index of each node and leaf, which is the offset in the + * emitted trie. These value must be pre-computed because relative + * offsets between nodes are used to navigate the tree. + */ +static int +index_nodes(struct tree *tree, int index) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int count; + int indent; + + /* Align to a cache line (or half a cache line?). */ + while (index % 64) + index++; + tree->index = index; + indent = 1; + count = 0; + + if (verbose > 0) + printf("Indexing %s_%x: %d", tree->type, tree->maxage, index); + if (tree->childnode == LEAF) { + index += tree->leaf_size(tree->root); + goto done; + } + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + count++; + if (node->index != index) + node->index = index; + index += node->size; +skip: + while (node) { + bitmask = 1 << node->bitnum; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + *tree->leaf_index(tree, node->left) = + index; + index += tree->leaf_size(node->left); + count++; + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + *tree->leaf_index(tree, node->right) = index; + index += tree->leaf_size(node->right); + count++; + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +done: + /* Round up to a multiple of 16 */ + while (index % 16) + index++; + if (verbose > 0) + printf("Final index %d\n", index); + return index; +} + +/* + * Compute the size of nodes and leaves. We start by assuming that + * each node needs to store a three-byte offset. The indexes of the + * nodes are calculated based on that, and then this function is + * called to see if the sizes of some nodes can be reduced. This is + * repeated until no more changes are seen. + */ +static int +size_nodes(struct tree *tree) +{ + struct tree *next; + struct node *node; + struct node *right; + struct node *n; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + unsigned int pathbits; + unsigned int pathmask; + int changed; + int offset; + int size; + int indent; + + indent = 1; + changed = 0; + size = 0; + + if (verbose > 0) + printf("Sizing %s_%x", tree->type, tree->maxage); + if (tree->childnode == LEAF) + goto done; + + assert(tree->childnode == NODE); + pathbits = 0; + pathmask = 0; + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + offset = 0; + if (!node->left || !node->right) { + size = 1; + } else { + if (node->rightnode == NODE) { + right = node->right; + next = tree->next; + while (!right->mark) { + assert(next); + n = next->root; + while (n->bitnum != node->bitnum) { + if (pathbits & (1<bitnum)) + n = n->right; + else + n = n->left; + } + n = n->right; + assert(right->bitnum == n->bitnum); + right = n; + next = next->next; + } + offset = right->index - node->index; + } else { + offset = *tree->leaf_index(tree, node->right); + offset -= node->index; + } + assert(offset >= 0); + assert(offset <= 0xffffff); + if (offset <= 0xff) { + size = 2; + } else if (offset <= 0xffff) { + size = 3; + } else { /* offset <= 0xffffff */ + size = 4; + } + } + if (node->size != size || node->offset != offset) { + node->size = size; + node->offset = offset; + changed++; + } +skip: + while (node) { + bitmask = 1 << node->bitnum; + pathmask |= bitmask; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + pathbits |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + pathmask &= ~bitmask; + pathbits &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +done: + if (verbose > 0) + printf("Found %d changes\n", changed); + return changed; +} + +/* + * Emit a trie for the given tree into the data array. + */ +static void +emit(struct tree *tree, unsigned char *data) +{ + struct node *node; + unsigned int leftmask; + unsigned int rightmask; + unsigned int bitmask; + int offlen; + int offset; + int index; + int indent; + unsigned char byte; + + index = tree->index; + data += index; + indent = 1; + if (verbose > 0) + printf("Emitting %s_%x\n", tree->type, tree->maxage); + if (tree->childnode == LEAF) { + assert(tree->root); + tree->leaf_emit(tree->root, data); + return; + } + + assert(tree->childnode == NODE); + node = tree->root; + leftmask = rightmask = 0; + while (node) { + if (!node->mark) + goto skip; + assert(node->offset != -1); + assert(node->index == index); + + byte = 0; + if (node->nextbyte) + byte |= NEXTBYTE; + byte |= (node->bitnum & BITNUM); + if (node->left && node->right) { + if (node->leftnode == NODE) + byte |= LEFTNODE; + if (node->rightnode == NODE) + byte |= RIGHTNODE; + if (node->offset <= 0xff) + offlen = 1; + else if (node->offset <= 0xffff) + offlen = 2; + else + offlen = 3; + offset = node->offset; + byte |= offlen << OFFLEN_SHIFT; + *data++ = byte; + index++; + while (offlen--) { + *data++ = offset & 0xff; + index++; + offset >>= 8; + } + } else if (node->left) { + if (node->leftnode == NODE) + byte |= TRIENODE; + *data++ = byte; + index++; + } else if (node->right) { + byte |= RIGHTNODE; + if (node->rightnode == NODE) + byte |= TRIENODE; + *data++ = byte; + index++; + } else { + assert(0); + } +skip: + while (node) { + bitmask = 1 << node->bitnum; + if (node->mark && (leftmask & bitmask) == 0) { + leftmask |= bitmask; + if (node->leftnode == LEAF) { + assert(node->left); + data = tree->leaf_emit(node->left, + data); + index += tree->leaf_size(node->left); + } else if (node->left) { + assert(node->leftnode == NODE); + indent += 1; + node = node->left; + break; + } + } + if (node->mark && (rightmask & bitmask) == 0) { + rightmask |= bitmask; + if (node->rightnode == LEAF) { + assert(node->right); + data = tree->leaf_emit(node->right, + data); + index += tree->leaf_size(node->right); + } else if (node->right) { + assert(node->rightnode==NODE); + indent += 1; + node = node->right; + break; + } + } + leftmask &= ~bitmask; + rightmask &= ~bitmask; + node = node->parent; + indent -= 1; + } + } +} + +/* ------------------------------------------------------------------ */ + +/* + * Unicode data. + * + * We need to keep track of the Canonical Combining Class, the Age, + * and decompositions for a code point. + * + * For the Age, we store the index into the ages table. Effectively + * this is a generation number that the table maps to a unicode + * version. + * + * The correction field is used to indicate that this entry is in the + * corrections array, which contains decompositions that were + * corrected in later revisions. The value of the correction field is + * the Unicode version in which the mapping was corrected. + */ +struct unicode_data { + unsigned int code; + int ccc; + int gen; + int correction; + unsigned int *utf32nfkdi; + unsigned int *utf32nfkdicf; + char *utf8nfkdi; + char *utf8nfkdicf; +}; + +struct unicode_data unicode_data[0x110000]; +struct unicode_data *corrections; +int corrections_count; + +struct tree *nfkdi_tree; +struct tree *nfkdicf_tree; + +struct tree *trees; +int trees_count; + +/* + * Check the corrections array to see if this entry was corrected at + * some point. + */ +static struct unicode_data * +corrections_lookup(struct unicode_data *u) +{ + int i; + + for (i = 0; i != corrections_count; i++) + if (u->code == corrections[i].code) + return &corrections[i]; + return u; +} + +static int +nfkdi_equal(void *l, void *r) +{ + struct unicode_data *left = l; + struct unicode_data *right = r; + + if (left->gen != right->gen) + return 0; + if (left->ccc != right->ccc) + return 0; + if (left->utf8nfkdi && right->utf8nfkdi && + strcmp(left->utf8nfkdi, right->utf8nfkdi) == 0) + return 1; + if (left->utf8nfkdi || right->utf8nfkdi) + return 0; + return 1; +} + +static int +nfkdicf_equal(void *l, void *r) +{ + struct unicode_data *left = l; + struct unicode_data *right = r; + + if (left->gen != right->gen) + return 0; + if (left->ccc != right->ccc) + return 0; + if (left->utf8nfkdicf && right->utf8nfkdicf && + strcmp(left->utf8nfkdicf, right->utf8nfkdicf) == 0) + return 1; + if (left->utf8nfkdicf && right->utf8nfkdicf) + return 0; + if (left->utf8nfkdicf || right->utf8nfkdicf) + return 0; + if (left->utf8nfkdi && right->utf8nfkdi && + strcmp(left->utf8nfkdi, right->utf8nfkdi) == 0) + return 1; + if (left->utf8nfkdi || right->utf8nfkdi) + return 0; + return 1; +} + +static void +nfkdi_print(void *l, int indent) +{ + struct unicode_data *leaf = l; + + printf("%*sleaf @ %p code %X ccc %d gen %d", indent, "", leaf, + leaf->code, leaf->ccc, leaf->gen); + if (leaf->utf8nfkdi) + printf(" nfkdi \"%s\"", (const char*)leaf->utf8nfkdi); + printf("\n"); +} + +static void +nfkdicf_print(void *l, int indent) +{ + struct unicode_data *leaf = l; + + printf("%*sleaf @ %p code %X ccc %d gen %d", indent, "", leaf, + leaf->code, leaf->ccc, leaf->gen); + if (leaf->utf8nfkdicf) + printf(" nfkdicf \"%s\"", (const char*)leaf->utf8nfkdicf); + else if (leaf->utf8nfkdi) + printf(" nfkdi \"%s\"", (const char*)leaf->utf8nfkdi); + printf("\n"); +} + +static int +nfkdi_mark(void *l) +{ + return 1; +} + +static int +nfkdicf_mark(void *l) +{ + struct unicode_data *leaf = l; + if (leaf->utf8nfkdicf) + return 1; + return 0; +} + +static int +correction_mark(void *l) +{ + struct unicode_data *leaf = l; + return leaf->correction; +} + +static int +nfkdi_size(void *l) +{ + struct unicode_data *leaf = l; + int size = 2; + if (leaf->utf8nfkdi) + size += strlen(leaf->utf8nfkdi) + 1; + return size; +} + +static int +nfkdicf_size(void *l) +{ + struct unicode_data *leaf = l; + int size = 2; + if (leaf->utf8nfkdicf) + size += strlen(leaf->utf8nfkdicf) + 1; + else if (leaf->utf8nfkdi) + size += strlen(leaf->utf8nfkdi) + 1; + return size; +} + +static int * +nfkdi_index(struct tree *tree, void *l) +{ + struct unicode_data *leaf = l; + return &tree->leafindex[leaf->code]; +} + +static int * +nfkdicf_index(struct tree *tree, void *l) +{ + struct unicode_data *leaf = l; + return &tree->leafindex[leaf->code]; +} + +static unsigned char * +nfkdi_emit(void *l, unsigned char *data) +{ + struct unicode_data *leaf = l; + unsigned char *s; + + *data++ = leaf->gen; + if (leaf->utf8nfkdi) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdi; + while ((*data++ = *s++) != 0) + ; + } else { + *data++ = leaf->ccc; + } + return data; +} + +static unsigned char * +nfkdicf_emit(void *l, unsigned char *data) +{ + struct unicode_data *leaf = l; + unsigned char *s; + + *data++ = leaf->gen; + if (leaf->utf8nfkdicf) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdicf; + while ((*data++ = *s++) != 0) + ; + } else if (leaf->utf8nfkdi) { + *data++ = DECOMPOSE; + s = (unsigned char*)leaf->utf8nfkdi; + while ((*data++ = *s++) != 0) + ; + } else { + *data++ = leaf->ccc; + } + return data; +} + +static void +utf8_create(struct unicode_data *data) +{ + char utf[18*4+1]; + char *u; + unsigned int *um; + int i; + + u = utf; + um = data->utf32nfkdi; + if (um) { + for (i = 0; um[i]; i++) + u += utf8key(um[i], u); + *u = '\0'; + data->utf8nfkdi = strdup((char*)utf); + } + u = utf; + um = data->utf32nfkdicf; + if (um) { + for (i = 0; um[i]; i++) + u += utf8key(um[i], u); + *u = '\0'; + if (!data->utf8nfkdi || strcmp(data->utf8nfkdi, (char*)utf)) + data->utf8nfkdicf = strdup((char*)utf); + } +} + +static void +utf8_init(void) +{ + unsigned int unichar; + int i; + + for (unichar = 0; unichar != 0x110000; unichar++) + utf8_create(&unicode_data[unichar]); + + for (i = 0; i != corrections_count; i++) + utf8_create(&corrections[i]); +} + +static void +trees_init(void) +{ + struct unicode_data *data; + unsigned int maxage; + unsigned int nextage; + int count; + int i; + int j; + + /* Count the number of different ages. */ + count = 0; + nextage = (unsigned int)-1; + do { + maxage = nextage; + nextage = 0; + for (i = 0; i <= corrections_count; i++) { + data = &corrections[i]; + if (nextage < data->correction && + data->correction < maxage) + nextage = data->correction; + } + count++; + } while (nextage); + + /* Two trees per age: nfkdi and nfkdicf */ + trees_count = count * 2; + trees = calloc(trees_count, sizeof(struct tree)); + + /* Assign ages to the trees. */ + count = trees_count; + nextage = (unsigned int)-1; + do { + maxage = nextage; + trees[--count].maxage = maxage; + trees[--count].maxage = maxage; + nextage = 0; + for (i = 0; i <= corrections_count; i++) { + data = &corrections[i]; + if (nextage < data->correction && + data->correction < maxage) + nextage = data->correction; + } + } while (nextage); + + /* The ages assigned above are off by one. */ + for (i = 0; i != trees_count; i++) { + j = 0; + while (ages[j] < trees[i].maxage) + j++; + trees[i].maxage = ages[j-1]; + } + + /* Set up the forwarding between trees. */ + trees[trees_count-2].next = &trees[trees_count-1]; + trees[trees_count-1].leaf_mark = nfkdi_mark; + trees[trees_count-2].leaf_mark = nfkdicf_mark; + for (i = 0; i != trees_count-2; i += 2) { + trees[i].next = &trees[trees_count-2]; + trees[i].leaf_mark = correction_mark; + trees[i+1].next = &trees[trees_count-1]; + trees[i+1].leaf_mark = correction_mark; + } + + /* Assign the callouts. */ + for (i = 0; i != trees_count; i += 2) { + trees[i].type = "nfkdicf"; + trees[i].leaf_equal = nfkdicf_equal; + trees[i].leaf_print = nfkdicf_print; + trees[i].leaf_size = nfkdicf_size; + trees[i].leaf_index = nfkdicf_index; + trees[i].leaf_emit = nfkdicf_emit; + + trees[i+1].type = "nfkdi"; + trees[i+1].leaf_equal = nfkdi_equal; + trees[i+1].leaf_print = nfkdi_print; + trees[i+1].leaf_size = nfkdi_size; + trees[i+1].leaf_index = nfkdi_index; + trees[i+1].leaf_emit = nfkdi_emit; + } + + /* Finish init. */ + for (i = 0; i != trees_count; i++) + trees[i].childnode = NODE; +} + +static void +trees_populate(void) +{ + struct unicode_data *data; + unsigned int unichar; + char keyval[4]; + int keylen; + int i; + + for (i = 0; i != trees_count; i++) { + if (verbose > 0) { + printf("Populating %s_%x\n", + trees[i].type, trees[i].maxage); + } + for (unichar = 0; unichar != 0x110000; unichar++) { + if (unicode_data[unichar].gen < 0) + continue; + keylen = utf8key(unichar, keyval); + data = corrections_lookup(&unicode_data[unichar]); + if (data->correction <= trees[i].maxage) + data = &unicode_data[unichar]; + insert(&trees[i], keyval, keylen, data); + } + } +} + +static void +trees_reduce(void) +{ + int i; + int size; + int changed; + + for (i = 0; i != trees_count; i++) + prune(&trees[i]); + for (i = 0; i != trees_count; i++) + mark_nodes(&trees[i]); + do { + size = 0; + for (i = 0; i != trees_count; i++) + size = index_nodes(&trees[i], size); + changed = 0; + for (i = 0; i != trees_count; i++) + changed += size_nodes(&trees[i]); + } while (changed); + + utf8data = calloc(size, 1); + utf8data_size = size; + for (i = 0; i != trees_count; i++) + emit(&trees[i], utf8data); + + if (verbose > 0) { + for (i = 0; i != trees_count; i++) { + printf("%s_%x idx %d\n", + trees[i].type, trees[i].maxage, trees[i].index); + } + } + + nfkdi = utf8data + trees[trees_count-1].index; + nfkdicf = utf8data + trees[trees_count-2].index; + + nfkdi_tree = &trees[trees_count-1]; + nfkdicf_tree = &trees[trees_count-2]; +} + +static void +verify(struct tree *tree) +{ + struct unicode_data *data; + utf8leaf_t *leaf; + unsigned int unichar; + char key[4]; + int report; + int nocf; + + if (verbose > 0) + printf("Verifying %s_%x\n", tree->type, tree->maxage); + nocf = strcmp(tree->type, "nfkdicf"); + + for (unichar = 0; unichar != 0x110000; unichar++) { + report = 0; + data = corrections_lookup(&unicode_data[unichar]); + if (data->correction <= tree->maxage) + data = &unicode_data[unichar]; + utf8key(unichar, key); + leaf = utf8lookup(tree, key); + if (!leaf) { + if (data->gen != -1) + report++; + if (unichar < 0xd800 || unichar > 0xdfff) + report++; + } else { + if (unichar >= 0xd800 && unichar <= 0xdfff) + report++; + if (data->gen == -1) + report++; + if (data->gen != LEAF_GEN(leaf)) + report++; + if (LEAF_CCC(leaf) == DECOMPOSE) { + if (nocf) { + if (!data->utf8nfkdi) { + report++; + } else if (strcmp(data->utf8nfkdi, + LEAF_STR(leaf))) { + report++; + } + } else { + if (!data->utf8nfkdicf && + !data->utf8nfkdi) { + report++; + } else if (data->utf8nfkdicf) { + if (strcmp(data->utf8nfkdicf, + LEAF_STR(leaf))) + report++; + } else if (strcmp(data->utf8nfkdi, + LEAF_STR(leaf))) { + report++; + } + } + } else if (data->ccc != LEAF_CCC(leaf)) { + report++; + } + } + if (report) { + printf("%X code %X gen %d ccc %d" + " nfdki -> \"%s\"", + unichar, data->code, data->gen, + data->ccc, + data->utf8nfkdi); + if (leaf) { + printf(" age %d ccc %d" + " nfdki -> \"%s\"\n", + LEAF_GEN(leaf), + LEAF_CCC(leaf), + LEAF_CCC(leaf) == DECOMPOSE ? + LEAF_STR(leaf) : ""); + } + printf("\n"); + } + } +} + +static void +trees_verify(void) +{ + int i; + + for (i = 0; i != trees_count; i++) + verify(&trees[i]); +} + +/* ------------------------------------------------------------------ */ + +static void +help(void) +{ + printf("Usage: %s [options]\n", argv0); + printf("\n"); + printf("This program creates an a data trie used for parsing and\n"); + printf("normalization of UTF-8 strings. The trie is derived from\n"); + printf("a set of input files from the Unicode character database\n"); + printf("found at: http://www.unicode.org/Public/UCD/latest/ucd/\n"); + printf("\n"); + printf("The generated tree supports two normalization forms:\n"); + printf("\n"); + printf("\tnfkdi:\n"); + printf("\t- Apply unicode normalization form NFKD.\n"); + printf("\t- Remove any Default_Ignorable_Code_Point.\n"); + printf("\n"); + printf("\tnfkdicf:\n"); + printf("\t- Apply unicode normalization form NFKD.\n"); + printf("\t- Remove any Default_Ignorable_Code_Point.\n"); + printf("\t- Apply a full casefold (C + F).\n"); + printf("\n"); + printf("These forms were chosen as being most useful when dealing\n"); + printf("with file names: NFKD catches most cases where characters\n"); + printf("should be considered equivalent. The ignorables are mostly\n"); + printf("invisible, making names hard to type.\n"); + printf("\n"); + printf("The options to specify the files to be used are listed\n"); + printf("below with their default values, which are the names used\n"); + printf("by version 7.0.0 of the Unicode Character Database.\n"); + printf("\n"); + printf("The input files:\n"); + printf("\t-a %s\n", AGE_NAME); + printf("\t-c %s\n", CCC_NAME); + printf("\t-p %s\n", PROP_NAME); + printf("\t-d %s\n", DATA_NAME); + printf("\t-f %s\n", FOLD_NAME); + printf("\t-n %s\n", NORM_NAME); + printf("\n"); + printf("Additionally, the generated tables are tested using:\n"); + printf("\t-t %s\n", TEST_NAME); + printf("\n"); + printf("Finally, the output file:\n"); + printf("\t-o %s\n", UTF8_NAME); + printf("\n"); +} + +static void +usage(void) +{ + help(); + exit(1); +} + +static void +open_fail(const char *name, int error) +{ + printf("Error %d opening %s: %s\n", error, name, strerror(error)); + exit(1); +} + +static void +file_fail(const char *filename) +{ + printf("Error parsing %s\n", filename); + exit(1); +} + +static void +line_fail(const char *filename, const char *line) +{ + printf("Error parsing %s:%s\n", filename, line); + exit(1); +} + +/* ------------------------------------------------------------------ */ + +static void +print_utf32(unsigned int *utf32str) +{ + int i; + for (i = 0; utf32str[i]; i++) + printf(" %X", utf32str[i]); +} + +static void +print_utf32nfkdi(unsigned int unichar) +{ + printf(" %X ->", unichar); + print_utf32(unicode_data[unichar].utf32nfkdi); + printf("\n"); +} + +static void +print_utf32nfkdicf(unsigned int unichar) +{ + printf(" %X ->", unichar); + print_utf32(unicode_data[unichar].utf32nfkdicf); + printf("\n"); +} + +/* ------------------------------------------------------------------ */ + +static void +age_init(void) +{ + FILE *file; + unsigned int first; + unsigned int last; + unsigned int unichar; + unsigned int major; + unsigned int minor; + unsigned int revision; + int gen; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", age_name); + + file = fopen(age_name, "r"); + if (!file) + open_fail(age_name, errno); + count = 0; + + gen = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "# Age=V%d_%d_%d", + &major, &minor, &revision); + if (ret == 3) { + ages_count++; + if (verbose > 1) + printf(" Age V%d_%d_%d\n", + major, minor, revision); + if (!age_valid(major, minor, revision)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "# Age=V%d_%d", &major, &minor); + if (ret == 2) { + ages_count++; + if (verbose > 1) + printf(" Age V%d_%d\n", major, minor); + if (!age_valid(major, minor, 0)) + line_fail(age_name, line); + continue; + } + } + + /* We must have found something above. */ + if (verbose > 1) + printf("%d age entries\n", ages_count); + if (ages_count == 0 || ages_count > MAXGEN) + file_fail(age_name); + + /* There is a 0 entry. */ + ages_count++; + ages = calloc(ages_count + 1, sizeof(*ages)); + /* And a guard entry. */ + ages[ages_count] = (unsigned int)-1; + + rewind(file); + count = 0; + gen = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "# Age=V%d_%d_%d", + &major, &minor, &revision); + if (ret == 3) { + ages[++gen] = + UNICODE_AGE(major, minor, revision); + if (verbose > 1) + printf(" Age V%d_%d_%d = gen %d\n", + major, minor, revision, gen); + if (!age_valid(major, minor, revision)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "# Age=V%d_%d", &major, &minor); + if (ret == 2) { + ages[++gen] = UNICODE_AGE(major, minor, 0); + if (verbose > 1) + printf(" Age V%d_%d = %d\n", + major, minor, gen); + if (!age_valid(major, minor, 0)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "%X..%X ; %d.%d #", + &first, &last, &major, &minor); + if (ret == 4) { + for (unichar = first; unichar <= last; unichar++) + unicode_data[unichar].gen = gen; + count += 1 + last - first; + if (verbose > 1) + printf(" %X..%X gen %d\n", first, last, gen); + if (!utf32valid(first) || !utf32valid(last)) + line_fail(age_name, line); + continue; + } + ret = sscanf(line, "%X ; %d.%d #", &unichar, &major, &minor); + if (ret == 3) { + unicode_data[unichar].gen = gen; + count++; + if (verbose > 1) + printf(" %X gen %d\n", unichar, gen); + if (!utf32valid(unichar)) + line_fail(age_name, line); + continue; + } + } + unicode_maxage = ages[gen]; + fclose(file); + + /* Nix surrogate block */ + if (verbose > 1) + printf(" Removing surrogate block D800..DFFF\n"); + for (unichar = 0xd800; unichar <= 0xdfff; unichar++) + unicode_data[unichar].gen = -1; + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(age_name); +} + +static void +ccc_init(void) +{ + FILE *file; + unsigned int first; + unsigned int last; + unsigned int unichar; + unsigned int value; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", ccc_name); + + file = fopen(ccc_name, "r"); + if (!file) + open_fail(ccc_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X..%X ; %d #", &first, &last, &value); + if (ret == 3) { + for (unichar = first; unichar <= last; unichar++) { + unicode_data[unichar].ccc = value; + count++; + } + if (verbose > 1) + printf(" %X..%X ccc %d\n", first, last, value); + if (!utf32valid(first) || !utf32valid(last)) + line_fail(ccc_name, line); + continue; + } + ret = sscanf(line, "%X ; %d #", &unichar, &value); + if (ret == 2) { + unicode_data[unichar].ccc = value; + count++; + if (verbose > 1) + printf(" %X ccc %d\n", unichar, value); + if (!utf32valid(unichar)) + line_fail(ccc_name, line); + continue; + } + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(ccc_name); +} + +static void +nfkdi_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char *s; + unsigned int *um; + int count; + int i; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", data_name); + file = fopen(data_name, "r"); + if (!file) + open_fail(data_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%*[^;];%*[^;];%*[^;];%*[^;];%[^;];", + &unichar, buf0); + if (ret != 2) + continue; + if (!utf32valid(unichar)) + line_fail(data_name, line); + + s = buf0; + /* skip over */ + if (*s == '<') + while (*s++ != ' ') + ; + /* decode the decomposition into UTF-32 */ + i = 0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(data_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + + if (verbose > 1) + print_utf32nfkdi(unichar); + count++; + } + fclose(file); + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(data_name); +} + +static void +nfkdicf_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char status; + char *s; + unsigned int *um; + int i; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", fold_name); + file = fopen(fold_name, "r"); + if (!file) + open_fail(fold_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X; %c; %[^;];", &unichar, &status, buf0); + if (ret != 3) + continue; + if (!utf32valid(unichar)) + line_fail(fold_name, line); + /* Use the C+F casefold. */ + if (status != 'C' && status != 'F') + continue; + s = buf0; + if (*s == '<') + while (*s++ != ' ') + ; + i = 0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(fold_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + + if (verbose > 1) + print_utf32nfkdicf(unichar); + count++; + } + fclose(file); + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(fold_name); +} + +static void +ignore_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int first; + unsigned int last; + unsigned int *um; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", prop_name); + file = fopen(prop_name, "r"); + if (!file) + open_fail(prop_name, errno); + assert(file); + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X..%X ; %s # ", &first, &last, buf0); + if (ret == 3) { + if (strcmp(buf0, "Default_Ignorable_Code_Point")) + continue; + if (!utf32valid(first) || !utf32valid(last)) + line_fail(prop_name, line); + for (unichar = first; unichar <= last; unichar++) { + free(unicode_data[unichar].utf32nfkdi); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdi = um; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdicf = um; + count++; + } + if (verbose > 1) + printf(" %X..%X Default_Ignorable_Code_Point\n", + first, last); + continue; + } + ret = sscanf(line, "%X ; %s # ", &unichar, buf0); + if (ret == 2) { + if (strcmp(buf0, "Default_Ignorable_Code_Point")) + continue; + if (!utf32valid(unichar)) + line_fail(prop_name, line); + free(unicode_data[unichar].utf32nfkdi); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdi = um; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(sizeof(unsigned int)); + *um = 0; + unicode_data[unichar].utf32nfkdicf = um; + if (verbose > 1) + printf(" %X Default_Ignorable_Code_Point\n", + unichar); + count++; + continue; + } + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(prop_name); +} + +static void +corrections_init(void) +{ + FILE *file; + unsigned int unichar; + unsigned int major; + unsigned int minor; + unsigned int revision; + unsigned int age; + unsigned int *um; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + char *s; + int i; + int count; + int ret; + + if (verbose > 0) + printf("Parsing %s\n", norm_name); + file = fopen(norm_name, "r"); + if (!file) + open_fail(norm_name, errno); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%[^;];%[^;];%d.%d.%d #", + &unichar, buf0, buf1, + &major, &minor, &revision); + if (ret != 6) + continue; + if (!utf32valid(unichar) || !age_valid(major, minor, revision)) + line_fail(norm_name, line); + count++; + } + corrections = calloc(count, sizeof(struct unicode_data)); + corrections_count = count; + rewind(file); + + count = 0; + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%X;%[^;];%[^;];%d.%d.%d #", + &unichar, buf0, buf1, + &major, &minor, &revision); + if (ret != 6) + continue; + if (!utf32valid(unichar) || !age_valid(major, minor, revision)) + line_fail(norm_name, line); + corrections[count] = unicode_data[unichar]; + assert(corrections[count].code == unichar); + age = UNICODE_AGE(major, minor, revision); + corrections[count].correction = age; + + i = 0; + s = buf0; + while (*s) { + mapping[i] = strtoul(s, &s, 16); + if (!utf32valid(mapping[i])) + line_fail(norm_name, line); + i++; + } + mapping[i++] = 0; + + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + corrections[count].utf32nfkdi = um; + + if (verbose > 1) + printf(" %X -> %s -> %s V%d_%d_%d\n", + unichar, buf0, buf1, major, minor, revision); + count++; + } + fclose(file); + + if (verbose > 0) + printf("Found %d entries\n", count); + if (count == 0) + file_fail(norm_name); +} + +/* ------------------------------------------------------------------ */ + +/* + * Hangul decomposition (algorithm from Section 3.12 of Unicode 6.3.0) + * + * AC00;;Lo;0;L;;;;;N;;;;; + * D7A3;;Lo;0;L;;;;;N;;;;; + * + * SBase = 0xAC00 + * LBase = 0x1100 + * VBase = 0x1161 + * TBase = 0x11A7 + * LCount = 19 + * VCount = 21 + * TCount = 28 + * NCount = 588 (VCount * TCount) + * SCount = 11172 (LCount * NCount) + * + * Decomposition: + * SIndex = s - SBase + * + * LV (Canonical/Full) + * LIndex = SIndex / NCount + * VIndex = (Sindex % NCount) / TCount + * LPart = LBase + LIndex + * VPart = VBase + VIndex + * + * LVT (Canonical) + * LVIndex = (SIndex / TCount) * TCount + * TIndex = (Sindex % TCount + * LVPart = LBase + LVIndex + * TPart = TBase + TIndex + * + * LVT (Full) + * LIndex = SIndex / NCount + * VIndex = (Sindex % NCount) / TCount + * TIndex = (Sindex % TCount + * LPart = LBase + LIndex + * VPart = VBase + VIndex + * if (TIndex == 0) { + * d = + * } else { + * TPart = TBase + TIndex + * d = + * } + * + */ + +static void +hangul_decompose(void) +{ + unsigned int sb = 0xAC00; + unsigned int lb = 0x1100; + unsigned int vb = 0x1161; + unsigned int tb = 0x11a7; + /* unsigned int lc = 19; */ + unsigned int vc = 21; + unsigned int tc = 28; + unsigned int nc = (vc * tc); + /* unsigned int sc = (lc * nc); */ + unsigned int unichar; + unsigned int mapping[4]; + unsigned int *um; + int count; + int i; + + if (verbose > 0) + printf("Decomposing hangul\n"); + /* Hangul */ + count = 0; + for (unichar = 0xAC00; unichar <= 0xD7A3; unichar++) { + unsigned int si = unichar - sb; + unsigned int li = si / nc; + unsigned int vi = (si % nc) / tc; + unsigned int ti = si % tc; + + i = 0; + mapping[i++] = lb + li; + mapping[i++] = vb + vi; + if (ti) + mapping[i++] = tb + ti; + mapping[i++] = 0; + + assert(!unicode_data[unichar].utf32nfkdi); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + + assert(!unicode_data[unichar].utf32nfkdicf); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + + if (verbose > 1) + print_utf32nfkdi(unichar); + + count++; + } + if (verbose > 0) + printf("Created %d entries\n", count); +} + +static void +nfkdi_decompose(void) +{ + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + unsigned int *um; + unsigned int *dc; + int count; + int i; + int j; + int ret; + + if (verbose > 0) + printf("Decomposing nfkdi\n"); + + count = 0; + for (unichar = 0; unichar != 0x110000; unichar++) { + if (!unicode_data[unichar].utf32nfkdi) + continue; + for (;;) { + ret = 1; + i = 0; + um = unicode_data[unichar].utf32nfkdi; + while (*um) { + dc = unicode_data[*um].utf32nfkdi; + if (dc) { + for (j = 0; dc[j]; j++) + mapping[i++] = dc[j]; + ret = 0; + } else { + mapping[i++] = *um; + } + um++; + } + mapping[i++] = 0; + if (ret) + break; + free(unicode_data[unichar].utf32nfkdi); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdi = um; + } + /* Add this decomposition to nfkdicf if there is no entry. */ + if (!unicode_data[unichar].utf32nfkdicf) { + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + } + if (verbose > 1) + print_utf32nfkdi(unichar); + count++; + } + if (verbose > 0) + printf("Processed %d entries\n", count); +} + +static void +nfkdicf_decompose(void) +{ + unsigned int unichar; + unsigned int mapping[19]; /* Magic - guaranteed not to be exceeded. */ + unsigned int *um; + unsigned int *dc; + int count; + int i; + int j; + int ret; + + if (verbose > 0) + printf("Decomposing nfkdicf\n"); + count = 0; + for (unichar = 0; unichar != 0x110000; unichar++) { + if (!unicode_data[unichar].utf32nfkdicf) + continue; + for (;;) { + ret = 1; + i = 0; + um = unicode_data[unichar].utf32nfkdicf; + while (*um) { + dc = unicode_data[*um].utf32nfkdicf; + if (dc) { + for (j = 0; dc[j]; j++) + mapping[i++] = dc[j]; + ret = 0; + } else { + mapping[i++] = *um; + } + um++; + } + mapping[i++] = 0; + if (ret) + break; + free(unicode_data[unichar].utf32nfkdicf); + um = malloc(i * sizeof(unsigned int)); + memcpy(um, mapping, i * sizeof(unsigned int)); + unicode_data[unichar].utf32nfkdicf = um; + } + if (verbose > 1) + print_utf32nfkdicf(unichar); + count++; + } + if (verbose > 0) + printf("Processed %d entries\n", count); +} + +/* ------------------------------------------------------------------ */ + +int utf8agemax(struct tree *, const char *); +int utf8nagemax(struct tree *, const char *, size_t); +int utf8agemin(struct tree *, const char *); +int utf8nagemin(struct tree *, const char *, size_t); +ssize_t utf8len(struct tree *, const char *); +ssize_t utf8nlen(struct tree *, const char *, size_t); +struct utf8cursor; +int utf8cursor(struct utf8cursor *, struct tree *, const char *); +int utf8ncursor(struct utf8cursor *, struct tree *, const char *, size_t); +int utf8byte(struct utf8cursor *); + +/* + * Use trie to scan s, touching at most len bytes. + * Returns the leaf if one exists, NULL otherwise. + * + * A non-NULL return guarantees that the UTF-8 sequence starting at s + * is well-formed and corresponds to a known unicode code point. The + * shorthand for this will be "is valid UTF-8 unicode". + */ +static utf8leaf_t * +utf8nlookup(struct tree *tree, const char *s, size_t len) +{ + utf8trie_t *trie = utf8data + tree->index; + int offlen; + int offset; + int mask; + int node; + + if (!tree) + return NULL; + if (len == 0) + return NULL; + node = 1; + while (node) { + offlen = (*trie & OFFLEN) >> OFFLEN_SHIFT; + if (*trie & NEXTBYTE) { + if (--len == 0) + return NULL; + s++; + } + mask = 1 << (*trie & BITNUM); + if (*s & mask) { + /* Right leg */ + if (offlen) { + /* Right node at offset of trie */ + node = (*trie & RIGHTNODE); + offset = trie[offlen]; + while (--offlen) { + offset <<= 8; + offset |= trie[offlen]; + } + trie += offset; + } else if (*trie & RIGHTPATH) { + /* Right node after this node */ + node = (*trie & TRIENODE); + trie++; + } else { + /* No right node. */ + node = 0; + trie = NULL; + } + } else { + /* Left leg */ + if (offlen) { + /* Left node after this node. */ + node = (*trie & LEFTNODE); + trie += offlen + 1; + } else if (*trie & RIGHTPATH) { + /* No left node. */ + node = 0; + trie = NULL; + } else { + /* Left node after this node */ + node = (*trie & TRIENODE); + trie++; + } + } + } + return trie; +} + +/* + * Use trie to scan s. + * Returns the leaf if one exists, NULL otherwise. + * + * Forwards to trie_nlookup(). + */ +static utf8leaf_t * +utf8lookup(struct tree *tree, const char *s) +{ + return utf8nlookup(tree, s, (size_t)-1); +} + +/* + * Return the number of bytes used by the current UTF-8 sequence. + * Assumes the input points to the first byte of a valid UTF-8 + * sequence. + */ +static inline int +utf8clen(const char *s) +{ + unsigned char c = *s; + return 1 + (c >= 0xC0) + (c >= 0xE0) + (c >= 0xF0); +} + +/* + * Maximum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if only non-assigned code points are used. + */ +int +utf8agemax(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age > age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Minimum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if non-assigned code points are used. + */ +int +utf8agemin(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + int age = tree->maxage; + int leaf_age; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age < age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemax(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age > age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemin(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int leaf_age; + int age = tree->maxage; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + leaf_age = ages[LEAF_GEN(leaf)]; + if (leaf_age <= tree->maxage && leaf_age < age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Length of the normalization of s. + * Return -1 if s is not valid UTF-8 unicode. + * + * A string of Default_Ignorable_Code_Point has length 0. + */ +ssize_t +utf8len(struct tree *tree, const char *s) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!tree) + return -1; + while (*s) { + if (!(leaf = utf8lookup(tree, s))) + return -1; + if (ages[LEAF_GEN(leaf)] > tree->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Length of the normalization of s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +ssize_t +utf8nlen(struct tree *tree, const char *s, size_t len) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!tree) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(tree, s, len))) + return -1; + if (ages[LEAF_GEN(leaf)] > tree->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + len -= utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Cursor structure used by the normalizer. + */ +struct utf8cursor { + struct tree *tree; + const char *s; + const char *p; + const char *ss; + const char *sp; + unsigned int len; + unsigned int slen; + short int ccc; + short int nccc; + unsigned int unichar; +}; + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * s : string. + * len : length of s. + * u8c : pointer to cursor. + * trie : utf8trie_t to use for normalization. + * + * Returns -1 on error, 0 on success. + */ +int +utf8ncursor( + struct utf8cursor *u8c, + struct tree *tree, + const char *s, + size_t len) +{ + if (!tree) + return -1; + if (!s) + return -1; + u8c->tree = tree; + u8c->s = s; + u8c->p = NULL; + u8c->ss = NULL; + u8c->sp = NULL; + u8c->len = len; + u8c->slen = 0; + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->unichar = 0; + /* Check we didn't clobber the maximum length. */ + if (u8c->len != len) + return -1; + /* The first byte of s may not be an utf8 continuation. */ + if (len > 0 && (*s & 0xC0) == 0x80) + return -1; + return 0; +} + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * s : NUL-terminated string. + * u8c : pointer to cursor. + * trie : utf8trie_t to use for normalization. + * + * Returns -1 on error, 0 on success. + */ +int +utf8cursor( + struct utf8cursor *u8c, + struct tree *tree, + const char *s) +{ + return utf8ncursor(u8c, tree, s, (unsigned int)-1); +} + +/* + * Get one byte from the normalized form of the string described by u8c. + * + * Returns the byte cast to an unsigned char on succes, and -1 on failure. + * + * The cursor keeps track of the location in the string in u8c->s. + * When a character is decomposed, the current location is stored in + * u8c->p, and u8c->s is set to the start of the decomposition. Note + * that bytes from a decomposition do not count against u8c->len. + * + * Characters are emitted if they match the current CCC in u8c->ccc. + * Hitting end-of-string while u8c->ccc == STOPPER means we're done, + * and the function returns 0 in that case. + * + * Sorting by CCC is done by repeatedly scanning the string. The + * values of u8c->s and u8c->p are stored in u8c->ss and u8c->sp at + * the start of the scan. The first pass finds the lowest CCC to be + * emitted and stores it in u8c->nccc, the second pass emits the + * characters with this CCC and finds the next lowest CCC. This limits + * the number of passes to 1 + the number of different CCCs in the + * sequence being scanned. + * + * Therefore: + * u8c->p != NULL -> a decomposition is being scanned. + * u8c->ss != NULL -> this is a repeating scan. + * u8c->ccc == -1 -> this is the first scan of a repeating scan. + */ +int +utf8byte(struct utf8cursor *u8c) +{ + utf8leaf_t *leaf; + int ccc; + + for (;;) { + /* Check for the end of a decomposed character. */ + if (u8c->p && *u8c->s == '\0') { + u8c->s = u8c->p; + u8c->p = NULL; + } + + /* Check for end-of-string. */ + if (!u8c->p && (u8c->len == 0 || *u8c->s == '\0')) { + /* There is no next byte. */ + if (u8c->ccc == STOPPER) + return 0; + /* End-of-string during a scan counts as a stopper. */ + ccc = STOPPER; + goto ccc_mismatch; + } else if ((*u8c->s & 0xC0) == 0x80) { + /* This is a continuation of the current character. */ + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Look up the data for the current character. */ + if (u8c->p) + leaf = utf8lookup(u8c->tree, u8c->s); + else + leaf = utf8nlookup(u8c->tree, u8c->s, u8c->len); + + /* No leaf found implies that the input is a binary blob. */ + if (!leaf) + return -1; + + /* Characters that are too new have CCC 0. */ + if (ages[LEAF_GEN(leaf)] > u8c->tree->maxage) { + ccc = STOPPER; + } else if ((ccc = LEAF_CCC(leaf)) == DECOMPOSE) { + u8c->len -= utf8clen(u8c->s); + u8c->p = u8c->s + utf8clen(u8c->s); + u8c->s = LEAF_STR(leaf); + /* Empty decomposition implies CCC 0. */ + if (*u8c->s == '\0') { + if (u8c->ccc == STOPPER) + continue; + ccc = STOPPER; + goto ccc_mismatch; + } + leaf = utf8lookup(u8c->tree, u8c->s); + ccc = LEAF_CCC(leaf); + } + u8c->unichar = utf8code(u8c->s); + + /* + * If this is not a stopper, then see if it updates + * the next canonical class to be emitted. + */ + if (ccc != STOPPER && u8c->ccc < ccc && ccc < u8c->nccc) + u8c->nccc = ccc; + + /* + * Return the current byte if this is the current + * combining class. + */ + if (ccc == u8c->ccc) { + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Current combining class mismatch. */ + ccc_mismatch: + if (u8c->nccc == STOPPER) { + /* + * Scan forward for the first canonical class + * to be emitted. Save the position from + * which to restart. + */ + assert(u8c->ccc == STOPPER); + u8c->ccc = MINCCC - 1; + u8c->nccc = ccc; + u8c->sp = u8c->p; + u8c->ss = u8c->s; + u8c->slen = u8c->len; + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (ccc != STOPPER) { + /* Not a stopper, and not the ccc we're emitting. */ + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (u8c->nccc != MAXCCC + 1) { + /* At a stopper, restart for next ccc. */ + u8c->ccc = u8c->nccc; + u8c->nccc = MAXCCC + 1; + u8c->s = u8c->ss; + u8c->p = u8c->sp; + u8c->len = u8c->slen; + } else { + /* All done, proceed from here. */ + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->sp = NULL; + u8c->ss = NULL; + u8c->slen = 0; + } + } +} + +/* ------------------------------------------------------------------ */ + +static int +normalize_line(struct tree *tree) +{ + char *s; + char *t; + int c; + struct utf8cursor u8c; + + /* First test: null-terminated string. */ + s = buf2; + t = buf3; + if (utf8cursor(&u8c, tree, s)) + return -1; + while ((c = utf8byte(&u8c)) > 0) + if (c != (unsigned char)*t++) + return -1; + if (c < 0) + return -1; + if (*t != 0) + return -1; + + /* Second test: length-limited string. */ + s = buf2; + /* Replace NUL with a value that will cause an error if seen. */ + s[strlen(s) + 1] = -1; + t = buf3; + if (utf8cursor(&u8c, tree, s)) + return -1; + while ((c = utf8byte(&u8c)) > 0) + if (c != (unsigned char)*t++) + return -1; + if (c < 0) + return -1; + if (*t != 0) + return -1; + + return 0; +} + +static void +normalization_test(void) +{ + FILE *file; + unsigned int unichar; + struct unicode_data *data; + char *s; + char *t; + int ret; + int ignorables; + int tests = 0; + int failures = 0; + + if (verbose > 0) + printf("Parsing %s\n", test_name); + /* Step one, read data from file. */ + file = fopen(test_name, "r"); + if (!file) + open_fail(test_name, errno); + + while (fgets(line, LINESIZE, file)) { + ret = sscanf(line, "%[^;];%*[^;];%*[^;];%*[^;];%[^;];", + buf0, buf1); + if (ret != 2 || *line == '#') + continue; + s = buf0; + t = buf2; + while (*s) { + unichar = strtoul(s, &s, 16); + t += utf8key(unichar, t); + } + *t = '\0'; + + ignorables = 0; + s = buf1; + t = buf3; + while (*s) { + unichar = strtoul(s, &s, 16); + data = &unicode_data[unichar]; + if (data->utf8nfkdi && !*data->utf8nfkdi) + ignorables = 1; + else + t += utf8key(unichar, t); + } + *t = '\0'; + + tests++; + if (normalize_line(nfkdi_tree) < 0) { + printf("\nline %s -> %s", buf0, buf1); + if (ignorables) + printf(" (ignorables removed)"); + printf(" failure\n"); + failures++; + } + } + fclose(file); + if (verbose > 0) + printf("Ran %d tests with %d failures\n", tests, failures); + if (failures) + file_fail(test_name); +} + +/* ------------------------------------------------------------------ */ + +static void +write_file(void) +{ + FILE *file; + int i; + int j; + int t; + int gen; + + if (verbose > 0) + printf("Writing %s\n", utf8_name); + file = fopen(utf8_name, "w"); + if (!file) + open_fail(utf8_name, errno); + + fprintf(file, "/* This file is generated code, do not edit. */\n"); + fprintf(file, "#ifndef __INCLUDED_FROM_UTF8NORM_C__\n"); + fprintf(file, "#error Only xfs_utf8.c may include this file.\n"); + fprintf(file, "#endif\n"); + fprintf(file, "\n"); + fprintf(file, "const unsigned int utf8version = %#x;\n", + unicode_maxage); + fprintf(file, "\n"); + fprintf(file, "static const unsigned int utf8agetab[] = {\n"); + for (i = 0; i != ages_count; i++) + fprintf(file, "\t%#x%s\n", ages[i], + ages[i] == unicode_maxage ? "" : ","); + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const struct utf8data utf8nfkdicfdata[] = {\n"); + t = 0; + for (gen = 0; gen < ages_count; gen++) { + fprintf(file, "\t{ %#x, %d }%s\n", + ages[gen], trees[t].index, + ages[gen] == unicode_maxage ? "" : ","); + if (trees[t].maxage == ages[gen]) + t += 2; + } + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const struct utf8data utf8nfkdidata[] = {\n"); + t = 1; + for (gen = 0; gen < ages_count; gen++) { + fprintf(file, "\t{ %#x, %d }%s\n", + ages[gen], trees[t].index, + ages[gen] == unicode_maxage ? "" : ","); + if (trees[t].maxage == ages[gen]) + t += 2; + } + fprintf(file, "};\n"); + fprintf(file, "\n"); + fprintf(file, "static const unsigned char utf8data[%zd] = {\n", + utf8data_size); + t = 0; + for (i = 0; i != utf8data_size; i += 16) { + if (i == trees[t].index) { + fprintf(file, "\t/* %s_%x */\n", + trees[t].type, trees[t].maxage); + if (t < trees_count-1) + t++; + } + fprintf(file, "\t"); + for (j = i; j != i + 16; j++) + fprintf(file, "0x%.2x%s", utf8data[j], + (j < utf8data_size -1 ? "," : "")); + fprintf(file, "\n"); + } + fprintf(file, "};\n"); + fclose(file); +} + +/* ------------------------------------------------------------------ */ + +int +main(int argc, char *argv[]) +{ + unsigned int unichar; + int opt; + + argv0 = argv[0]; + + while ((opt = getopt(argc, argv, "a:c:d:f:hn:o:p:t:v")) != -1) { + switch (opt) { + case 'a': + age_name = optarg; + break; + case 'c': + ccc_name = optarg; + break; + case 'd': + data_name = optarg; + break; + case 'f': + fold_name = optarg; + break; + case 'n': + norm_name = optarg; + break; + case 'o': + utf8_name = optarg; + break; + case 'p': + prop_name = optarg; + break; + case 't': + test_name = optarg; + break; + case 'v': + verbose++; + break; + case 'h': + help(); + exit(0); + default: + usage(); + } + } + + if (verbose > 1) + help(); + for (unichar = 0; unichar != 0x110000; unichar++) + unicode_data[unichar].code = unichar; + age_init(); + ccc_init(); + nfkdi_init(); + nfkdicf_init(); + ignore_init(); + corrections_init(); + hangul_decompose(); + nfkdi_decompose(); + nfkdicf_decompose(); + utf8_init(); + trees_init(); + trees_populate(); + trees_reduce(); + trees_verify(); + /* Prevent "unused function" warning. */ + (void)lookup(nfkdi_tree, " "); + if (verbose > 2) + tree_walk(nfkdi_tree); + if (verbose > 2) + tree_walk(nfkdicf_tree); + normalization_test(); + write_file(); + + return 0; +} -- 1.7.12.4 From bpm@sgi.com Fri Sep 19 11:07:45 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD, T_FILL_THIS_FORM_SHORT autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 3D39E29DF9 for ; Fri, 19 Sep 2014 11:07:45 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id A02898F8052; Fri, 19 Sep 2014 09:07:41 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 3D7DB4266DC; Fri, 19 Sep 2014 11:07:41 -0500 (CDT) Date: Fri, 19 Sep 2014 11:07:41 -0500 From: Ben Myers To: linux-fsdevel@vger.kernel.org Cc: xfs@oss.sgi.com, olaf@sgi.com, tinguely@sgi.com Subject: [PATCH 07b/13] libxfs: add supporting code for UTF-8. Message-ID: <20140919160741.GG4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918203114.GN4482@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) From: Olaf Weber Supporting functions for UTF-8 normalization are in utf8norm.c with the header utf8norm.h. Two normalization forms are supported: nfkdi and nfkdicf. nfkdi: - Apply unicode normalization form NFKD. - Remove any Default_Ignorable_Code_Point. nfkdicf: - Apply unicode normalization form NFKD. - Remove any Default_Ignorable_Code_Point. - Apply a full casefold (C + F). For the purposes of the code, a string is valid UTF-8 if: - The values encoded are 0x1..0x10FFFF. - The surrogate codepoints 0xD800..0xDFFFF are not encoded. - The shortest possible encoding is used for all values. The supporting functions work on null-terminated strings (utf8 prefix) and on length-limited strings (utf8n prefix). Signed-off-by: Olaf Weber --- include/utf8norm.h | 111 ++++++++++ libxfs/Makefile | 1 + libxfs/utf8norm.c | 628 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 740 insertions(+) create mode 100644 include/utf8norm.h create mode 100644 libxfs/utf8norm.c diff --git a/include/utf8norm.h b/include/utf8norm.h new file mode 100644 index 0000000..6aa3391 --- /dev/null +++ b/include/utf8norm.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef UTF8NORM_H +#define UTF8NORM_H + +/* An opaque type used to determine the normalization in use. */ +typedef const struct utf8data *utf8data_t; + +/* Encoding a unicode version number as a single unsigned int. */ +#define UNICODE_MAJ_SHIFT (16) +#define UNICODE_MIN_SHIFT (8) + +#define UNICODE_AGE(MAJ,MIN,REV) \ + (((unsigned int)(MAJ) << UNICODE_MAJ_SHIFT) | \ + ((unsigned int)(MIN) << UNICODE_MIN_SHIFT) | \ + ((unsigned int)(REV))) + +/* Highest unicode version supported by the data tables. */ +extern const unsigned int utf8version; + +/* + * Look for the correct utf8data_t for a unicode version. + * Returns NULL if the version requested is too new. + * + * Two normalization forms are supported: nfkdi and nfkdicf. + * + * nfkdi: + * - Apply unicode normalization form NFKD. + * - Remove any Default_Ignorable_Code_Point. + * + * nfkdicf: + * - Apply unicode normalization form NFKD. + * - Remove any Default_Ignorable_Code_Point. + * - Apply a full casefold (C + F). + */ +extern utf8data_t utf8nfkdi(unsigned int); +extern utf8data_t utf8nfkdicf(unsigned int); + +/* + * Determine the maximum age of any unicode character in the string. + * Returns 0 if only unassigned code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern int utf8agemax(utf8data_t, const char *); +extern int utf8nagemax(utf8data_t, const char *, size_t); + +/* + * Determine the minimum age of any unicode character in the string. + * Returns 0 if any unassigned code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern int utf8agemin(utf8data_t, const char *); +extern int utf8nagemin(utf8data_t, const char *, size_t); + +/* + * Determine the length of the normalized from of the string, + * excluding any terminating NULL byte. + * Returns 0 if only ignorable code points are present. + * Returns -1 if the input is not valid UTF-8. + */ +extern ssize_t utf8len(utf8data_t, const char *); +extern ssize_t utf8nlen(utf8data_t, const char *, size_t); + +/* + * Cursor structure used by the normalizer. + */ +struct utf8cursor { + utf8data_t data; + const char *s; + const char *p; + const char *ss; + const char *sp; + unsigned int len; + unsigned int slen; + short int ccc; + short int nccc; +}; + +/* + * Initialize a utf8cursor to normalize a string. + * Returns 0 on success. + * Returns -1 on failure. + */ +extern int utf8cursor(struct utf8cursor *, utf8data_t, const char *); +extern int utf8ncursor(struct utf8cursor *, utf8data_t, const char *, size_t); + +/* + * Get the next byte in the normalization. + * Returns a value > 0 && < 256 on success. + * Returns 0 when the end of the normalization is reached. + * Returns -1 if the string being normalized is not valid UTF-8. + */ +extern int utf8byte(struct utf8cursor *); + +#endif /* UTF8NORM_H */ diff --git a/libxfs/Makefile b/libxfs/Makefile index ae15a5d..a1e85ef 100644 --- a/libxfs/Makefile +++ b/libxfs/Makefile @@ -14,6 +14,7 @@ HFILES = xfs.h init.h xfs_dir2_priv.h crc32defs.h crc32table.h CFILES = cache.c \ crc32.c \ init.c kmem.c logitem.c radix-tree.c rdwr.c trans.c util.c \ + utf8norm.c \ xfs_alloc.c \ xfs_alloc_btree.c \ xfs_attr.c \ diff --git a/libxfs/utf8norm.c b/libxfs/utf8norm.c new file mode 100644 index 0000000..6232d1a --- /dev/null +++ b/libxfs/utf8norm.c @@ -0,0 +1,628 @@ +/* + * Copyright (c) 2014 SGI. + * All rights reserved. + * + * This program 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. + * + * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "xfs.h" +#include "xfs_types.h" +#include + +struct utf8data { + unsigned int maxage; + unsigned int offset; +}; + +#define __INCLUDED_FROM_UTF8NORM_C__ +#include +#undef __INCLUDED_FROM_UTF8NORM_C__ + +/* + * UTF-8 valid ranges. + * + * The UTF-8 encoding spreads the bits of a 32bit word over several + * bytes. This table gives the ranges that can be held and how they'd + * be represented. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000000 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000000 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * There is an additional requirement on UTF-8, in that only the + * shortest representation of a 32bit value is to be used. A decoder + * must not decode sequences that do not satisfy this requirement. + * Thus the allowed ranges have a lower bound. + * + * 0x00000000 0x0000007F: 0xxxxxxx + * 0x00000080 0x000007FF: 110xxxxx 10xxxxxx + * 0x00000800 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx + * 0x00010000 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x00200000 0x03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * 0x04000000 0x7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Actual unicode characters are limited to the range 0x0 - 0x10FFFF, + * 17 planes of 65536 values. This limits the sequences actually seen + * even more, to just the following. + * + * 0 - 0x7F: 0 - 0x7F + * 0x80 - 0x7FF: 0xC2 0x80 - 0xDF 0xBF + * 0x800 - 0xFFFF: 0xE0 0xA0 0x80 - 0xEF 0xBF 0xBF + * 0x10000 - 0x10FFFF: 0xF0 0x90 0x80 0x80 - 0xF4 0x8F 0xBF 0xBF + * + * Within those ranges the surrogates 0xD800 - 0xDFFF are not allowed. + * + * Note that the longest sequence seen with valid usage is 4 bytes, + * the same a single UTF-32 character. This makes the UTF-8 + * representation of Unicode strictly smaller than UTF-32. + * + * The shortest sequence requirement was introduced by: + * Corrigendum #1: UTF-8 Shortest Form + * It can be found here: + * http://www.unicode.org/versions/corrigendum1.html + * + */ + +/* + * Return the number of bytes used by the current UTF-8 sequence. + * Assumes the input points to the first byte of a valid UTF-8 + * sequence. + */ +static inline int +utf8clen(const char *s) +{ + unsigned char c = *s; + return 1 + (c >= 0xC0) + (c >= 0xE0) + (c >= 0xF0); +} + +/* + * utf8trie_t + * + * A compact binary tree, used to decode UTF-8 characters. + * + * Internal nodes are one byte for the node itself, and up to three + * bytes for an offset into the tree. The first byte contains the + * following information: + * NEXTBYTE - flag - advance to next byte if set + * BITNUM - 3 bit field - the bit number to tested + * OFFLEN - 2 bit field - number of bytes in the offset + * if offlen == 0 (non-branching node) + * RIGHTPATH - 1 bit field - set if the following node is for the + * right-hand path (tested bit is set) + * TRIENODE - 1 bit field - set if the following node is an internal + * node, otherwise it is a leaf node + * if offlen != 0 (branching node) + * LEFTNODE - 1 bit field - set if the left-hand node is internal + * RIGHTNODE - 1 bit field - set if the right-hand node is internal + * + * Due to the way utf8 works, there cannot be branching nodes with + * NEXTBYTE set, and moreover those nodes always have a righthand + * descendant. + */ +typedef const unsigned char utf8trie_t; +#define BITNUM 0x07 +#define NEXTBYTE 0x08 +#define OFFLEN 0x30 +#define OFFLEN_SHIFT 4 +#define RIGHTPATH 0x40 +#define TRIENODE 0x80 +#define RIGHTNODE 0x40 +#define LEFTNODE 0x80 + +/* + * utf8leaf_t + * + * The leaves of the trie are embedded in the trie, and so the same + * underlying datatype: unsigned char. + * + * leaf[0]: The unicode version, stored as a generation number that is + * an index into utf8agetab[]. With this we can filter code + * points based on the unicode version in which they were + * defined. The CCC of a non-defined code point is 0. + * leaf[1]: Canonical Combining Class. During normalization, we need + * to do a stable sort into ascending order of all characters + * with a non-zero CCC that occur between two characters with + * a CCC of 0, or at the begin or end of a string. + * The unicode standard guarantees that all CCC values are + * between 0 and 254 inclusive, which leaves 255 available as + * a special value. + * Code points with CCC 0 are known as stoppers. + * leaf[2]: Decomposition. If leaf[1] == 255, then leaf[2] is the + * start of a NUL-terminated string that is the decomposition + * of the character. + * The CCC of a decomposable character is the same as the CCC + * of the first character of its decomposition. + * Some characters decompose as the empty string: these are + * characters with the Default_Ignorable_Code_Point property. + * These do affect normalization, as they all have CCC 0. + * + * The decompositions in the trie have been fully expanded. + * + * Casefolding, if applicable, is also done using decompositions. + * + * The trie is constructed in such a way that leaves exist for all + * UTF-8 sequences that match the criteria from the "UTF-8 valid + * ranges" comment above, and only for those sequences. Therefore a + * lookup in the trie can be used to validate the UTF-8 input. + */ +typedef const unsigned char utf8leaf_t; + +#define LEAF_GEN(LEAF) ((LEAF)[0]) +#define LEAF_CCC(LEAF) ((LEAF)[1]) +#define LEAF_STR(LEAF) ((const char*)((LEAF) + 2)) + +#define MINCCC (0) +#define MAXCCC (254) +#define STOPPER (0) +#define DECOMPOSE (255) + +/* + * Use trie to scan s, touching at most len bytes. + * Returns the leaf if one exists, NULL otherwise. + * + * A non-NULL return guarantees that the UTF-8 sequence starting at s + * is well-formed and corresponds to a known unicode code point. The + * shorthand for this will be "is valid UTF-8 unicode". + */ +static utf8leaf_t * +utf8nlookup(utf8data_t data, const char *s, size_t len) +{ + utf8trie_t *trie = utf8data + data->offset; + int offlen; + int offset; + int mask; + int node; + + if (!data) + return NULL; + if (len == 0) + return NULL; + node = 1; + while (node) { + offlen = (*trie & OFFLEN) >> OFFLEN_SHIFT; + if (*trie & NEXTBYTE) { + if (--len == 0) + return NULL; + s++; + } + mask = 1 << (*trie & BITNUM); + if (*s & mask) { + /* Right leg */ + if (offlen) { + /* Right node at offset of trie */ + node = (*trie & RIGHTNODE); + offset = trie[offlen]; + while (--offlen) { + offset <<= 8; + offset |= trie[offlen]; + } + trie += offset; + } else if (*trie & RIGHTPATH) { + /* Right node after this node */ + node = (*trie & TRIENODE); + trie++; + } else { + /* No right node. */ + node = 0; + trie = NULL; + } + } else { + /* Left leg */ + if (offlen) { + /* Left node after this node. */ + node = (*trie & LEFTNODE); + trie += offlen + 1; + } else if (*trie & RIGHTPATH) { + /* No left node. */ + node = 0; + trie = NULL; + } else { + /* Left node after this node */ + node = (*trie & TRIENODE); + trie++; + } + } + } + return trie; +} + +/* + * Use trie to scan s. + * Returns the leaf if one exists, NULL otherwise. + * + * Forwards to utf8nlookup(). + */ +static utf8leaf_t * +utf8lookup(utf8data_t data, const char *s) +{ + return utf8nlookup(data, s, (size_t)-1); +} + +/* + * Maximum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if only non-assigned code points are used. + */ +int +utf8agemax(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!data) + return -1; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age > age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Minimum age of any character in s. + * Return -1 if s is not valid UTF-8 unicode. + * Return 0 if non-assigned code points are used. + */ +int +utf8agemin(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + int age = data->maxage; + int leaf_age; + + if (!data) + return -1; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age < age) + age = leaf_age; + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemax(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int age = 0; + int leaf_age; + + if (!data) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age > age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Maximum age of any character in s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +int +utf8nagemin(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + int leaf_age; + int age = data->maxage; + + if (!data) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + leaf_age = utf8agetab[LEAF_GEN(leaf)]; + if (leaf_age <= data->maxage && leaf_age < age) + age = leaf_age; + len -= utf8clen(s); + s += utf8clen(s); + } + return age; +} + +/* + * Length of the normalization of s. + * Return -1 if s is not valid UTF-8 unicode. + * + * A string of Default_Ignorable_Code_Point has length 0. + */ +ssize_t +utf8len(utf8data_t data, const char *s) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!data) + return -1; + while (*s) { + if (!(leaf = utf8lookup(data, s))) + return -1; + if (utf8agetab[LEAF_GEN(leaf)] > data->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Length of the normalization of s, touch at most len bytes. + * Return -1 if s is not valid UTF-8 unicode. + */ +ssize_t +utf8nlen(utf8data_t data, const char *s, size_t len) +{ + utf8leaf_t *leaf; + size_t ret = 0; + + if (!data) + return -1; + while (len && *s) { + if (!(leaf = utf8nlookup(data, s, len))) + return -1; + if (utf8agetab[LEAF_GEN(leaf)] > data->maxage) + ret += utf8clen(s); + else if (LEAF_CCC(leaf) == DECOMPOSE) + ret += strlen(LEAF_STR(leaf)); + else + ret += utf8clen(s); + len -= utf8clen(s); + s += utf8clen(s); + } + return ret; +} + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * u8c : pointer to cursor. + * data : utf8data_t to use for normalization. + * s : string. + * len : length of s. + * + * Returns -1 on error, 0 on success. + */ +int +utf8ncursor( + struct utf8cursor *u8c, + utf8data_t data, + const char *s, + size_t len) +{ + if (!data) + return -1; + if (!s) + return -1; + u8c->data = data; + u8c->s = s; + u8c->p = NULL; + u8c->ss = NULL; + u8c->sp = NULL; + u8c->len = len; + u8c->slen = 0; + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + /* Check we didn't clobber the maximum length. */ + if (u8c->len != len) + return -1; + /* The first byte of s may not be an utf8 continuation. */ + if (len > 0 && (*s & 0xC0) == 0x80) + return -1; + return 0; +} + +/* + * Set up an utf8cursor for use by utf8byte(). + * + * u8c : pointer to cursor. + * data : utf8data_t to use for normalization. + * s : NUL-terminated string. + * + * Returns -1 on error, 0 on success. + */ +int +utf8cursor( + struct utf8cursor *u8c, + utf8data_t data, + const char *s) +{ + return utf8ncursor(u8c, data, s, (unsigned int)-1); +} + +/* + * Get one byte from the normalized form of the string described by u8c. + * + * Returns the byte cast to an unsigned char on succes, and -1 on failure. + * + * The cursor keeps track of the location in the string in u8c->s. + * When a character is decomposed, the current location is stored in + * u8c->p, and u8c->s is set to the start of the decomposition. Note + * that bytes from a decomposition do not count against u8c->len. + * + * Characters are emitted if they match the current CCC in u8c->ccc. + * Hitting end-of-string while u8c->ccc == STOPPER means we're done, + * and the function returns 0 in that case. + * + * Sorting by CCC is done by repeatedly scanning the string. The + * values of u8c->s and u8c->p are stored in u8c->ss and u8c->sp at + * the start of the scan. The first pass finds the lowest CCC to be + * emitted and stores it in u8c->nccc, the second pass emits the + * characters with this CCC and finds the next lowest CCC. This limits + * the number of passes to 1 + the number of different CCCs in the + * sequence being scanned. + * + * Therefore: + * u8c->p != NULL -> a decomposition is being scanned. + * u8c->ss != NULL -> this is a repeating scan. + * u8c->ccc == -1 -> this is the first scan of a repeating scan. + */ +int +utf8byte(struct utf8cursor *u8c) +{ + utf8leaf_t *leaf; + int ccc; + + for (;;) { + /* Check for the end of a decomposed character. */ + if (u8c->p && *u8c->s == '\0') { + u8c->s = u8c->p; + u8c->p = NULL; + } + + /* Check for end-of-string. */ + if (!u8c->p && (u8c->len == 0 || *u8c->s == '\0')) { + /* There is no next byte. */ + if (u8c->ccc == STOPPER) + return 0; + /* End-of-string during a scan counts as a stopper. */ + ccc = STOPPER; + goto ccc_mismatch; + } else if ((*u8c->s & 0xC0) == 0x80) { + /* This is a continuation of the current character. */ + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Look up the data for the current character. */ + if (u8c->p) + leaf = utf8lookup(u8c->data, u8c->s); + else + leaf = utf8nlookup(u8c->data, u8c->s, u8c->len); + + /* No leaf found implies that the input is a binary blob. */ + if (!leaf) + return -1; + + /* Characters that are too new have CCC 0. */ + if (utf8agetab[LEAF_GEN(leaf)] > u8c->data->maxage) { + ccc = STOPPER; + } else if ((ccc = LEAF_CCC(leaf)) == DECOMPOSE) { + u8c->len -= utf8clen(u8c->s); + u8c->p = u8c->s + utf8clen(u8c->s); + u8c->s = LEAF_STR(leaf); + /* Empty decomposition implies CCC 0. */ + if (*u8c->s == '\0') { + if (u8c->ccc == STOPPER) + continue; + ccc = STOPPER; + goto ccc_mismatch; + } + leaf = utf8lookup(u8c->data, u8c->s); + ccc = LEAF_CCC(leaf); + } + + /* + * If this is not a stopper, then see if it updates + * the next canonical class to be emitted. + */ + if (ccc != STOPPER && u8c->ccc < ccc && ccc < u8c->nccc) + u8c->nccc = ccc; + + /* + * Return the current byte if this is the current + * combining class. + */ + if (ccc == u8c->ccc) { + if (!u8c->p) + u8c->len--; + return (unsigned char)*u8c->s++; + } + + /* Current combining class mismatch. */ + ccc_mismatch: + if (u8c->nccc == STOPPER) { + /* + * Scan forward for the first canonical class + * to be emitted. Save the position from + * which to restart. + */ + u8c->ccc = MINCCC - 1; + u8c->nccc = ccc; + u8c->sp = u8c->p; + u8c->ss = u8c->s; + u8c->slen = u8c->len; + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (ccc != STOPPER) { + /* Not a stopper, and not the ccc we're emitting. */ + if (!u8c->p) + u8c->len -= utf8clen(u8c->s); + u8c->s += utf8clen(u8c->s); + } else if (u8c->nccc != MAXCCC + 1) { + /* At a stopper, restart for next ccc. */ + u8c->ccc = u8c->nccc; + u8c->nccc = MAXCCC + 1; + u8c->s = u8c->ss; + u8c->p = u8c->sp; + u8c->len = u8c->slen; + } else { + /* All done, proceed from here. */ + u8c->ccc = STOPPER; + u8c->nccc = STOPPER; + u8c->sp = NULL; + u8c->ss = NULL; + u8c->slen = 0; + } + } +} + +const struct utf8data * +utf8nfkdi(unsigned int maxage) +{ + int i = sizeof(utf8nfkdidata)/sizeof(utf8nfkdidata[0]) - 1; + + while (maxage < utf8nfkdidata[i].maxage) + i--; + if (maxage > utf8nfkdidata[i].maxage) + return NULL; + return &utf8nfkdidata[i]; +} + +const struct utf8data * +utf8nfkdicf(unsigned int maxage) +{ + int i = sizeof(utf8nfkdicfdata)/sizeof(utf8nfkdicfdata[0]) - 1; + + while (maxage < utf8nfkdicfdata[i].maxage) + i--; + if (maxage > utf8nfkdicfdata[i].maxage) + return NULL; + return &utf8nfkdicfdata[i]; +} -- 1.7.12.4 From bfoster@redhat.com Fri Sep 19 13:13:12 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B07B47F3F for ; Fri, 19 Sep 2014 13:13:12 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 73E148F8052 for ; Fri, 19 Sep 2014 11:13:09 -0700 (PDT) X-ASG-Debug-ID: 1411150387-04bdf003a147e40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id vjXfCFW09CWdMSq4 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 19 Sep 2014 11:13:08 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8JID7BB003066 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 19 Sep 2014 14:13:07 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8JID6WV003975; Fri, 19 Sep 2014 14:13:07 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id A2CC6120064; Fri, 19 Sep 2014 14:13:05 -0400 (EDT) From: Brian Foster To: fstests@vger.kernel.org Cc: xfs@oss.sgi.com Subject: [PATCH] xfs/062: add xfs unwritten extent data corruption reproducer Date: Fri, 19 Sep 2014 14:13:05 -0400 X-ASG-Orig-Subj: [PATCH] xfs/062: add xfs unwritten extent data corruption reproducer Message-Id: <1411150385-32121-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411150388 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 XFS had a data corruption problem where writeback of pages to unwritten extents would fail to run unwritten extent conversion at I/O completion. This causes subsequent reads of written, but unconverted regions to return zeroes. This occurs on sub-page block size filesystems when writeback contends for the inode lock (e.g., with a file writer). Add a test that creates the conditions to reproduce the data corruption and detect it by looking for unwritten extents after all said extents have been overwritten. Signed-off-by: Brian Foster --- Hi all, Here's a test for the data corruption issue I sent a fix for yesterday: http://oss.sgi.com/archives/xfs/2014-09/msg00259.html It took a little time to improve the effectiveness of the test, but I've been able to run it in current form for 90+ iterations without a false negative (e.g., test passes when it shouldn't) on my setup. It runs in ~30s when there is no failure. Brian tests/xfs/062 | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/xfs/062.out | 5 +++ tests/xfs/group | 1 + 3 files changed, 120 insertions(+) create mode 100755 tests/xfs/062 create mode 100644 tests/xfs/062.out diff --git a/tests/xfs/062 b/tests/xfs/062 new file mode 100755 index 0000000..61f8cf4 --- /dev/null +++ b/tests/xfs/062 @@ -0,0 +1,114 @@ +#! /bin/bash +# FS QA Test No. 062 +# +# This test implements a data corruption scenario on XFS filesystems with +# sub-page sized blocks and unwritten extents. Inode lock contention during +# writeback of pages to unwritten extents leads to failure to convert those +# extents on I/O completion. This causes data corruption as unwritten extents +# are always read back as zeroes. +# +#----------------------------------------------------------------------- +# Copyright (c) 2014 Red Hat, Inc. All Rights Reserved. +# +# This program 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. +# +# This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + kill -9 $syncpid > /dev/null 2>&1 +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/punch + +# real QA test starts here + +_syncloop() +{ + while [ true ] + do + sync + done +} + +# Modify as appropriate. +_supported_fs xfs +_supported_os Linux +_require_scratch +_require_xfs_io_command "falloc" + +_scratch_mkfs >/dev/null 2>&1 +_scratch_mount + +# run background sync thread +_syncloop & +syncpid=$! + +for iters in $(seq 1 100) +do + rm -f $SCRATCH_MNT/file + + # create a delalloc block in each page of the first 64k of the file + for pgoff in $(seq 0 0x1000 0xf000) + do + offset=$((pgoff + 0xc00)) + $XFS_IO_PROG -fc "pwrite $offset 0x1" $SCRATCH_MNT/file \ + > /dev/null 2>&1 + done + + # preallocate the first 64k and overwite, writing past 64k to contend + # with writeback + $XFS_IO_PROG \ + -c "falloc 0 0x10000" \ + -c "pwrite 0 0x100000" \ + -c "fsync" \ + $SCRATCH_MNT/file > /dev/null 2>&1 + + # Check for unwritten extents. We should have none since we wrote over + # the entire preallocated region and ran fsync. + xfs_bmap -v $SCRATCH_MNT/file | _filter_bmap | grep unwritten \ + > /dev/null 2>&1 + if [ $? == 0 ] + then + xfs_bmap -v $SCRATCH_MNT/file + break + fi +done + +echo $iters iterations + +kill $syncpid +wait + +# clear page cache and dump the file +_scratch_unmount +_scratch_mount +hexdump $SCRATCH_MNT/file + +_scratch_unmount +_check_scratch_fs + +status=0 +exit diff --git a/tests/xfs/062.out b/tests/xfs/062.out new file mode 100644 index 0000000..420f2e4 --- /dev/null +++ b/tests/xfs/062.out @@ -0,0 +1,5 @@ +QA output created by 062 +100 iterations +0000000 cdcd cdcd cdcd cdcd cdcd cdcd cdcd cdcd +* +0100000 diff --git a/tests/xfs/group b/tests/xfs/group index 09bce15..685cbe7 100644 --- a/tests/xfs/group +++ b/tests/xfs/group @@ -57,6 +57,7 @@ 059 dump ioctl auto quick 060 dump ioctl auto quick 061 dump ioctl auto quick +062 auto quick 063 dump attr auto quick 064 dump auto 065 dump auto -- 1.8.3.1 From continentalnvestment@gmail.com Fri Sep 19 15:43:51 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: * X-Spam-Status: No, score=1.0 required=5.0 tests=FREEMAIL_FROM,FREEMAIL_REPLYTO, HTML_MESSAGE,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B5A487F3F for ; Fri, 19 Sep 2014 15:43:51 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id A39368F8040 for ; Fri, 19 Sep 2014 13:43:51 -0700 (PDT) X-ASG-Debug-ID: 1411159428-04cbb073024c5d0001-NocioJ Received: from tbjjbihbhfbei.turbo-smtp.net (tbjjbihbhfbei.turbo-smtp.net [199.187.175.148]) by cuda.sgi.com with SMTP id YVWSwmfhy4Sy3t8p for ; Fri, 19 Sep 2014 13:43:48 -0700 (PDT) X-Barracuda-Envelope-From: continentalnvestment@gmail.com X-Barracuda-Apparent-Source-IP: 199.187.175.148 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=turbo-smtp; x=1411764229; h=DomainKey-Signature: Received:Received:Reply-To:From:To:Subject:Date:Organization: Message-ID:MIME-Version:Content-Type:Thread-Index: Content-Language; bh=oWS6phPgHsLwG9N2jivacmLbno5fizVuh7LOlpqt1/Q =; b=YFXpoPqe+Ry51C2fqJfMg1dFZS+k0ffqxCVaBJfiRjOwucpL271TnTHQP9e lKAiAHqryewpHCSWHomTQgUgUsgmdLwunAvHWHZFSfvgIugXlWPzsLPojiTmb0RG Y8Ay/5vbrVtsIF6JwbyV+EsrJK0oh6wyy/OdD4WFJRFbjKyA= DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=turbo-smtp; d=gmail.com; h=Received:Received:X-TurboSMTP-Tracking:Reply-To:From:To:Subject:Date:Organization:Message-ID:MIME-Version:Content-Type:X-Mailer:Thread-Index:Content-Language:X-Cr-Hashedpuzzle:X-Cr-Puzzleid; b=B83w437vTYVphUFYqd9z/X5mQZPv+BXrza+Sh2CBivds8NVpo6zgZjWgRYjnb6 wvAJYTSGTw61oQRwwFvJQfVAnSYf3dDGdO7xmvUMYDoUbbYOMWZSjwbyBxYwWtr3 3KWiat3L6yT4JHQqA8dw9oXqxRv+6suunDQFNi4fqk9Ac=; Received: (qmail 7456 invoked from network); 19 Sep 2014 20:43:48 -0000 Received: from unknown (HELO LenocoPC) (authenticated@175.141.35.18) by turbo-smtp.com with SMTP; 19 Sep 2014 20:43:46 -0000 X-TurboSMTP-Tracking: 1454734197 Reply-To: From: "Alternative Financial Solutions" To: Subject: Project Finance, Proof of Funds, Credit Enhancement... etc Date: Sat, 20 Sep 2014 04:30:11 +0800 X-ASG-Orig-Subj: Project Finance, Proof of Funds, Credit Enhancement... etc Organization: Continental Investment group Message-ID: <3b6a01cfd44a$678d36d0$36a7a470$@com> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_3B6B_01CFD48D.75B076D0" X-Mailer: Microsoft Office Outlook 12.0 Thread-Index: Ac/UO34Gi59DsLZOT4WAB2n1FWKPlg== Content-Language: en-us X-Cr-Hashedpuzzle: ADtG AtZ3 BEDZ B5hi CYHn D8en E7s0 FgjR HMXD HOte HYew HjQ+ IB8T J+dd Kk/f K0fK;1;eABmAHMAQABvAHMAcwAuAHMAZwBpAC4AYwBvAG0A;Sosha1_v1;7;{D6B8881E-F0D0-41FE-9AE7-83C247502163};YwBvAG4AdABpAG4AZQBuAHQAYQBsAG4AdgBlAHMAdABtAGUAbgB0AEAAZwBtAGEAaQBsAC4AYwBvAG0A;Fri, 19 Sep 2014 19:37:34 GMT;UAByAG8AagBlAGMAdAAgAEYAaQBuAGEAbgBjAGUALAAgAFAAcgBvAG8AZgAgAG8AZgAgAEYAdQBuAGQAcwAsACAAQwByAGUAZABpAHQAIABFAG4AaABhAG4AYwBlAG0AZQBuAHQALgAuAC4AIABlAHQAYwA= X-Cr-Puzzleid: {D6B8881E-F0D0-41FE-9AE7-83C247502163} X-Barracuda-Connect: tbjjbihbhfbei.turbo-smtp.net[199.187.175.148] X-Barracuda-Start-Time: 1411159428 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.21 X-Barracuda-Spam-Status: No, SCORE=0.21 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA038b, DKIM_SIGNED, HTML_MESSAGE, THREAD_INDEX X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9662 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message 0.20 BSF_SC0_SA038b Custom Rule SA038b This is a MIME-formatted message. If you see this text it means that your E-mail software does not support MIME-formatted messages. ------=_NextPart_000_3B6B_01CFD48D.75B076D0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Dear Esteemed Clients, Many of you have already benefited from the credit enhancement and proof of funds product services we have been providing since 2006. Our personal and historic relationships with each of these institutions will ensure timely, affordable, and professional service. Our September 2014 List of available Bank Facilities are: SERVICES AVAILABLE . Bank to Bank Phone/Fax Verification . Hard Copy Courier and Electronic Documentation . Account Statement . Proof of Funds Letter . Ready Willing Able Letter . Bank Comfort Letter . SWIFT MT199/799/999/103 messaging (additional charges may apply) . Blocked Funds/Reserved Funds MT199/799/999/760 (additional charges may apply) FINANCIAL INSTRUMENT MONETIZATION Funding through bank instruments is ideal for financing small and large project. It is a viable and powerful alternative to bank funding and has become a valuable tool when banks and conventional funding fall short. Rather than locating an instrument and then looking for a lender who will fund it, the entire process can be handled at once. We can provide the bank instrument and have it monetized through our sources. You can have the funding for your project in the form of a non-recourse loan in 14 days. Please if you are interested in the offer or have a client who may be interested, let me know so that we can discuss the business further. Best Regards, Larsen Roland ------=_NextPart_000_3B6B_01CFD48D.75B076D0 Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

Dear Esteemed Clients,

 

Many of you have already benefited from the cre= dit enhancement and proof of funds product services we have been providing sinc= e 2006.

 

Our personal and historic relationships with ea= ch of these institutions will ensure timely, affordable, and professional serv= ice.

         &= nbsp;  

Our September 2014 List of available Bank Facilities are:

 

SERVICES AVAILABLE

·      =    Bank to Ban= k Phone/Fax Verification<= span lang=3DEN-MY style=3D'font-size:12.0pt;font-family:"Helvetica","sans-serif"= ; mso-fareast-font-family:"Times New Roman";color:black;mso-ansi-language:EN-= MY; mso-fareast-language:EN-MY'>

·      =    Hard Copy Courier and Electronic Documentation

·      =    Account Statement

·      =    Proof of Fu= nds Letter

·      =    Ready Willi= ng Able Letter

·      =    Bank Comfor= t Letter

·      =    SWIFT MT199/799/999/103 messaging (additional charges may apply)=

·      =    Blocked Funds/Reserved Funds MT199/799/999/760 (additional charges may apply)=

FINANCIAL INSTRUMENT MONETIZATION  

Funding throu= gh bank instruments is ideal for financing small and large project. It is a vi= able and powerful alternative to bank funding and has become a valuable tool whe= n banks and conventional funding fall short.

Rather than locating an instrument and then looking for a lender who will fund it, the entire process can be handled at once.

We can provid= e the bank instrument and have it monetized through our sources. You can have= the funding for your project in the form of a non-recourse loan in 14 days.

Please if you= are interested in the offer or have a client who may be interested, let me know= so that we can discuss the business further.

Best Regards,=

Larsen Roland=

 

3D"" ------=_NextPart_000_3B6B_01CFD48D.75B076D0-- From sandeen@sandeen.net Fri Sep 19 15:44:35 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 7C9A97F3F for ; Fri, 19 Sep 2014 15:44:35 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 681D88F8040 for ; Fri, 19 Sep 2014 13:44:34 -0700 (PDT) X-ASG-Debug-ID: 1411159473-04cbb073014c630001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id IdTu9y7QS4jGL2di for ; Fri, 19 Sep 2014 13:44:33 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 37A06654E2BE for ; Fri, 19 Sep 2014 15:44:33 -0500 (CDT) Message-ID: <541C95B1.9020807@sandeen.net> Date: Fri, 19 Sep 2014 15:44:33 -0500 From: Eric Sandeen MIME-Version: 1.0 To: xfs-oss Subject: [PATCH] libxfs: use structure initializers for cache_operations Content-Type: text/plain; charset=utf-8 X-ASG-Orig-Subj: [PATCH] libxfs: use structure initializers for cache_operations Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1411159473 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9662 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This makes it a lot easier for cscope etc. Surely all modern compilers can cope? Signed-off-by: Eric Sandeen --- diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index 9ee89d3..80de6fa 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -1088,12 +1088,12 @@ libxfs_bcache_overflowed(void) } struct cache_operations libxfs_bcache_operations = { - /* .hash */ libxfs_bhash, - /* .alloc */ libxfs_balloc, - /* .flush */ libxfs_bflush, - /* .relse */ libxfs_brelse, - /* .compare */ libxfs_bcompare, - /* .bulkrelse */libxfs_bulkrelse + .hash = libxfs_bhash, + .alloc = libxfs_balloc, + .flush = libxfs_bflush, + .relse = libxfs_brelse, + .compare = libxfs_bcompare, + .bulkrelse = libxfs_bulkrelse }; From alessio.dimaria@gmail.com Fri Sep 19 15:58:52 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE, T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 8A0577F3F for ; Fri, 19 Sep 2014 15:58:52 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 58F988F8064 for ; Fri, 19 Sep 2014 13:58:52 -0700 (PDT) X-ASG-Debug-ID: 1411160329-04bdf003a24e020001-NocioJ Received: from mail-vc0-f178.google.com (mail-vc0-f178.google.com [209.85.220.178]) by cuda.sgi.com with ESMTP id pbgMnjlByCiSDBCx (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Fri, 19 Sep 2014 13:58:50 -0700 (PDT) X-Barracuda-Envelope-From: alessio.dimaria@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.220.178 X-Barracuda-IPDD: Level1 [gmail.com/209.85.220.178] Received: by mail-vc0-f178.google.com with SMTP id lf12so84858vcb.23 for ; Fri, 19 Sep 2014 13:58:49 -0700 (PDT) X-Barracuda-IPDD: Level1 [gmail.com/209.85.220.178] X-Barracuda-IPDD: Level1 [gmail.com/209.85.220.178] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=VdZBZe86br1Iu12wpdOSnNuFWzMRZL/jiUbrghvrOU0=; b=SrrMGMpmLFj0CI38ciILeEYbLH+cg5wxULYB8kGY5X++zB9TWfVa/D7OsoIb2J2E0f 2X7Q0lv7rgRfq1cqOy8URGDlxY/YCG9E0WbqfxL0lmD80pwG8Ned8Sa+/5qo08+Z3fzp yzJpFLhb8RtUcEiczDg/OfcN9g6P0EQV21R520ygQrBbJGApWU6lxP+0X6BaOVsUi/bc HxRgOibWW+VwkEeUfpCqgBAUlVgzfnlDZqIgSKLscHIBn8pvfTUT59sXXg/oy0Wq0l6B 8wVKXdRTyN+fXq5wgAoHnjFrzsIS4zZYq7h8wfKIspb1g6/e5kV2p5bAFuMpyhIjK2Pc zqYA== MIME-Version: 1.0 X-Received: by 10.221.62.194 with SMTP id xb2mr835406vcb.40.1411160329365; Fri, 19 Sep 2014 13:58:49 -0700 (PDT) Received: by 10.221.56.138 with HTTP; Fri, 19 Sep 2014 13:58:49 -0700 (PDT) Date: Fri, 19 Sep 2014 22:58:49 +0200 Message-ID: Subject: Repair XFS from 1/3 of the table From: Alessio Di Maria X-ASG-Orig-Subj: Repair XFS from 1/3 of the table To: xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=001a1136211e272da90503715ef9 X-Barracuda-Connect: mail-vc0-f178.google.com[209.85.220.178] X-Barracuda-Start-Time: 1411160330 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9664 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message --001a1136211e272da90503715ef9 Content-Type: text/plain; charset=UTF-8 Hi, for fist i'm sorry for my bad English.. so, I'm trying to do a recovery from my NAS, After it stopped, 3 disk of 4 was reinitialized so, raid partition was deleted on disk 1 2 and 3, and first about 5m was zero filled.. I'm actually work on a copy of that... in my luck, the XFS superblock was on 4th disk.. I was able to rebuild RAID5 with the original configuration and now i can read RAW files up to few kb... i was able to read a 15Mb zip file, and some big jpeg, so i can say that RAID it's working fine At sector 384 of the raid volume start the xfs superblock, i made a loopback at this offset, mounting it.. but obviusly it said that was not clean. making xfs_repair i get anything, but with xfs_repair -L i had infinite list of lost inode, and than i was able to mount the partition, but with any file, only the lost + found directory with few but complete files... On the NAS there were Big Files of ISCSI, in the lost + found i find one of this, big 100Gb.. now i don't know how i can recovery the rest.. Is it possible to find lost inode? i tryied with many programs to get back the original Filesystem but anything up the Lost + Found directory after the repair... I know that XFS is based on sparse file, and so i can't find my file and hope to copy it contigusly (about 5Gb) cose the fs reidirect zero filled zone... in addiction i can't do a RAW recovery cose in the deep of 2.7Tb i find MFT entryies and system files inner ISCSI units... So what chache? Wha can i do myself? I know that a DIY approach it this case is hard Many Thaks in advance of any reponse! --001a1136211e272da90503715ef9 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi, for fist i'm sorry for my bad English..
so,=C2= =A0
I'm trying to do a recovery from my NAS,=C2=A0
= After it stopped, 3 disk of 4 was reinitialized so, raid partition was dele= ted on disk 1 2 and 3, and first about 5m was zero filled..=C2=A0
I'm actually work on a copy of that...
in my luck, the XFS s= uperblock was on 4th disk..=C2=A0
I was able to rebuild RAID5 wit= h the original configuration and now i can read RAW files up to few kb... i= was able to read a 15Mb zip file, and some big jpeg, so i can say that RAI= D it's working fine

At sector 384 of the raid = volume start the xfs superblock, i made a loopback at this offset,
mounting it.. but obviusly it said that was not clean.=C2=A0
ma= king xfs_repair i get anything, but with xfs_repair -L i had infinite list = of lost inode, and than i was able to mount the partition,=C2=A0
= but with any file, only the lost + found directory with few but complete fi= les...

On the NAS there were Big Files of ISCSI, i= n the lost + found i find one of this, big 100Gb.. now i don't know how= i can recovery the rest..

Is it possible to find = lost inode?

i tryied with many programs to get bac= k the original Filesystem but anything up the Lost + Found directory after = the repair...
I know that XFS is based on sparse file, and so i c= an't find my file and hope to copy it contigusly (about 5Gb) cose the f= s reidirect zero filled zone... in addiction i can't do a RAW recovery = cose in the deep of 2.7Tb i find MFT entryies and system files inner ISCSI = units...=C2=A0
So what chache?=C2=A0
Wha can i = do myself?

I know that a DIY approach it this case= is hard
Many Thaks in advance of any reponse!
--001a1136211e272da90503715ef9-- From daldrich1@mail.csuchico.edu Fri Sep 19 22:13:40 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 9E7AC7F3F for ; Fri, 19 Sep 2014 22:13:40 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3C92AAC003 for ; Fri, 19 Sep 2014 20:13:37 -0700 (PDT) X-ASG-Debug-ID: 1411182815-04cb6c50e755650001-NocioJ Received: from mail-yh0-f44.google.com (mail-yh0-f44.google.com [209.85.213.44]) by cuda.sgi.com with ESMTP id NrXn8Faj3ggEokxT (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Fri, 19 Sep 2014 20:13:36 -0700 (PDT) X-Barracuda-Envelope-From: daldrich1@mail.csuchico.edu X-Barracuda-Apparent-Source-IP: 209.85.213.44 Received: by mail-yh0-f44.google.com with SMTP id v1so999019yhn.17 for ; Fri, 19 Sep 2014 20:13:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:reply-to:date:message-id:subject :from:to:content-type; bh=8eyY6jZUKKrrfAtEJlUhFZnLRmNAcpMiMBi0J6gNDXg=; b=ThIupl90WNYMdfxbYlt9egtNdZ4VD6DOWIhZyL6+5nsQXwXSGhtBaIzS6y/GpiiuNQ abdemi5SlS3YVNgAKMNUWk1lazyVBYWz1p05lWUrBtYaPjWqrvAr2TaJUPQNRyZEOjkZ Utl3v0dzaPs9gWL3Fl2gw+VmGZr5tqzot2a5sUkFG8Stumk8BnxvUI1FRqLTXjRqUnpe luSv6DleCwY7QGtl+2j0sdGayORDZPo8XVFSEBb+BgrMUHxhqkYrc9EI5Bhm7kOD5JNM Z7MVb1tOYsDDo/hNoenmnVvEJ18UDOmfgLcN8VlJw+I9t7h4uX/nXtbL1tTACl+8eF2z 5PWw== X-Gm-Message-State: ALoCoQnV37QpnNakPMHvUEe9YNm/yRaFSKIin8sVFAFF9hrWzxFUu5DphNNauaEQ8W71Kf5JW6Mc MIME-Version: 1.0 X-Received: by 10.236.65.193 with SMTP id f41mr6030743yhd.24.1411182815035; Fri, 19 Sep 2014 20:13:35 -0700 (PDT) Received: by 10.170.191.74 with HTTP; Fri, 19 Sep 2014 20:13:34 -0700 (PDT) Reply-To: jessicahealings@outlook.com Date: Sat, 20 Sep 2014 05:13:34 +0200 Message-ID: Subject: From: Jessica Lombard X-ASG-Orig-Subj: To: undisclosed-recipients:; Content-Type: text/plain; charset=ISO-8859-1 X-Barracuda-Connect: mail-yh0-f44.google.com[209.85.213.44] X-Barracuda-Start-Time: 1411182815 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.79 X-Barracuda-Spam-Status: No, SCORE=1.79 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA620a, MISSING_SUBJECT, MISSING_SUBJECT_2 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9673 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 MISSING_SUBJECT Missing Subject: header 0.50 BSF_SC0_SA620a Custom Rule SA620a 1.28 MISSING_SUBJECT_2 Missing Subject: header -- To whom it may concern, My name is Jessica Lombard, I am based in South Africa, I am a prophetess by nature, and last night, while I was asleep, I had a vision, and in the vision, an old woman, gave me this email address to contact. I'm not sure if this email works, but if this message gets to you, please take the content of this message to be very serious. The old woman I saw in my dream told me that you will win a lottery, and it'll be a big one... She had also asked me to tell you to play a lotto, she also provided me with some winning lucky numbers to use in playing. Please contact me using the same email address so that I can arrange the numbers and pray on it before giving you to go and play and win as the ancestors has declared. Note: I don't do evils with my gift. Jessica Lombard. From stan@hardwarefreak.com Sat Sep 20 14:47:18 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 114527F3F for ; Sat, 20 Sep 2014 14:47:18 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 84549AC001 for ; Sat, 20 Sep 2014 12:47:14 -0700 (PDT) X-ASG-Debug-ID: 1411242429-04cbb073026e410001-NocioJ Received: from greer.hardwarefreak.com (mo-65-41-216-221.sta.embarqhsd.net [65.41.216.221]) by cuda.sgi.com with ESMTP id sO74zlAAK8NB8QKA for ; Sat, 20 Sep 2014 12:47:10 -0700 (PDT) X-Barracuda-Envelope-From: stan@hardwarefreak.com X-Barracuda-Apparent-Source-IP: 65.41.216.221 X-Barracuda-User-Whitelist: xfs@oss.sgi.com Received: from [192.168.100.53] (mo-65-41-216-221.sta.embarqhsd.net [65.41.216.221]) by greer.hardwarefreak.com (Postfix) with ESMTPA id 624546C127; Sat, 20 Sep 2014 14:47:09 -0500 (CDT) Message-ID: <541DD9C8.3090403@hardwarefreak.com> Date: Sat, 20 Sep 2014 14:47:20 -0500 From: stan hoeppner User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Icedove/24.7.0 MIME-Version: 1.0 To: Dave Chinner CC: xfs@oss.sgi.com Subject: Re: storage, libaio, or XFS problem? 3.4.26 References: <20140828230817.GU20518@dastard> <2d2ce7bb38c00a7d35f4a324f6a36cbb@localhost> <20140829235538.GF20518@dastard> <20140831235749.GH20518@dastard> <5403E9B9.7040608@hardwarefreak.com> <20140901234529.GI20518@dastard> <5405FB19.2020208@hardwarefreak.com> <20140902221915.GK20518@dastard> <540BEBB7.7020306@hardwarefreak.com> <20140907233910.GA30012@dastard> <540DC78C.4010607@hardwarefreak.com> X-ASG-Orig-Subj: Re: storage, libaio, or XFS problem? 3.4.26 In-Reply-To: <540DC78C.4010607@hardwarefreak.com> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mo-65-41-216-221.sta.embarqhsd.net[65.41.216.221] X-Barracuda-Start-Time: 1411242430 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On 09/08/2014 10:13 AM, stan hoeppner wrote: > On 09/07/2014 06:39 PM, Dave Chinner wrote: >> On Sun, Sep 07, 2014 at 12:23:03AM -0500, stan hoeppner wrote: >>> I have some more information regarding the AIO issue. I fired up the >>> test harness and it ran for 30 hours at 706 MB/s avg write rate, 303 >>> MB/s per LUN, nearly flawlessly, less than 0.01% buffer loss, and avg IO >>> times were less than 0.5 seconds. Then the app crashed and I found the >>> following in dmesg. I had to "hard reset" the box due to the shrapnel. >>> There are no IO errors of any kind leading up to the forced shutdown. >>> I assume the inode update and streamRT-sa hung task traces are a result >>> of the forced shutdown, not a cause of it. In lieu of an xfs_repair >>> with a version newer than I'm able to install, any ideas what caused the >>> forced shutdown after 30 hours, given there are no errors preceding it? >>> >>> >>> Sep 6 06:33:33 Anguish-ssu-1 kernel: [288087.334863] XFS (dm-5): >>> xfs_do_force_shutdown(0x8) called from line 3732 of file >>> fs/xfs/xfs_bmap.c. Return address = 0xffffffffa02009a6 >>> Sep 6 06:33:42 Anguish-ssu-1 kernel: [288096.220920] XFS (dm-5): failed >>> to update timestamps for inode 0x2ffc9caae >> >> Hi Stan, can you need to turn off line wrapping for stuff you paste >> in? It's all but unreadable when it line wraps like this? > > Sorry. I switched my daily desktop from Windows/Tbird to Wheezy/Icedove > and I haven't tweaked it out much yet. I set hard wrap at 72 and that's > the problem. I'll set flowed format and see if that helps. > >> Next, you need to turn /proc/sys/fs/xfs/error_level up to 11 so that >> it dumps a stack trace on corruption events. I don't have a (I can't >> remember what kernel version you are running) tree in front of me to >> convert that line number to something meaningful, so it's not a >> great help... > > error_level is now 11 on both systems and will survive reboots. It's > kernel 3.4.26. > >> Was there anything in the logs before the shutdown? i.e. can you >> paste the dmesg output from the start of the test (i.e. the mount of >> the fs) to the end? > > They have this setup in a quasi production/test manner, which is > frustrating. The two test rigs PXE/tftp boot and mount rootfs on NFS. > Both systems remote log kern.log into to a single file on the boot > server, so I grep for hostname. dmesg isn't logged remotely, and is > lost after a reboot. So I don't have the mount entries for some reason. > It seems kern.log doesn't get populated with all the stuff that goes > into dmesg. I'll be sure to grab all of dmesg next time before > rebooting. However, I don't recall any errors of any kind prior to the > shutdown, which in itself is strange. Hi Dave, Long story short I was able to get 3.12.26 installed and ran the test harness for 96 hours without problems. It usually puked within 30 hours or much sooner. Just prior to this a new firmware was uploaded to the controllers--which decreased throughput by ~35% and increased IO latency by ~25x. So I'm not sure if the new kernel fixed this problem or if it was the new controller firmware. This old firmware (one of about 50 previous binary loads) is planned to be reloaded Monday so we can test against it with 3.12.26 and hopefully put this AIO issue to rest. Thanks, Stan From www-data@mail.chemitec.com.br Sat Sep 20 18:09:24 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: *** X-Spam-Status: No, score=3.2 required=5.0 tests=FREEMAIL_FROM,FREEMAIL_REPLYTO, HTML_MESSAGE,MIME_HTML_ONLY autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 21FAC7F3F for ; Sat, 20 Sep 2014 18:09:24 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id B27D0AC001 for ; Sat, 20 Sep 2014 16:09:19 -0700 (PDT) X-ASG-Debug-ID: 1411254557-04bdf003a275a80001-NocioJ Received: from mail.chemitec.com.br (mail.chemitec.com.br [200.143.182.9]) by cuda.sgi.com with ESMTP id f0rwhJDXzYrsqYVH for ; Sat, 20 Sep 2014 16:09:18 -0700 (PDT) X-Barracuda-Envelope-From: www-data@mail.chemitec.com.br X-Barracuda-Apparent-Source-IP: 200.143.182.9 Received: from localhost (localhost [127.0.0.1]) by mail-chemitec.182.143.200.static.sp2.alog.com.br (Postfix) with ESMTP id C43034A4FC1 for ; Sat, 20 Sep 2014 20:09:16 -0300 (BRT) X-Virus-Scanned: by amavisd-new-2.6.4 (20090625) (Debian) at 182.143.200.static.sp2.alog.com.br X-Amavis-Alert: BAD HEADER SECTION, Improper use of control character (char 0D hex): From: Lucy Conner \r Received: from mail.chemitec.com.br ([127.0.0.1]) by localhost (mail-chemitec.182.143.200.static.sp2.alog.com.br [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id lkY1+Rio9zsi for ; Sat, 20 Sep 2014 20:09:16 -0300 (BRT) Received: by mail-chemitec.182.143.200.static.sp2.alog.com.br (Postfix, from userid 33) id 587FB4A5236; Sat, 20 Sep 2014 20:08:54 -0300 (BRT) To: xfs@oss.sgi.com Subject: Love Dont Cost A Thing X-PHP-Originating-Script: 33:shotterrtrtrteet.php X-ASG-Orig-Subj: Love Dont Cost A Thing From: Lucy Conner Reply-To: talk2lucyconner@yahoo.com MIME-Version: 1.0 Content-Type: text/html Content-Transfer-Encoding: 8bit Message-Id: <20140920230854.587FB4A5236@mail-chemitec.182.143.200.static.sp2.alog.com.br> Date: Sat, 20 Sep 2014 20:08:54 -0300 (BRT) X-Barracuda-Connect: mail.chemitec.com.br[200.143.182.9] X-Barracuda-Start-Time: 1411254558 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE, MIME_HTML_ONLY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9699 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts 0.00 HTML_MESSAGE BODY: HTML included in message New Page 1

Hi,

I am Lucy Conner, I got your email via internet search. I am looking for an interesting man with a good sense of humor, easy-going, I appreciate seriousness and this should be the main quality in his character. To tell the truth I don't have experience of communicating with men in this way but I would like to find the person who will lead me in the grown life, it might lead to something more, but for now I need a man that I would adore and learn on to have fun when needed, whom we will have a lot in common, who has the knack of listening and talking, who will be loyal not to me but to the love and affection we are going to share. I want to find my match here and live with him all my life.

kindly view attached my pics.

Love

Lucy

From david@fromorbit.com Sat Sep 20 18:45:06 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 27E3D7F3F for ; Sat, 20 Sep 2014 18:45:06 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 12B86304039 for ; Sat, 20 Sep 2014 16:45:05 -0700 (PDT) X-ASG-Debug-ID: 1411256702-04cbb0730173520001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id c60ChyGZA5zDNqZC for ; Sat, 20 Sep 2014 16:45:03 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtY6ABcRHlR5LM9HPGdsb2JhbABfgw5TV4Ixsy4BAgEBAQaUNIFdhWoCAgEBAXsXAQYBAQEBODeEAwEBAQMBOg0PIxAIAw4KCSUPBSUDBxoTiDYHDrJ3kCIYGIV1h2eCEgeESwWGIIsPhGCHBplGKy8BgkkBAQE Received: from ppp121-44-207-71.lns20.syd7.internode.on.net (HELO dastard) ([121.44.207.71]) by ipmail06.adl2.internode.on.net with ESMTP; 21 Sep 2014 09:15:01 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XVUKq-0007hR-QG; Sun, 21 Sep 2014 09:45:00 +1000 Date: Sun, 21 Sep 2014 09:45:00 +1000 From: Dave Chinner To: Brian Foster Cc: fstests@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH] xfs/062: add xfs unwritten extent data corruption reproducer Message-ID: <20140920234500.GK4267@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs/062: add xfs unwritten extent data corruption reproducer References: <1411150385-32121-1-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411150385-32121-1-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1411256702 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9700 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 19, 2014 at 02:13:05PM -0400, Brian Foster wrote: > XFS had a data corruption problem where writeback of pages to unwritten > extents would fail to run unwritten extent conversion at I/O completion. > This causes subsequent reads of written, but unconverted regions to > return zeroes. This occurs on sub-page block size filesystems when > writeback contends for the inode lock (e.g., with a file writer). > > Add a test that creates the conditions to reproduce the data corruption > and detect it by looking for unwritten extents after all said extents > have been overwritten. > > Signed-off-by: Brian Foster > --- > > Hi all, > > Here's a test for the data corruption issue I sent a fix for yesterday: > > http://oss.sgi.com/archives/xfs/2014-09/msg00259.html > > It took a little time to improve the effectiveness of the test, but I've > been able to run it in current form for 90+ iterations without a false > negative (e.g., test passes when it shouldn't) on my setup. It runs in > ~30s when there is no failure. > > Brian > > tests/xfs/062 | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > tests/xfs/062.out | 5 +++ > tests/xfs/group | 1 + > 3 files changed, 120 insertions(+) > create mode 100755 tests/xfs/062 > create mode 100644 tests/xfs/062.out There's nothing XFS specific about this test. Yes, it exposes a bug on XFS, but every filesystem should be able to run and pass this test. > > diff --git a/tests/xfs/062 b/tests/xfs/062 > new file mode 100755 > index 0000000..61f8cf4 > --- /dev/null > +++ b/tests/xfs/062 > @@ -0,0 +1,114 @@ > +#! /bin/bash > +# FS QA Test No. 062 > +# > +# This test implements a data corruption scenario on XFS filesystems with > +# sub-page sized blocks and unwritten extents. Inode lock contention during > +# writeback of pages to unwritten extents leads to failure to convert those > +# extents on I/O completion. This causes data corruption as unwritten extents > +# are always read back as zeroes. > +# > +#----------------------------------------------------------------------- > +# Copyright (c) 2014 Red Hat, Inc. All Rights Reserved. > +# > +# This program 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. > +# > +# This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, > +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > +#----------------------------------------------------------------------- > +# > + > +seq=`basename $0` > +seqres=$RESULT_DIR/$seq > +echo "QA output created by $seq" > + > +here=`pwd` > +status=1 # failure is the default! > +trap "_cleanup; exit \$status" 0 1 2 3 15 Always need to set $tmp here. It's used by things like _scratch_mkfs. > + > +_cleanup() > +{ > + cd / > + kill -9 $syncpid > /dev/null 2>&1 wait rm -f $tmp.* > +} > + > +# get standard environment, filters and checks > +. ./common/rc > +. ./common/punch > + > +# real QA test starts here > + > +_syncloop() > +{ > + while [ true ] > + do > + sync > + done while [....]; do ..... done > +} > + > +# Modify as appropriate. > +_supported_fs xfs > +_supported_os Linux > +_require_scratch > +_require_xfs_io_command "falloc" _require_xfs_io_command "fiemap" > + > +_scratch_mkfs >/dev/null 2>&1 > +_scratch_mount > + > +# run background sync thread > +_syncloop & > +syncpid=$! > + > +for iters in $(seq 1 100) > +do > + rm -f $SCRATCH_MNT/file > + > + # create a delalloc block in each page of the first 64k of the file > + for pgoff in $(seq 0 0x1000 0xf000) > + do > + offset=$((pgoff + 0xc00)) > + $XFS_IO_PROG -fc "pwrite $offset 0x1" $SCRATCH_MNT/file \ > + > /dev/null 2>&1 > + done for .... ; do ..... done is the normal way of doing this. Also it's worth splitting the xfs_io command across multiple lines as you have done later on to make it more readable. Maybe, also, redirect the output to $seqres.full so it's there for debugging failures rather than /dev/null. > + > + # preallocate the first 64k and overwite, writing past 64k to contend > + # with writeback > + $XFS_IO_PROG \ > + -c "falloc 0 0x10000" \ > + -c "pwrite 0 0x100000" \ > + -c "fsync" \ > + $SCRATCH_MNT/file > /dev/null 2>&1 > + > + # Check for unwritten extents. We should have none since we wrote over > + # the entire preallocated region and ran fsync. > + xfs_bmap -v $SCRATCH_MNT/file | _filter_bmap | grep unwritten \ > + > /dev/null 2>&1 Use $XFS_IO_PROG -c "fiemap -v" and dump the output to $seqres.full. > + if [ $? == 0 ] > + then > + xfs_bmap -v $SCRATCH_MNT/file > + break > + fi if [...]; then. That's also a failure, right? So shouldn't it set status=1 and exit, leaving the cleanup function to kill and wait for everything to finish? > +done > + > +echo $iters iterations > + > +kill $syncpid > +wait > + > +# clear page cache and dump the file > +_scratch_unmount > +_scratch_mount _scratch_remount > +hexdump $SCRATCH_MNT/file > + > +_scratch_unmount > +_check_scratch_fs Don't need to do that anymore. > + > +status=0 > +exit > diff --git a/tests/xfs/062.out b/tests/xfs/062.out > new file mode 100644 > index 0000000..420f2e4 > --- /dev/null > +++ b/tests/xfs/062.out > @@ -0,0 +1,5 @@ > +QA output created by 062 > +100 iterations > +0000000 cdcd cdcd cdcd cdcd cdcd cdcd cdcd cdcd > +* > +0100000 > diff --git a/tests/xfs/group b/tests/xfs/group > index 09bce15..685cbe7 100644 > --- a/tests/xfs/group > +++ b/tests/xfs/group > @@ -57,6 +57,7 @@ > 059 dump ioctl auto quick > 060 dump ioctl auto quick > 061 dump ioctl auto quick > +062 auto quick and the rw group, too. Cheers, Dave. -- Dave Chinner david@fromorbit.com From root@krios.tbi.univie.ac.at Sat Sep 20 23:25:11 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 438ED7F3F for ; Sat, 20 Sep 2014 23:25:11 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 319F98F8033 for ; Sat, 20 Sep 2014 21:25:07 -0700 (PDT) X-ASG-Debug-ID: 1411273505-04cb6c50e477f70001-NocioJ Received: from krios.tbi.univie.ac.at (krios.tbi.univie.ac.at [131.130.44.60]) by cuda.sgi.com with ESMTP id mpXGcMay6Fgo9tAS for ; Sat, 20 Sep 2014 21:25:06 -0700 (PDT) X-Barracuda-Envelope-From: root@krios.tbi.univie.ac.at X-Barracuda-Apparent-Source-IP: 131.130.44.60 Received: by krios.tbi.univie.ac.at (Postfix) id 9C5095F33F; Sun, 21 Sep 2014 06:25:03 +0200 (CEST) Delivered-To: root@krios.tbi.univie.ac.at Received: by krios.tbi.univie.ac.at (Postfix, from userid 0) id 88A195F347; Sun, 21 Sep 2014 06:25:03 +0200 (CEST) From: root@krios.tbi.univie.ac.at (Cron Daemon) To: root@krios.tbi.univie.ac.at Subject: Cron test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) Content-Type: text/plain; charset=UTF-8 X-ASG-Orig-Subj: Cron test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) X-Cron-Env: X-Cron-Env: X-Cron-Env: X-Cron-Env: Message-Id: <20140921042503.88A195F347@krios.tbi.univie.ac.at> Date: Sun, 21 Sep 2014 06:25:03 +0200 (CEST) X-Barracuda-Connect: krios.tbi.univie.ac.at[131.130.44.60] X-Barracuda-Start-Time: 1411273506 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.70 X-Barracuda-Spam-Status: No, SCORE=0.70 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, BSF_SC0_SA_TO_FROM_ADDR_MATCH, PR0N_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9706 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.20 PR0N_SUBJECT Subject has letters around special characters (pr0n) 0.50 BSF_SC0_SA_TO_FROM_ADDR_MATCH Sender Address Matches Recipient Address /etc/cron.daily/logrotate: error: error opening /home/git/gitlab/log/application.log: Permission denied error: error opening /home/git/gitlab/log/githost.log: Permission denied error: error opening /home/git/gitlab/log/production.log: Permission denied error: error opening /home/git/gitlab/log/satellites.log: Permission denied error: error opening /home/git/gitlab/log/sidekiq.log: Permission denied error: error opening /home/git/gitlab/log/unicorn.stderr.log: Permission denied error: error opening /home/git/gitlab/log/unicorn.stdout.log: Permission denied error: error opening /home/git/gitlab-shell/gitlab-shell.log: Permission denied run-parts: /etc/cron.daily/logrotate exited with return code 1 From admin@a2.pointingyou.com Sun Sep 21 05:30:17 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE,RCVD_NUMERIC_HELO, T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B61507F4E for ; Sun, 21 Sep 2014 05:30:17 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id A2B78304048 for ; Sun, 21 Sep 2014 03:30:14 -0700 (PDT) X-ASG-Debug-ID: 1411295407-04cbb0730280c30001-NocioJ Received: from a2.pointingyou.com (69-190-128-104-static.reverse.queryfoundry.net [104.128.190.69]) by cuda.sgi.com with ESMTP id 1xpaOJZbgPQuipqr (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sun, 21 Sep 2014 03:30:07 -0700 (PDT) X-Barracuda-Envelope-From: admin@a2.pointingyou.com X-Barracuda-Apparent-Source-IP: 104.128.190.69 Received: from 112.90.37.233 (unknown [112.90.37.233]) by a2.pointingyou.com (Postfix) with ESMTPA id 46A2D52F7F for ; Sun, 21 Sep 2014 18:30:15 +0800 (CST) X-DKIM: Sendmail DKIM Filter v2.8.3 a2.pointingyou.com 46A2D52F7F DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=a2.pointingyou.com; s=a2; t=1411295416; bh=lwpA1AbGb1e06gLVYG+blBnNBsoZDdj2f+eGgxP5DKE=; h=From:Subject:To:Content-Type:MIME-Version:Reply-To:Date; b=CtKCJ7040bl62duzpciCla9ySJOm9vOZfrxE11yTZBW9gUKp2zhvN+8pNKJfpkMUR EZhsjRTSnMHnFhQqAG3NkeBCUQqnxtc51OORZSW6xlJYqEEiUMK5canZlSoI7BM9zS ycLkl8HvMQwgpok0bU6VEFEDPalMEfr3kRHtbZlk= From: "win" Subject: World first----Super size 16 millions color Changing LED Mood Light/18:29:47 To: "xfs" X-ASG-Orig-Subj: World first----Super size 16 millions color Changing LED Mood Light/18:29:47 Content-Type: multipart/alternative; boundary="0aO7uSrx1JlNaDUaqLwmG8TS=_ObKC3fbI" MIME-Version: 1.0 Reply-To: "Chen" Date: Sun, 21 Sep 2014 18:29:49 +0800 Priority: urgent X-Priority: 1 X-Barracuda-Connect: 69-190-128-104-static.reverse.queryfoundry.net[104.128.190.69] X-Barracuda-Start-Time: 1411295407 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.40 X-Barracuda-Spam-Status: No, SCORE=1.40 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, HTML_MESSAGE, MISSING_MID, RCVD_NUMERIC_HELO, RCVD_NUMERIC_HELO_2 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9714 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.14 MISSING_MID Missing Message-Id: header 0.00 RCVD_NUMERIC_HELO Received: contains an IP address used for HELO -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message 1.25 RCVD_NUMERIC_HELO_2 Received: contains an IP address used for HELO Message-Id: <20140921103014.0B4B8106C883@cuda.sgi.com> This is a multi-part message in MIME format --0aO7uSrx1JlNaDUaqLwmG8TS=_ObKC3fbI Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline =EF=BB=BF Hello,this is Chen,today I want to introduce our super size 16 million= s color LED mood light to you,it is our patented product, and works ma= gic in creating romance at nights. = http://www.starringled.com= =20 =20 Highlights: 1). It has 16 millions of colors, from red, to violet, to everything i= n between all at fingertips. 2). It also features a transparent, bubble-like design that allows you= to see into its metal interior. 3). And it has super size with the diameter 25cm,making it emitt suffi= cient romantic lighting. 4). Using touch-sensitive remote control, you can instantly change the= color and magically bathe your room in a color that suits your mood. 5). The lamp also gives you a second, more-dynamic option: automatic c= olor changing mode.=20 weblink: http://www.starringled.com/product/showproduct.php?lang=3Den&= id=3D106 =20 Prices: The big size 25cm diameter, the package weight is around 5KG. For sample price, it is 106USD/per,including the DHL door to door char= ge. Bulk order prices are negotiable. If you have interest in our products,please feel free to contact us. Best regards/Mr.Chen Company: GD Hi-tech lighting Group Co,.LTD Website: http://www.starringled.com =20= Add::Building 6, Baolong Indutrial park, longgang district,Shenzhen Ch= ina =20 Email: sales@starringled.com = =20 Mobile: +86-13714518751,Tel: +86-755-36626032 (10 lines) = =20 Skype: xiaguangchen=20 Let our LED mood light bring colors and romance to your life! =20 If you don't want to hear from us,please click Here to unsubscribe = 21/9/201418:29:47kIKkOm --0aO7uSrx1JlNaDUaqLwmG8TS=_ObKC3fbI Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline =EF=BB=BF =

Hello,this is = Chen,today I want to introduce our super size 16= millions color LED mood light to you,it is our patented produc= t, and works magic in creating romance at nights.   &nb= sp;           &= nbsp;           = ;           &nb= sp;           &= nbsp;           = ;           &nb= sp;      http://www.starringled.com

           &n= bsp;          3D""

Highlights:

1).=  It has 16 millions of colors, from=  red, to violet, to everything in b= etween all at fingertips.

2). It also = features a transparent, bubble-like design th= at allows you to see into its metal=  interior.

3). And it has super s= ize with the diameter 25cm,making it emi= tt sufficient romantic lighting.

4). Using&= nbsp;touch-sensitive remote control, you can = instantly change the color and magically = ;bathe your room in a color

 that suits your mo= od.

5). The lamp also gives you a=  second, more-dynamic option: automatic color=  changing mode. 

weblink: h= ttp://www.starringled.com/product/showproduct.php?lang=3Den&id=3D1= 06  

 

Prices:

The big size 25cm diameter, = ;the package weight is around 5KG.

For=  sample price, it is 106USD/per,including&nbs= p;the DHL door to door charge.
Bulk o= rder prices are negotiable.

If you have interest in our products,please feel fre= e to contact us.

Best regards/Mr.Chen

Company: GD Hi-tech lighting Group Co,.LTD
Websit= e: http://www.starringled.com            &= nbsp;           = ;          
Add:= :Building 6, Baolong Indutrial park, longgang district,Shenzhen China&= nbsp;           = ;           &nb= sp;         
Email: <= A href=3D"mailto:sales@starringled.com">sales@starringled.com
&nbs= p;           &n= bsp;           =            &nbs= p;           &n= bsp;           =     
Mobile: +86-13714518751,Tel: +86-755-3662= 6032 (10 lines)         &= nbsp;           = ;           &nb= sp;    
Skype: xiaguangchen

 
Le= t our LED mood light bring colors and romance to your life!

 

If you don't want to hear from us,ple= ase click Here to unsubscribe     &nb= sp;     21/9/201= 418:29:476Q5ew

--0aO7uSrx1JlNaDUaqLwmG8TS=_ObKC3fbI-- From cm1215m@yahoo-inc.com Mon Sep 22 00:20:12 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.2 required=5.0 tests=HTML_MESSAGE,MIME_HTML_ONLY autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 13B6A7F50 for ; Mon, 22 Sep 2014 00:20:12 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 87459AC004 for ; Sun, 21 Sep 2014 22:20:11 -0700 (PDT) X-ASG-Debug-ID: 1411363204-04cbb07303a08b0001-NocioJ Received: from mail.infotrade.com.ua (mail.infotrade.com.ua [92.60.183.57]) by cuda.sgi.com with ESMTP id 9pmnAzmEUjleGynH (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sun, 21 Sep 2014 22:20:05 -0700 (PDT) X-Barracuda-Envelope-From: cm1215m@yahoo-inc.com X-Barracuda-Apparent-Source-IP: 92.60.183.57 Received: from Unknown ([46.191.234.170]) (authenticated bits=0) by mail.infotrade.com.ua (8.14.7/8.14.9) with ESMTP id s8M5K4A5061803; Mon, 22 Sep 2014 08:20:05 +0300 (EEST) (envelope-from cm1215m@yahoo-inc.com) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.97.5 at mail.infotrade.com.ua Message-ID: From: =?utf-8?B?0JjQvdC20LXQvdC10YAt0L/RgNC+0LXQutGC0LjRgNC+?= =?utf-8?B?0LLRidC40Lo=?= To: , , , Subject: =?utf-8?B?0J/RgNCw0LrRgtC40LrQsCDQv9GA0LjQstC70LXRh9C1?= =?utf-8?B?0L3QuNGPINC6INCw0LTQvNC40L3QuNGB0YLRgNCw0YLQ?= =?utf-8?B?uNCy0L3QvtC5INC4INGD0LPQvtC70L7QstC90L7QuSDQ?= =?utf-8?B?vtGC0LLQtdGC0YHRgtCy0LXQvdC90L7RgdGC0Lgg0LfQ?= =?utf-8?B?sCDQv9GA0LDQstC+0L3QsNGA0YPRiNC10L3QuNGPINCy?= =?utf-8?B?INC+0LHQu9Cw0YHRgtC4INGB0YLRgNC+0LjRgtC10LvR?= =?utf-8?B?jNGB0YLQstCwLg==?= Date: Mon, 22 Sep 2014 07:19:57 +0200 X-ASG-Orig-Subj: =?utf-8?B?0J/RgNCw0LrRgtC40LrQsCDQv9GA0LjQstC70LXRh9C1?= =?utf-8?B?0L3QuNGPINC6INCw0LTQvNC40L3QuNGB0YLRgNCw0YLQ?= =?utf-8?B?uNCy0L3QvtC5INC4INGD0LPQvtC70L7QstC90L7QuSDQ?= =?utf-8?B?vtGC0LLQtdGC0YHRgtCy0LXQvdC90L7RgdGC0Lgg0LfQ?= =?utf-8?B?sCDQv9GA0LDQstC+0L3QsNGA0YPRiNC10L3QuNGPINCy?= =?utf-8?B?INC+0LHQu9Cw0YHRgtC4INGB0YLRgNC+0LjRgtC10LvR?= =?utf-8?B?jNGB0YLQstCwLg==?= MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0E81_01CFD635.9D267DF0" X-Priority: 3 X-Barracuda-Connect: mail.infotrade.com.ua[92.60.183.57] X-Barracuda-Start-Time: 1411363205 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_TG035a, HTML_MESSAGE, MIME_HTML_ONLY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9741 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 BSF_SC0_TG035a Message contains invalid style definition This is a multi-part message in MIME format. ------=_NextPart_000_0E81_01CFD635.9D267DF0 Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: base64 PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwv L0VOIj4NCjxIVE1MIHhtbG5zOm8gPSAidXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6 b2ZmaWNlIj48SEVBRD4NCjxNRVRBIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD11dGYtOCIg aHR0cC1lcXVpdj1Db250ZW50LVR5cGU+DQo8TUVUQSBuYW1lPUdFTkVSQVRPUiBjb250ZW50PSJN U0hUTUwgMTEuMDAuOTYwMC4xNzEwNSI+DQo8U1RZTEU+PC9TVFlMRT4NCjwvSEVBRD4NCjxCT0RZ IGJnQ29sb3I9I2ZmZmZmZj4NCjxESVY+0KDRg9C60L7QstC+0LTRj9GJ0LjQtSDQtNC+0LrRg9C8 0LXQvdGC0Ysg0L/QviDQstCy0L7QtNGDINC+0LHRitC10LrRgtCwINCyINGN0LrRgdC/0LvRg9Cw 0YLQsNGG0LjRji4g0J7QutGC0Y/QsdGA0YwgMjAxNCE8L0RJVj4NCjxESVY+Jm5ic3A7PC9ESVY+ DQo8RElWPtCU0LvRjyDQt9Cw0LLQtdGA0YjQtdC90LjRjyDRgdGC0YDQvtC40YLQtdC70YzRgdGC 0LLQsCDQuCDQvtGE0L7RgNC80LvQtdC90LjRjyDQv9GA0LDQstCwINGB0L7QsdGB0YLQstC10L3Q vdC+0YHRgtC4INC90LAg0L7QsdGK0LXQutGCIA0K0L3QtdC00LLQuNC20LjQvNC+0YHRgtC4INCy Jm5ic3A7INGB0L7QvtGC0LLQtdGC0YHRgtCy0LjQuCDRgSDQt9Cw0LrQvtC90L7QtNCw0YLQtdC7 0YzRgdGC0LLQvtC8INCg0KQg0L/RgNC10LTRg9GB0LzQvtGC0YDQtdC90LAg0L/RgNC+0YbQtdC0 0YPRgNCwIA0K0LLRi9C00LDRh9C4INGA0LDQt9GA0LXRiNC10L3QuNGPINC90LAg0LLQstC+0LQm bmJzcDsg0L7QsdGK0LXQutGC0LAg0LIg0Y3QutGB0L/Qu9GD0LDRgtCw0YbQuNGOLjwvRElWPg0K PERJVj4mbmJzcDs8L0RJVj4NCjxESVY+0JLQviDQstC70L7QttC10L3QuNC4INCS0Ysg0L3QsNC5 0LTRkdGC0LUg0LjQvdGE0L7RgNC80LDRhtC40L7QvdC90L7QtSDQv9C40YHRjNC80L4sINGBINC/ 0YDQuNCz0LvQsNGI0LXQvdC40LXQvCDQvdCwIA0K0LrQvtC90YHRg9C70YzRgtCw0YbQuNGOINC/ 0L4g0LLQvtC/0YDQvtGB0LDQvCDQvtGE0L7RgNC80LvQtdC90LjRjyDQstCy0L7QtNCwINC+0LHR itC10LrRgtCwINC60LDQv9C40YLQsNC70YzQvdC+0LPQviDRgdGC0YDQvtC40YLQtdC70YzRgdGC 0LLQsCDQsiANCtGN0LrRgdC/0LvRg9Cw0YLQsNGG0LjRji48QlI+PC9ESVY+PC9CT0RZPjwvSFRN TD4NCg== ------=_NextPart_000_0E81_01CFD635.9D267DF0 Content-Type: application/octet-stream; name="=?utf-8?B?0JjQvdGE0L7RgNC80LDRhtC40L7QvdC90L7QtSDQv9C4?= =?utf-8?B?0YHRjNC80L4uZG9jeA==?=" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="=?utf-8?B?0JjQvdGE0L7RgNC80LDRhtC40L7QvdC90L7QtSDQv9C4?= =?utf-8?B?0YHRjNC80L4uZG9jeA==?=" UEsDBBQABgAIAAAAIQBkPG6ZoAEAABYHAAATAAgCW0NvbnRlbnRfVHlwZXNdLnhtbCCiBAIooAAC AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC0 lctOwzAQRfdI/EPkLUpcWCCEmrLgsQQkilgbe9JYJLblGR79eyZNGwFqcXl0E8mx597jsXU9Pntr m+wFIlrvSnFYjEQGTntj3awU99Or/ERkSMoZ1XgHpZgDirPJ/t54Og+AGVc7LEVNFE6lRF1Dq7Dw ARzPVD62ingYZzIo/aRmII9Go2OpvSNwlFOnISbjC6jUc0PZ5Rv/7kkiNCiy835h51UKFUJjtSIm lS/OfHHJlw4FVy7WYG0DHjCGkGsdupnNBsu6G25NtAayWxXpWrWMIV99NNJ4/dzyHorvZdZw+qqy Gob6Ti1ErwGRe942xTDTKutW/Bs5kOYN4P9T9Lpb2j9Yqi+rCjQfdrofLebdpove4kNt2g2IuEnb mHy+gnmq6bhUTiK8wuPdzig+iCdBKu/JedrF2Q/SSQhwZkcMK+UkQg3KQDzc4t798Er0wkn/iiNq qh4b+H+CQToJQZy7IBffv3diIfOdJSfUbfQBOcfjL7a9CuquOufoCxDJwhDV66JucOQ34M99hu6V MWDWeMvFqzZ5BwAA//8DAFBLAwQUAAYACAAAACEAHpEat/MAAABOAgAACwAIAl9yZWxzLy5yZWxz IKIEAiigAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAIyS20oDQQyG7wXfYch9N9sKItLZ3kihdyLrA4SZ7AF3Dsyk2r69oyC6UNte5vTny0/W m4Ob1DunPAavYVnVoNibYEffa3htt4sHUFnIW5qCZw1HzrBpbm/WLzyRlKE8jDGrouKzhkEkPiJm M7CjXIXIvlS6kBxJCVOPkcwb9Yyrur7H9FcDmpmm2lkNaWfvQLXHWDZf1g5dNxp+Cmbv2MuJFcgH YW/ZLmIqbEnGco1qKfUsGmwwzyWdkWKsCjbgaaLV9UT/X4uOhSwJoQmJz/N8dZwDWl4PdNmiecev Ox8hWSwWfXv7Q4OzL2g+AQAA//8DAFBLAwQUAAYACAAAACEAYPLRdE0BAABBBQAAHAAIAXdvcmQv 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 ------=_NextPart_000_0E81_01CFD635.9D267DF0-- From bfoster@redhat.com Mon Sep 22 08:19:01 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C873A7F4E for ; Mon, 22 Sep 2014 08:19:01 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id B6B468F8035 for ; Mon, 22 Sep 2014 06:18:58 -0700 (PDT) X-ASG-Debug-ID: 1411391937-04cbb07304b0450001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id XPzIDTqJbY4a1Y1P (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 22 Sep 2014 06:18:57 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8MDIu83030626 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Mon, 22 Sep 2014 09:18:57 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8MDIuV5019941; Mon, 22 Sep 2014 09:18:56 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 7F258120064; Mon, 22 Sep 2014 09:18:55 -0400 (EDT) Date: Mon, 22 Sep 2014 09:18:55 -0400 From: Brian Foster To: Eric Sandeen Cc: xfs-oss Subject: Re: [PATCH] xfs_repair: validate & fix inode CRCs Message-ID: <20140922131855.GA29156@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs_repair: validate & fix inode CRCs References: <5418AC01.30006@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5418AC01.30006@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411391937 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Sep 16, 2014 at 04:30:41PM -0500, Eric Sandeen wrote: > xfs_repair doesn't ever check an inode's CRC, so it never repairs > them. If the root inode or realtime inodes have bad crcs, the > fs won't even mount and can't be fixed (without using xfs_db). > > It's fairly straightforward to just test the inode CRC before > we do any other checking or modification of the inode, once we > get past the "verify only" phase of process_dinode_int(); > just mark it dirty if it's wrong and needs to be re-written. > > Signed-off-by: Eric Sandeen > --- > > forgive the gratuitous big honkin' comment line, but > process_dinode_int is so long, I thought the visual delimiter was > useful. ;) > > diff --git a/repair/dinode.c b/repair/dinode.c > index 8891e84..27c0da6 100644 > --- a/repair/dinode.c > +++ b/repair/dinode.c > @@ -2524,6 +2524,30 @@ _("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"), > if (verify_mode) > return retval; > > + /* =========== END OF VERIFY MODE =================== */ > + > + /* > + * We'd really like to know if the CRC is bad before we > + * go fixing anything; that way we have some hint about > + * bit-rot vs bugs. Also, any changes will invalidate the > + * existing CRC, so this is the only valid point to test it. > + * > + * Of course if we make any modifications after this, the > + * inode gets rewritten, and CRC is updated automagically. > + */ > + if (xfs_sb_version_hascrc(&mp->m_sb)) { > + ASSERT(!verify_mode); > + if(!xfs_verify_cksum((char *)dino, mp->m_sb.sb_inodesize, > + XFS_DINODE_CRC_OFF)) { > + do_warn(_("bad CRC for inode %" PRIu64), lino); > + if (!no_modify) { > + do_warn(_(", will rewrite\n")); > + *dirty = 1; > + } else > + do_warn(_(", would rewrite\n")); > + } > + } > + So we verify each inode first in process_inode_chunk() and then follow on with process_dinode(). There's a comment further up in process_dinode_int() that indicates we explicitly do not check the crc at that point, presumably considering verify_mode. I only see one call to each of verify_inode() and process_dinode() (in that order). The other process_dinode_int() caller is verify_uncertain_dinode(), which looks like it occurs ultimately from process_uncertain_aginodes() in phase 3. I suppose that logic makes sense, but it's not totally clear tbh. We do fix up the crc in the caller if the inode is marked dirty. It also seems like it's possible to modify the inode before this point where we check the crc. Given that, it seems like we could just add an "if (!verify_mode)" hunk to the preexisting hascrc() hunk further up in the function..? I don't really have a clear beat on this at the moment. I think what I'm getting after is that right now if we see the new crc message, it isn't necessarily clear if that is because repair changed something or it is legitimately wrong on-disk, depending on how the inode might be corrupted or if the inode is free (do we care about crc's in that case? it looks like we miss that as well). It would be nice if we had some kind of consistent rule for this scenario, such as "always print the error if the crc is wrong" (e.g., before we make any modifications) or "only print the error if the crc is the only thing wrong" (e.g., we've already verified the inode and the crc itself is wrong). Either way it seems inappropriate to print a crc error that might be caused by repair itself. Brian > /* > * clear the next unlinked field if necessary on a good > * inode only during phase 4 -- when checking for inodes > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Mon Sep 22 08:21:11 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id BB4897F50 for ; Mon, 22 Sep 2014 08:21:11 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id A7A788F804B for ; Mon, 22 Sep 2014 06:21:11 -0700 (PDT) X-ASG-Debug-ID: 1411392070-04cbb07304b0550001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id iqUGvCJf2VRW3WIH (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 22 Sep 2014 06:21:10 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8MDL9XT010182 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 22 Sep 2014 09:21:09 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8MDL8n5021630; Mon, 22 Sep 2014 09:21:08 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 834DB120064; Mon, 22 Sep 2014 09:21:07 -0400 (EDT) Date: Mon, 22 Sep 2014 09:21:07 -0400 From: Brian Foster To: Eric Sandeen Cc: xfs-oss Subject: Re: [PATCH] libxfs: use structure initializers for cache_operations Message-ID: <20140922132107.GB29156@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] libxfs: use structure initializers for cache_operations References: <541C95B1.9020807@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <541C95B1.9020807@sandeen.net> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411392070 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Sep 19, 2014 at 03:44:33PM -0500, Eric Sandeen wrote: > This makes it a lot easier for cscope etc. > > Surely all modern compilers can cope? > > Signed-off-by: Eric Sandeen > --- Seems reasonable to me. Reviewed-by: Brian Foster > > diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c > index 9ee89d3..80de6fa 100644 > --- a/libxfs/rdwr.c > +++ b/libxfs/rdwr.c > @@ -1088,12 +1088,12 @@ libxfs_bcache_overflowed(void) > } > > struct cache_operations libxfs_bcache_operations = { > - /* .hash */ libxfs_bhash, > - /* .alloc */ libxfs_balloc, > - /* .flush */ libxfs_bflush, > - /* .relse */ libxfs_brelse, > - /* .compare */ libxfs_bcompare, > - /* .bulkrelse */libxfs_bulkrelse > + .hash = libxfs_bhash, > + .alloc = libxfs_balloc, > + .flush = libxfs_bflush, > + .relse = libxfs_brelse, > + .compare = libxfs_bcompare, > + .bulkrelse = libxfs_bulkrelse > }; > > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From sandeen@sandeen.net Mon Sep 22 09:45:52 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 5C9237F51 for ; Mon, 22 Sep 2014 09:45:52 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id F03A1AC005 for ; Mon, 22 Sep 2014 07:45:51 -0700 (PDT) X-ASG-Debug-ID: 1411397147-04bdf003a0ba220001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id zJB9SGETN5bcOkCi for ; Mon, 22 Sep 2014 07:45:47 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id F239063C0582; Mon, 22 Sep 2014 09:45:46 -0500 (CDT) Message-ID: <5420361C.1090500@sandeen.net> Date: Mon, 22 Sep 2014 09:45:48 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Brian Foster , Eric Sandeen CC: xfs-oss Subject: Re: [PATCH] xfs_repair: validate & fix inode CRCs References: <5418AC01.30006@redhat.com> <20140922131855.GA29156@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs_repair: validate & fix inode CRCs In-Reply-To: <20140922131855.GA29156@bfoster.bfoster> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1411397147 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9753 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/22/14 8:18 AM, Brian Foster wrote: > So we verify each inode first in process_inode_chunk() and then follow > on with process_dinode(). There's a comment further up in > process_dinode_int() that indicates we explicitly do not check the crc > at that point, presumably considering verify_mode. I only see one call > to each of verify_inode() and process_dinode() (in that order). The > other process_dinode_int() caller is verify_uncertain_dinode(), which > looks like it occurs ultimately from process_uncertain_aginodes() in > phase 3. > > I suppose that logic makes sense, but it's not totally clear tbh. We do > fix up the crc in the caller if the inode is marked dirty. It also seems > like it's possible to modify the inode before this point where we check > the crc. Given that, it seems like we could just add an "if > (!verify_mode)" hunk to the preexisting hascrc() hunk further up in the > function..? Ugh, I am not sure how I missed that we could have already modified it. Ok, that throws the whole thing out, I'll take another look. Thanks, -Eric From andi@firstfloor.org Mon Sep 22 09:56:21 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C61DF7F53 for ; Mon, 22 Sep 2014 09:56:21 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id B53728F8035 for ; Mon, 22 Sep 2014 07:56:18 -0700 (PDT) X-ASG-Debug-ID: 1411397776-04cb6c50e5b2fc0001-NocioJ Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by cuda.sgi.com with ESMTP id vwhYS5lgVe8VBt27 for ; Mon, 22 Sep 2014 07:56:17 -0700 (PDT) X-Barracuda-Envelope-From: andi@firstfloor.org X-Barracuda-Apparent-Source-IP: 192.55.52.93 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 22 Sep 2014 07:56:16 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.04,572,1406617200"; d="scan'208";a="603465231" Received: from tassilo.jf.intel.com (HELO tassilo.localdomain) ([10.7.201.157]) by fmsmga002.fm.intel.com with ESMTP; 22 Sep 2014 07:55:59 -0700 Received: by tassilo.localdomain (Postfix, from userid 1000) id 3DE60300D7A; Mon, 22 Sep 2014 07:55:59 -0700 (PDT) From: Andi Kleen To: Ben Myers Cc: linux-fsdevel@vger.kernel.org, tinguely@sgi.com, olaf@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> X-ASG-Orig-Subj: Re: [RFC v2] Unicode/UTF-8 support for XFS Date: Mon, 22 Sep 2014 07:55:59 -0700 In-Reply-To: <20140918195650.GI19952@sgi.com> (Ben Myers's message of "Thu, 18 Sep 2014 14:56:50 -0500") Message-ID: <87lhpbhfgg.fsf@tassilo.jf.intel.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Barracuda-Connect: mga11.intel.com[192.55.52.93] X-Barracuda-Start-Time: 1411397776 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9753 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Ben Myers writes: > > Strings are normalized using a trie that stores the relevant > information. The trie itself is about 250kB in size, and lives in a > separate module. So 250kB bloat -- and what does this fix exactly? Someone putting random ligatures into their file names and expecting the file to be the same as before. Can't they just not do that? -Andi From BATV+2673b30bf3b50f663555+4047+infradead.org+hch@bombadil.srs.infradead.org Mon Sep 22 12:35:57 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 546D07F4E for ; Mon, 22 Sep 2014 12:35:57 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 430D7304039 for ; Mon, 22 Sep 2014 10:35:53 -0700 (PDT) X-ASG-Debug-ID: 1411407346-04cb6c50e7badc0001-NocioJ Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) by cuda.sgi.com with ESMTP id gGJ7nc9VopPFOHs6 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 22 Sep 2014 10:35:47 -0700 (PDT) X-Barracuda-Envelope-From: BATV+2673b30bf3b50f663555+4047+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XW7Wb-0006nd-HA for xfs@oss.sgi.com; Mon, 22 Sep 2014 17:35:45 +0000 Date: Mon, 22 Sep 2014 10:35:45 -0700 From: Christoph Hellwig To: xfs@oss.sgi.com Subject: beginners project: RENAME_EXCHANGE Message-ID: <20140922173545.GA20308@infradead.org> X-ASG-Orig-Subj: beginners project: RENAME_EXCHANGE MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: bombadil.infradead.org[198.137.202.9] X-Barracuda-Start-Time: 1411407347 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9758 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- As people are looking for beginners projects one in a while there's an easy one at the moment: implement support for the RENAME_EXCHANGE flag to the renameat2 system call, which swaps the names for two existing files. Documentation here: http://man7.org/linux/man-pages/man2/rename.2.html This should mostly be doable by refactoring (or more likely copy & pasting) the existing rename implementation. xfstests already has test case for it, although making sure they covering everything would be a nice extrea. (if no one replies to the list I will add it to the wiki after a while) From bpm@sgi.com Mon Sep 22 13:41:48 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B66D27F4E for ; Mon, 22 Sep 2014 13:41:48 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8C8D4304032; Mon, 22 Sep 2014 11:41:45 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 52E584266DC; Mon, 22 Sep 2014 13:41:45 -0500 (CDT) Date: Mon, 22 Sep 2014 13:41:45 -0500 From: Ben Myers To: Andi Kleen Cc: linux-fsdevel@vger.kernel.org, tinguely@sgi.com, olaf@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140922184145.GH4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <87lhpbhfgg.fsf@tassilo.jf.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <87lhpbhfgg.fsf@tassilo.jf.intel.com> User-Agent: Mutt/1.5.20 (2009-06-14) Hey Andi, On Mon, Sep 22, 2014 at 07:55:59AM -0700, Andi Kleen wrote: > Ben Myers writes: > > > > Strings are normalized using a trie that stores the relevant > > information. The trie itself is about 250kB in size, and lives in a > > separate module. > > So 250kB bloat -- and what does this fix exactly? We're trying to address the size issue by only loading the module when it's needed, but yeah it's big. Open to suggestions on how best to deal with that. I understand the sticker shock. > Someone putting random ligatures into their file names and expecting > the file to be the same as before. Can't they just not do that? The ligature example that Olaf gave might seem kind of trivial, but for other characters and languages could it be more significant? As far as telling the customer "don't do that", my guess is that they would just go elsewhere. There are several other options for filesystems that support unicode. Thanks, Ben From andi@firstfloor.org Mon Sep 22 14:30:05 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 5A0C87F4E for ; Mon, 22 Sep 2014 14:30:05 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id ED109AC004 for ; Mon, 22 Sep 2014 12:30:01 -0700 (PDT) X-ASG-Debug-ID: 1411414198-04cbb07301c1300001-NocioJ Received: from one.firstfloor.org (one.firstfloor.org [193.170.194.197]) by cuda.sgi.com with ESMTP id uDna5WuBUHRCrmyB (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 22 Sep 2014 12:30:00 -0700 (PDT) X-Barracuda-Envelope-From: andi@firstfloor.org X-Barracuda-Apparent-Source-IP: 193.170.194.197 Received: by one.firstfloor.org (Postfix, from userid 503) id 24AC386A02; Mon, 22 Sep 2014 21:29:58 +0200 (CEST) Date: Mon, 22 Sep 2014 21:29:58 +0200 From: Andi Kleen To: Ben Myers Cc: Andi Kleen , linux-fsdevel@vger.kernel.org, tinguely@sgi.com, olaf@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140922192958.GJ4120@two.firstfloor.org> X-ASG-Orig-Subj: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <87lhpbhfgg.fsf@tassilo.jf.intel.com> <20140922184145.GH4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140922184145.GH4482@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) X-Barracuda-Connect: one.firstfloor.org[193.170.194.197] X-Barracuda-Start-Time: 1411414199 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9761 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- > > So 250kB bloat -- and what does this fix exactly? > > We're trying to address the size issue by only loading the module when I'm not sure this is really addressing it. > it's needed, but yeah it's big. Open to suggestions on how best to deal > with that. I understand the sticker shock. I don't even understand why you need the whole table. You want to not compare some special symbols, and a few other symbols are equivalent to others. But most symbols are only identical to themselves. Couldn't you have a much smaller table that only expresses the exceptions? > As far as telling the customer "don't do that", my guess is that they > would just go elsewhere. There are several other options for > filesystems that support unicode. They could put some code into their user app that generates an unique representation. -Andi From bfoster@redhat.com Mon Sep 22 14:40:31 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 0C5447F50 for ; Mon, 22 Sep 2014 14:40:31 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8EC28AC001 for ; Mon, 22 Sep 2014 12:40:30 -0700 (PDT) X-ASG-Debug-ID: 1411414828-04cbb07304c1ce0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id FZYHPO52QwGo7ZEl (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 22 Sep 2014 12:40:29 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8MJeKdD019980 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 22 Sep 2014 15:40:20 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8MJeKqR011925; Mon, 22 Sep 2014 15:40:20 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 91A92120064; Mon, 22 Sep 2014 15:40:18 -0400 (EDT) Date: Mon, 22 Sep 2014 15:40:18 -0400 From: Brian Foster To: Dave Chinner Cc: fstests@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH] xfs/062: add xfs unwritten extent data corruption reproducer Message-ID: <20140922194018.GA39580@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs/062: add xfs unwritten extent data corruption reproducer References: <1411150385-32121-1-git-send-email-bfoster@redhat.com> <20140920234500.GK4267@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140920234500.GK4267@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411414829 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Sun, Sep 21, 2014 at 09:45:00AM +1000, Dave Chinner wrote: > On Fri, Sep 19, 2014 at 02:13:05PM -0400, Brian Foster wrote: > > XFS had a data corruption problem where writeback of pages to unwritten > > extents would fail to run unwritten extent conversion at I/O completion. > > This causes subsequent reads of written, but unconverted regions to > > return zeroes. This occurs on sub-page block size filesystems when > > writeback contends for the inode lock (e.g., with a file writer). > > > > Add a test that creates the conditions to reproduce the data corruption > > and detect it by looking for unwritten extents after all said extents > > have been overwritten. > > > > Signed-off-by: Brian Foster > > --- > > > > Hi all, > > > > Here's a test for the data corruption issue I sent a fix for yesterday: > > > > http://oss.sgi.com/archives/xfs/2014-09/msg00259.html > > > > It took a little time to improve the effectiveness of the test, but I've > > been able to run it in current form for 90+ iterations without a false > > negative (e.g., test passes when it shouldn't) on my setup. It runs in > > ~30s when there is no failure. > > > > Brian > > > > tests/xfs/062 | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > tests/xfs/062.out | 5 +++ > > tests/xfs/group | 1 + > > 3 files changed, 120 insertions(+) > > create mode 100755 tests/xfs/062 > > create mode 100644 tests/xfs/062.out > > There's nothing XFS specific about this test. Yes, it exposes a bug > on XFS, but every filesystem should be able to run and pass this > test. > Indeed, converted to a generic test. > > > > diff --git a/tests/xfs/062 b/tests/xfs/062 > > new file mode 100755 > > index 0000000..61f8cf4 > > --- /dev/null > > +++ b/tests/xfs/062 ... > > + if [ $? == 0 ] > > + then > > + xfs_bmap -v $SCRATCH_MNT/file > > + break > > + fi > > if [...]; then. > > That's also a failure, right? So shouldn't it set status=1 and exit, > leaving the cleanup function to kill and wait for everything to > finish? > It's the main/expected failure. The intent was to use the hexdump as the determination for success/failure, but I had to determine when to break out of the loop since the reproducer requires several iterations. I figured the raw extent map output would be useful (the output of which also calls out something is wrong when compared to the golden output) as well as the content diff, so both are printed in the failure case. I've added an additional comment here for the v2 I'm about to post. I can just dump the extent map here and exit with status=1 if that is preferred, but it seems appropriate to include the hexdump in the failure scenario as well. Brian > > +done > > + > > +echo $iters iterations > > + > > +kill $syncpid > > +wait > > + > > +# clear page cache and dump the file > > +_scratch_unmount > > +_scratch_mount > > _scratch_remount > > > +hexdump $SCRATCH_MNT/file > > + > > +_scratch_unmount > > +_check_scratch_fs > > Don't need to do that anymore. > > > + > > +status=0 > > +exit > > diff --git a/tests/xfs/062.out b/tests/xfs/062.out > > new file mode 100644 > > index 0000000..420f2e4 > > --- /dev/null > > +++ b/tests/xfs/062.out > > @@ -0,0 +1,5 @@ > > +QA output created by 062 > > +100 iterations > > +0000000 cdcd cdcd cdcd cdcd cdcd cdcd cdcd cdcd > > +* > > +0100000 > > diff --git a/tests/xfs/group b/tests/xfs/group > > index 09bce15..685cbe7 100644 > > --- a/tests/xfs/group > > +++ b/tests/xfs/group > > @@ -57,6 +57,7 @@ > > 059 dump ioctl auto quick > > 060 dump ioctl auto quick > > 061 dump ioctl auto quick > > +062 auto quick > > and the rw group, too. > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com From bfoster@redhat.com Mon Sep 22 14:40:40 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6AD937F55 for ; Mon, 22 Sep 2014 14:40:40 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 0A098AC008 for ; Mon, 22 Sep 2014 12:40:39 -0700 (PDT) X-ASG-Debug-ID: 1411414838-04bdf003a0cae60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id IoAqqAMag7tFEXj4 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 22 Sep 2014 12:40:39 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8MJecsF001234 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 22 Sep 2014 15:40:38 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8MJec4r013960; Mon, 22 Sep 2014 15:40:38 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id E658F120064; Mon, 22 Sep 2014 15:40:36 -0400 (EDT) From: Brian Foster To: fstests@vger.kernel.org Cc: xfs@oss.sgi.com Subject: [PATCH v2] generic/032: add xfs unwritten extent data corruption reproducer Date: Mon, 22 Sep 2014 15:40:36 -0400 X-ASG-Orig-Subj: [PATCH v2] generic/032: add xfs unwritten extent data corruption reproducer Message-Id: <1411414836-64598-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411414839 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 XFS had a data corruption problem where writeback of pages to unwritten extents would fail to run unwritten extent conversion at I/O completion. This causes subsequent reads of written, but unconverted regions to return zeroes. This occurs on sub-page block size filesystems when writeback contends for the inode lock (e.g., with a file writer). Add a test that creates the conditions to reproduce the data corruption and detect it by looking for unwritten extents after all said extents have been overwritten. Signed-off-by: Brian Foster --- v2: - Converted to generic test. - Use fiemap instead of xfs_bmap. - Added to rw group. - Various fixups: init/clean $tmp, loop syntax, redirect output to $seqres.full, use _scratch_remount. v1: http://oss.sgi.com/archives/xfs/2014-09/msg00296.html tests/generic/032 | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/032.out | 5 +++ tests/generic/group | 1 + 3 files changed, 125 insertions(+) create mode 100755 tests/generic/032 create mode 100644 tests/generic/032.out diff --git a/tests/generic/032 b/tests/generic/032 new file mode 100755 index 0000000..deaeba8 --- /dev/null +++ b/tests/generic/032 @@ -0,0 +1,119 @@ +#! /bin/bash +# FS QA Test No. 032 +# +# This test implements a data corruption scenario on XFS filesystems with +# sub-page sized blocks and unwritten extents. Inode lock contention during +# writeback of pages to unwritten extents leads to failure to convert those +# extents on I/O completion. This causes data corruption as unwritten extents +# are always read back as zeroes. +# +#----------------------------------------------------------------------- +# Copyright (c) 2014 Red Hat, Inc. All Rights Reserved. +# +# This program 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. +# +# This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + kill -9 $syncpid > /dev/null 2>&1 + wait + rm -f $tmp.* +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/punch + +# real QA test starts here +rm -f $seqres.full + +_syncloop() +{ + while [ true ]; do + sync + done +} + +# Modify as appropriate. +_supported_fs generic +_supported_os Linux +_require_scratch +_require_xfs_io_command "falloc" +_require_xfs_io_command "fiemap" + +_scratch_mkfs >/dev/null 2>&1 +_scratch_mount + +# run background sync thread +_syncloop & +syncpid=$! + +for iters in $(seq 1 100) +do + rm -f $SCRATCH_MNT/file + + # create a delalloc block in each page of the first 64k of the file + for pgoff in $(seq 0 0x1000 0xf000); do + offset=$((pgoff + 0xc00)) + $XFS_IO_PROG -f \ + -c "pwrite $offset 0x1" \ + $SCRATCH_MNT/file >> $seqres.full 2>&1 + done + + # preallocate the first 64k and overwite, writing past 64k to contend + # with writeback + $XFS_IO_PROG \ + -c "falloc 0 0x10000" \ + -c "pwrite 0 0x100000" \ + -c "fsync" \ + $SCRATCH_MNT/file >> $seqres.full 2>&1 + + # Check for unwritten extents. We should have none since we wrote over + # the entire preallocated region and ran fsync. + $XFS_IO_PROG \ + -c "fiemap -v" \ + $SCRATCH_MNT/file | _filter_fiemap | \ + grep unwritten >> $seqres.full 2>&1 + if [ $? == 0 ]; then + # data corruption! dump the extent list and break out to dump + # the file content + $XFS_IO_PROG -c "fiemap -v" $SCRATCH_MNT/file + break + fi +done + +echo $iters iterations + +kill $syncpid +wait + +# clear page cache and dump the file +_scratch_remount +hexdump $SCRATCH_MNT/file + +_scratch_unmount + +status=0 +exit diff --git a/tests/generic/032.out b/tests/generic/032.out new file mode 100644 index 0000000..ca5376d --- /dev/null +++ b/tests/generic/032.out @@ -0,0 +1,5 @@ +QA output created by 032 +100 iterations +0000000 cdcd cdcd cdcd cdcd cdcd cdcd cdcd cdcd +* +0100000 diff --git a/tests/generic/group b/tests/generic/group index bdcfd9d..8e0c22a 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -31,6 +31,7 @@ 026 acl quick auto 027 auto enospc 028 auto quick +032 auto quick rw 053 acl repair auto quick 062 attr udf auto quick 068 other auto freeze dangerous stress -- 1.8.3.1 From david@fromorbit.com Mon Sep 22 15:54:46 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id D91BA7F4E for ; Mon, 22 Sep 2014 15:54:46 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id B7B30304048 for ; Mon, 22 Sep 2014 13:54:46 -0700 (PDT) X-ASG-Debug-ID: 1411419280-04cbb07302c4eb0001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id NAVtheAUvvfNBDnk for ; Mon, 22 Sep 2014 13:54:41 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AkI6AIeLIFR5LM9HPGdsb2JhbABggw5TV7YbBpQ2gVuFagICAQEBgRIXAQYBAQEBODiEAwEBAQQ6HCMQCAMOBwMJJQ8FJQMHGhMJiDQOxGoYGIV1iXkHhEsFj0CNVZlGKy8BAQGCRwEBAQ Received: from ppp121-44-207-71.lns20.syd7.internode.on.net (HELO dastard) ([121.44.207.71]) by ipmail06.adl6.internode.on.net with ESMTP; 23 Sep 2014 06:24:39 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XWAd4-0004pE-R2; Tue, 23 Sep 2014 06:54:38 +1000 Date: Tue, 23 Sep 2014 06:54:38 +1000 From: Dave Chinner To: Ben Myers Cc: linux-fsdevel@vger.kernel.org, tinguely@sgi.com, olaf@sgi.com, xfs@oss.sgi.com Subject: Re: [PATCH 06/10] xfs: add unicode character database files Message-ID: <20140922205438.GM4267@dastard> X-ASG-Orig-Subj: Re: [PATCH 06/10] xfs: add unicode character database files References: <20140918195650.GI19952@sgi.com> <20140918201440.GI4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918201440.GI4482@sgi.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1411419280 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9764 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 18, 2014 at 03:14:40PM -0500, Ben Myers wrote: > From: Olaf Weber > > Add files from the Unicode Character Database, version 7.0.0, to the source. > A helper program that generates a trie used for normalization from these > files is part of a separate commit. > > Signed-off-by: Olaf Weber > --- > [v2: Removed large unicode files prior to posting. Get them as below. -bpm] > [v3: Moved files to ucd8norm directory. -bpm] > > cd fs/xfs/utf8norm/ucd > wget http://www.unicode.org/Public/7.0.0/ucd/CaseFolding.txt > wget http://www.unicode.org/Public/7.0.0/ucd/DerivedAge.txt > wget http://www.unicode.org/Public/7.0.0/ucd/extracted/DerivedCombiningClass.txt > wget http://www.unicode.org/Public/7.0.0/ucd/DerivedCoreProperties.txt > wget http://www.unicode.org/Public/7.0.0/ucd/NormalizationCorrections.txt > wget http://www.unicode.org/Public/7.0.0/ucd/NormalizationTest.txt > wget http://www.unicode.org/Public/7.0.0/ucd/UnicodeData.txt > for e in *.txt > do > base=`basename $e .txt` > mv $e $base-7.0.0.txt > done > --- > fs/xfs/utf8norm/ucd/README | 33 +++++++++++++++++++++++++++++++++ This probably needs to live somewhere under lib/. There's nothing XFS specific in it and the translations should be the same for anything that wants to parse unicode. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Sep 22 15:57:21 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 659927F4E for ; Mon, 22 Sep 2014 15:57:21 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 022E6AC007 for ; Mon, 22 Sep 2014 13:57:17 -0700 (PDT) X-ASG-Debug-ID: 1411419436-04bdf0039fce800001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id hgPmozFQ0JGotKGq for ; Mon, 22 Sep 2014 13:57:16 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ApVDAJ+MIFR5LM9HPGdsb2JhbABggw6BKoc4rmMGlhGFagICAQEBgRMXAQYBAQEBODiEAwEBAQQ6HCMQCAMOBwMJJQ8FJQMHGhOIPcUUGIV1iSFYB4RLBZ0VmUYrL4EGgUQBAQE Received: from ppp121-44-207-71.lns20.syd7.internode.on.net (HELO dastard) ([121.44.207.71]) by ipmail06.adl6.internode.on.net with ESMTP; 23 Sep 2014 06:27:15 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XWAfa-0004pu-FC; Tue, 23 Sep 2014 06:57:14 +1000 Date: Tue, 23 Sep 2014 06:57:14 +1000 From: Dave Chinner To: Ben Myers Cc: linux-fsdevel@vger.kernel.org, tinguely@sgi.com, olaf@sgi.com, xfs@oss.sgi.com Subject: Re: [PATCH 07/10] xfs: add trie generator and supporting code for UTF-8. Message-ID: <20140922205714.GN4267@dastard> X-ASG-Orig-Subj: Re: [PATCH 07/10] xfs: add trie generator and supporting code for UTF-8. References: <20140918195650.GI19952@sgi.com> <20140918201518.GJ4482@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918201518.GJ4482@sgi.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1411419436 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9764 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 18, 2014 at 03:15:19PM -0500, Ben Myers wrote: > From: Olaf Weber > > mkutf8data.c is the source for a program that generates utf8data.h, which > contains the trie that utf8norm.c uses. The trie is generated from the > Unicode 7.0.0 data files. The format of the utf8data[] table is described > in utf8norm.c. > > Supporting functions for UTF-8 normalization are in utf8norm.c with the > header utf8norm.h. Two normalization forms are supported: nfkdi and nfkdicf. > > nfkdi: > - Apply unicode normalization form NFKD. > - Remove any Default_Ignorable_Code_Point. > > nfkdicf: > - Apply unicode normalization form NFKD. > - Remove any Default_Ignorable_Code_Point. > - Apply a full casefold (C + F). > > For the purposes of the code, a string is valid UTF-8 if: > > - The values encoded are 0x1..0x10FFFF. > - The surrogate codepoints 0xD800..0xDFFFF are not encoded. > - The shortest possible encoding is used for all values. > > The supporting functions work on null-terminated strings (utf8 prefix) and > on length-limited strings (utf8n prefix). > > Signed-off-by: Olaf Weber > > --- > [v2: the trie is now separated into utf8norm.ko; > utf8version is now a function and exported; > introduced CONFIG_XFS_UTF8. -bpm] > --- > fs/xfs/Kconfig | 8 + > fs/xfs/Makefile | 2 +- > fs/xfs/utf8norm/Makefile | 37 + > fs/xfs/utf8norm/mkutf8data.c | 3239 ++++++++++++++++++++++++++++++++++++++++++ > fs/xfs/utf8norm/utf8norm.c | 649 +++++++++ > fs/xfs/utf8norm/utf8norm.h | 116 ++ Again, nothing XFS specific here. It's being built as a separate module and the only thing that XFS uses are exported functions, so it really should be generic library code.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Sep 22 16:05:57 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2D30D7F4E for ; Mon, 22 Sep 2014 16:05:57 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id F2E7B8F8050 for ; Mon, 22 Sep 2014 14:05:53 -0700 (PDT) X-ASG-Debug-ID: 1411419950-04bdf003a2ceff0001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id xmBNTWd1vFVT1YA5 for ; Mon, 22 Sep 2014 14:05:51 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ArcoANyNIFR5LM9HPGdsb2JhbABggw6BKoc4rmMGlhGFagQCAYETFwEGAQEBATg4hAMBAQEDATocIwULCAMYCSUPBSUDBxoTiDYHxH8YGIV1iQ5rB4RLBYUNApgGmUYrL4JKAQEB Received: from ppp121-44-207-71.lns20.syd7.internode.on.net (HELO dastard) ([121.44.207.71]) by ipmail06.adl6.internode.on.net with ESMTP; 23 Sep 2014 06:35:50 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XWAnt-0004sO-1p; Tue, 23 Sep 2014 07:05:49 +1000 Date: Tue, 23 Sep 2014 07:05:49 +1000 From: Dave Chinner To: Alessio Di Maria Cc: xfs@oss.sgi.com Subject: Re: Repair XFS from 1/3 of the table Message-ID: <20140922210548.GO4267@dastard> X-ASG-Orig-Subj: Re: Repair XFS from 1/3 of the table References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1411419950 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9764 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 19, 2014 at 10:58:49PM +0200, Alessio Di Maria wrote: > Hi, for fist i'm sorry for my bad English.. > so, > I'm trying to do a recovery from my NAS, > After it stopped, 3 disk of 4 was reinitialized so, raid partition was > deleted on disk 1 2 and 3, and first about 5m was zero filled.. So you lost the root inode and a lot of other critical metadata. > I'm actually work on a copy of that... > in my luck, the XFS superblock was on 4th disk.. > I was able to rebuild RAID5 with the original configuration and now i can > read RAW files up to few kb... i was able to read a 15Mb zip file, and some > big jpeg, so i can say that RAID it's working fine > > At sector 384 of the raid volume start the xfs superblock, i made a > loopback at this offset, > mounting it.. but obviusly it said that was not clean. > making xfs_repair i get anything, but with xfs_repair -L i had infinite > list of lost inode, and than i was able to mount the partition, > but with any file, only the lost + found directory with few but complete > files... That happens when you lose the root inode. > On the NAS there were Big Files of ISCSI, in the lost + found i find one of > this, big 100Gb.. now i don't know how i can recovery the rest.. If you had regions of of the drives zeroed, then you've lost data randomly in the files in the filesystem. It's basically unrecoverable if you don't have a backup. > Is it possible to find lost inode? You can google for xfs_irecover, but you've already run xfs_repair and so it's going to be mostly useless at this point. > i tryied with many programs to get back the original Filesystem but > anything up the Lost + Found directory after the repair... > I know that XFS is based on sparse file, and so i can't find my file and > hope to copy it contigusly (about 5Gb) cose the fs reidirect zero filled > zone... in addiction i can't do a RAW recovery cose in the deep of 2.7Tb i > find MFT entryies and system files inner ISCSI units... > So what chache? > Wha can i do myself? If xfs_repair hasn't recovered the inodes that contained the files you care about, then it's almost certain that you've lost those files forever unless you have a backup. You can try grepping the raw device for sectors that contain signatures you care about, but that only works for contiguous files that were lost (that's effectively what photorec does). Other than that, there's nothing that can be done to recover what has been lost from the corpse you have on your hands... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Sep 22 17:26:20 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2FDEF7F4E for ; Mon, 22 Sep 2014 17:26:20 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0D6B68F8039 for ; Mon, 22 Sep 2014 15:26:20 -0700 (PDT) X-ASG-Debug-ID: 1411424773-04cb6c50e4c7ca0001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id CkRlT8bSvvfHsW8d for ; Mon, 22 Sep 2014 15:26:14 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Am0iAJqgIFR5LM9HPGdsb2JhbABggw5TV7YbBpQ0gV2FagQCAYETFwEGAQEBATg4hAMBAQEDATocIwULCAMOCgkDIg8FJQMHGhMZiB0HDsVQGIV1h2eCEgeESwWGII9vhwaBYopTiwcfgWsrLwGBBySBHgEBAQ Received: from ppp121-44-207-71.lns20.syd7.internode.on.net (HELO dastard) ([121.44.207.71]) by ipmail06.adl6.internode.on.net with ESMTP; 23 Sep 2014 07:56:13 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XWC3f-00057x-7k; Tue, 23 Sep 2014 08:26:11 +1000 Date: Tue, 23 Sep 2014 08:26:11 +1000 From: Dave Chinner To: Ben Myers Cc: linux-fsdevel@vger.kernel.org, tinguely@sgi.com, olaf@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140922222611.GZ4322@dastard> X-ASG-Orig-Subj: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140918195650.GI19952@sgi.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1411424773 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9767 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 18, 2014 at 02:56:50PM -0500, Ben Myers wrote: > Hi, > > I'm posting this RFC for Unicode support in XFS on Olaf's behalf, as he > is busy with other projects. This is the second revision of the series. > The first is available here: > > http://oss.sgi.com/archives/xfs/2014-09/msg00169.html > > In response to the initial feedback, the changes in version 2 include: > > * linux-fsdevel in the To: line, > * Updated design notes, > * Separation of the fs-independent trie and support code into utf8norm.ko, > * A mechanism for loading the normalization module only when necessary. > > I'll post the whole series for completeness sake. Many on -fsdevel will > not be interested in the xfs-specific bits, but it may be helpful to > have the full series as an example and for testing purposes. > > First there is a set of kernel bits, then some libxfs/xfsprogs stuff, > and finally a test. (Note: I am not posting the unicode database files > due to their large size. There are scripts to download them from > unicode.org in the relevant commit headers.) > > TODO: Store the unicode version number of the filesystem on disk in the > super block. So, if the filesystem has to store the specific unicode version it was created with so that we know what version to put in trie lookups, again I'll ask: why are we loading the trie as a generic kernel module and not as metadata in the filesystem that is demand paged and cached? i.e. put the entire trie on disk, look up the specific conversion required for the name being compared, and then cache that conversion in memory. This makes repeated lookups much faster because the trie only contains conversions that are in use, the memory footprint is way lower and the conversions are guaranteed to be consistent for the life of the filesystem.... > Here are Olaf's design notes: > > ----------------------------------------------------------------------------- > Unicode/UTF-8 support for XFS > > So we had a customer request proper unicode support... > > > * What does "supporting unicode" actually mean? > > From a text processing point of view, what a filesystem does with > filenames is simple: it stores and retrieves them, and compares them > for equality. It may reject certain byte sequences as invalid > filenames (for example, no filename can contain an ASCII NUL). > > I've been taking it as a given that when a file is created with a > certain byte sequence as its name, then a subsequent directory listing > will contain that same byte sequence among the names listed. > > This leaves comparing names for equality, and in my view this is what > "supporting unicode" revolves about. > > The present state of affairs is that different byte sequences are > different filenames. This amounts to tolerating unicode without > actually supporting it. That's somewhat circular - using your own definition of "supported" to argue that your own definition is the right one.... > To support unicode we have to interpret filenames. What happens when > (part of) a filename cannot be interpreted? We can reject the > filename, interpret the parts we can, or punt and accept it as an > uninterpreted blob. > > Rejecting ill-formed filenames was my first choice, but I came around > on the issue: there are too many ways in which you can end up with > having to deal with ill-formed filenames that would leave a user with > no recourse but to move whatever they're doing to a different > filesystem. Unpacking a tarball with filenames in a different encoding > is an example. You still haven't addressed this: | So we accept invalid unicode in filenames, but only after failing to | parse them? Isn't this a potential vector for exploiting weaknesses | in application filename handling? i.e. unprivileged user writes | specially crafted invalid unicode filename to disk, setuid program | tries to parse it, invalid sequence triggers a buffer overflow bug | in setuid parser? apart from handwaving that userspace has to be able to handle invalid utf-8 already. Why should we let filesystems say "we fully understand and support utf8" and then allow them to accept and propagate invalid utf8 sequences and leave everyone else to have to clean up the mess? > Partial interpretation of an ill-formed filename just strikes me as > the kind of bad idea that most half-houses are. I admit that I have no > stronger objection to this than the fact that it makes the code even > more complicated and fragile. > > Which leaves "blob" as the preferred option by default for coping with > ill-formed filenames. And so can't be case-folded, leading to inconsistent behaviour of case-insensitive filename comparisons. I don't blindly subscribe to the robustness principle of "be liberal with what you accept". Being liberal means accepting malformed junk and then trying to make good. It's a fool's game - we've learnt time and time again that if we don't fully validate string inputs that we have to interpret then someone will find an exploit that utilises malformed strings. I don't think we should expose core kernel code to such structural weaknesses... > When comparing well-formed filenames, the question now becomes which > byte sequences are considered to be alternative spellings of the same > filename. This is where normalization forms come into play, and the > unicode standard has quite a bit to say about the subject. > > If all you're doing is comparison, then choosing NFD over NFC is easy, > because the former is easier to calculate than the latter. > > If you want various spellings of "office" to compare equal, then > picking NFKD over NFD for comparison is also an obvious > choice. (Hand-picking individual compatibility forms is truly a bad > idea.) Ways to spell "office": "o_f_f_i_c_e", "o_f_fi_c_e", and > "o_ffi_c_e", using no ligatures, the fi ligature, or the ffi > ligature. (Some fool thought it a good idea to add these ligatures to > unicode, all we get to decide is how to cope.) Yet normalised strings are only stable and hence comparable if there are no unassigned code points in them. What happens when userspace is not using the same version of unicode as the filesystem and is using newer code points in it's strings? Normalisation fails, right? And as an extension of using normalisation for case-folded comparisons, how do we make case folding work with blobs that can't be normalised? It seems to me that this just leads to the nasty situation where some filenames are case sensitive and some aren't based on what the filesystem thinks is valid utf-8. The worst part is that userspace has no idea that the filesystem is making such distinctions and so behaviour is not at all predictable or expected. This is another point in favour of rejecting invalid utf-8 strings and for keeping the translation tables stable within the filesystem... > The most contentious part is (should be) ignoring the codepoints with > the Default_Ignorable_Code_Point property. I've included the list > below. My argument, such as it is, is that these code points either > have no visible rendering, or in cases like the soft hyphen, are only > conditionally visible. The problem with these (as I see it) is that on > seeing a filename that might contain them you cannot tell whether they > are present. So I propose to ignore them for the purpose of comparing > filenames for equality. Which introduces a non-standard "visibility criterial" for determining what should be or shouldn't be part of the normalised string for comparison. I don't see any real justification for stepping outside the standard unicode normalisation here - just because the user cannot see a character in a specific context does not mean that it is not significant to the application that created it. > Finally, case folding. First of all, it is optional. Then the issue is > that you either go the language-specific route, or simplify the task > by "just" doing a full casefold (C+F, in unicode parlance). Looking > around the net I tend to find that if you're going to do casefolding > at all, then a language-independent full casefold is preferred because > it is the most predictable option. See > http://www.w3.org/TR/charmod-norm/ for an example of that kind of > reasoning. Which says in section 2.4: "Some languages need case-folding to be tailored to meet specific linguistic needs". That implies that the case folding needs to be language aware and hence needs to be tied into the NLS subsystem for handling specific quirks like Turkic. I also note that it says in several places that C+F can result in a folded string of a different length. What happens when that folded string is longer than 255 bytes and hence longer than NAME_MAX? That's a bit of a nasty landmine for pathname string handling functions - developers are going to assume that pathname components are not longer than NAME_MAX, and if we are passing normalised strings around that is not a valid assumption.... > * XFS-specific design notes. ... > If the borgbit (the bit enabling legacy ASCII-based CI in XFS) is set > in the superblock, then case folding is added into the mix. This is > the nfkdicf normalization form mentioned above. It allows for the > creation of case-insensitive filesystems with UTF-8 support. Please don't overload existing superblock feature bits with multiple meanings. ASCII-CI is a stand-alone feature and is not in any way compatible with Unicode: Unicode-CI is a superset of Unicode support. So it really needs two new feature bits for Unicode and Unicode-CI, not just one for unicode. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Sep 22 20:27:05 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 662477F4E for ; Mon, 22 Sep 2014 20:27:05 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5210330404E for ; Mon, 22 Sep 2014 18:27:05 -0700 (PDT) X-ASG-Debug-ID: 1411435619-04cb6c50e5ce470001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id ZpBOvdCh0WOORy22 for ; Mon, 22 Sep 2014 18:27:00 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ApNDALzLIFR5LM9HPGdsb2JhbABggw6BKoc4rmkGlhGFagICAQEBgRQXAQYBAQEBODiEBAEBBDocIxAIAw4KCSUPBSUDBxoTiD3FdRgYhXWJeQeESwWdFZlGKy+CSgEBAQ Received: from ppp121-44-207-71.lns20.syd7.internode.on.net (HELO dastard) ([121.44.207.71]) by ipmail05.adl6.internode.on.net with ESMTP; 23 Sep 2014 10:56:57 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XWEsa-0005VT-JP; Tue, 23 Sep 2014 11:26:56 +1000 Date: Tue, 23 Sep 2014 11:26:56 +1000 From: Dave Chinner To: Brian Foster Cc: fstests@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH v2] generic/032: add xfs unwritten extent data corruption reproducer Message-ID: <20140923012656.GP4267@dastard> X-ASG-Orig-Subj: Re: [PATCH v2] generic/032: add xfs unwritten extent data corruption reproducer References: <1411414836-64598-1-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411414836-64598-1-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1411435619 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=MARKETING_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9772 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words On Mon, Sep 22, 2014 at 03:40:36PM -0400, Brian Foster wrote: > XFS had a data corruption problem where writeback of pages to unwritten > extents would fail to run unwritten extent conversion at I/O completion. > This causes subsequent reads of written, but unconverted regions to > return zeroes. This occurs on sub-page block size filesystems when > writeback contends for the inode lock (e.g., with a file writer). > > Add a test that creates the conditions to reproduce the data corruption > and detect it by looking for unwritten extents after all said extents > have been overwritten. > > Signed-off-by: Brian Foster I still think the error handling for the unwritten extent case is wrong. Failure debug is exactly what $seqres.full is for, so that's where failure information should go. If we detect a failure case and have to abort immediately, then _fail() should be used. And _fail() leaves a message to look at $seqres.full for details. So: > + # Check for unwritten extents. We should have none since we wrote over > + # the entire preallocated region and ran fsync. > + $XFS_IO_PROG \ > + -c "fiemap -v" \ > + $SCRATCH_MNT/file | _filter_fiemap | \ > + grep unwritten >> $seqres.full 2>&1 > + if [ $? == 0 ]; then > + # data corruption! dump the extent list and break out to dump > + # the file content > + $XFS_IO_PROG -c "fiemap -v" $SCRATCH_MNT/file > + break > + fi Can simply be: $XFS_IO_PROG -c "fiemap -v" $SCRATCH_MNT/file | \ tee -a $seqres.full | \ filter_fiemap | grep unwritten [ $? == 0 ] && _fail "Unwritten extents found!" and will result in the output: generic/032 0s.... [failed, exit status 1] - output mismatch (see ....results/generic/032.bad) And results/generic/032.bad will contain: .... Unwritten extents found! (see ..../results/generic/032.full for details) And the complete fiemap output will be in results/generic/032.full. > +done > + > +echo $iters iterations > + > +kill $syncpid > +wait > + > +# clear page cache and dump the file > +_scratch_remount > +hexdump $SCRATCH_MNT/file > + > +_scratch_unmount No need to unmount. check does that when checking the filesystem, and if not the next _require_scratch call will do it.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From cmaiolino@redhat.com Mon Sep 22 22:44:23 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 42F987F4E for ; Mon, 22 Sep 2014 22:44:23 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 308AD304039 for ; Mon, 22 Sep 2014 20:44:19 -0700 (PDT) X-ASG-Debug-ID: 1411443858-04cbb07302d4960001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id T2VjMj7o92zG286F (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 22 Sep 2014 20:44:19 -0700 (PDT) X-Barracuda-Envelope-From: cmaiolino@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8N3htO8005145 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 22 Sep 2014 23:43:55 -0400 Received: from localhost.localdomain (ovpn-113-183.phx2.redhat.com [10.3.113.183]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8N3hqdh003352 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Mon, 22 Sep 2014 23:43:54 -0400 Date: Tue, 23 Sep 2014 00:43:52 -0300 From: Carlos Maiolino To: Christoph Hellwig Cc: xfs@oss.sgi.com Subject: Re: beginners project: RENAME_EXCHANGE Message-ID: <20140923034351.GB25353@localhost.localdomain> X-ASG-Orig-Subj: Re: beginners project: RENAME_EXCHANGE Mail-Followup-To: Christoph Hellwig , xfs@oss.sgi.com References: <20140922173545.GA20308@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140922173545.GA20308@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411443859 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hi, for some time I don't work on anything upstream due being very busy with another stuff, I'm interested in take this project if nobody has objections On Mon, Sep 22, 2014 at 10:35:45AM -0700, Christoph Hellwig wrote: > As people are looking for beginners projects one in a while there's > an easy one at the moment: implement support for the RENAME_EXCHANGE > flag to the renameat2 system call, which swaps the names for two > existing files. Documentation here: > > http://man7.org/linux/man-pages/man2/rename.2.html > > This should mostly be doable by refactoring (or more likely copy & > pasting) the existing rename implementation. xfstests already has test > case for it, although making sure they covering everything would be a > nice extrea. > > (if no one replies to the list I will add it to the wiki after a while) > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs -- Carlos From service@epost.com Mon Sep 22 23:21:10 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.2 required=5.0 tests=HTML_MESSAGE, HTML_MIME_NO_HTML_TAG,MIME_HTML_ONLY autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id CBCF97F4E for ; Mon, 22 Sep 2014 23:21:10 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id B73FF304039 for ; Mon, 22 Sep 2014 21:21:10 -0700 (PDT) X-ASG-Debug-ID: 1411446063-04cb6c50e4d35c0001-NocioJ Received: from mail.kopu.ee (154.233.159.217.sta.estpak.ee [217.159.233.154]) by cuda.sgi.com with ESMTP id BurnX448ysd0B2qX for ; Mon, 22 Sep 2014 21:21:04 -0700 (PDT) X-Barracuda-Envelope-From: service@epost.com X-Barracuda-Apparent-Source-IP: 217.159.233.154 Received: from localhost (localhost.localdomain [127.0.0.1]) by mail.kopu.ee (Postfix) with ESMTP id 76DF81E2300 for ; Tue, 23 Sep 2014 07:21:03 +0300 (EEST) Received: from mail.kopu.ee ([127.0.0.1]) by localhost (mail.kopu.ee [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id gDx+XjDi8tBr for ; Tue, 23 Sep 2014 07:21:03 +0300 (EEST) Received: from localhost (localhost.localdomain [127.0.0.1]) by mail.kopu.ee (Postfix) with ESMTP id 53BC81E22FF for ; Tue, 23 Sep 2014 07:21:03 +0300 (EEST) Received: from 680client.digitalpound.net (unknown [216.107.148.250]) by mail.kopu.ee (Postfix) with ESMTPA id CBE731E2209 for ; Tue, 23 Sep 2014 07:21:02 +0300 (EEST) MIME-Version: 1.0 From: "mail service center" Reply-To: service@epost.com To: xfs@oss.sgi.com Subject: xfs@oss.sgi.com Periodic Account Verification Content-Type: text/html; charset="windows-1252" X-ASG-Orig-Subj: xfs@oss.sgi.com Periodic Account Verification Content-Transfer-Encoding: quoted-printable X-Mailer: Smart_Send_2_0_138 Date: Mon, 22 Sep 2014 21:20:32 -0700 Message-ID: <2364353832664410921192@WIN-8GU2GFQBBV1> X-Barracuda-Connect: 154.233.159.217.sta.estpak.ee[217.159.233.154] X-Barracuda-Start-Time: 1411446064 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.85 X-Barracuda-Spam-Status: No, SCORE=1.85 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_MJ1963, HTML_MESSAGE, HTML_MIME_NO_HTML_TAG, MIME_HTML_ONLY, PR0N_SUBJECT, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9776 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts 0.00 HTML_MESSAGE BODY: HTML included in message 1.05 HTML_MIME_NO_HTML_TAG HTML-only message, but there is no HTML tag 0.20 PR0N_SUBJECT Subject has letters around special characters (pr0n) 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963

D= ear user, (xfs@oss.sgi.com ­­)<=3Fxml:namespace prefix =3D o ns =3D "urn:sc= hemas-microsoft-com:office:office" />

<= BR>Your Email, (xfs@oss.sgi.com ­­) is yet to be verified as required by our new online secur= ity policy.

F= ailures to verify within 48 hours will result in permanent closure.

Please sign in t= o your account A using the link below and update you= r account.  

UPD= ATE NOW

If you have addi= tional questions about account safety, please visit our Help page 

Thanks, 
mail service center

C= opyright 2014 Mail Service Inc.<= /SPAN>

 

 

From bfoster@redhat.com Tue Sep 23 07:42:30 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 57D397F3F for ; Tue, 23 Sep 2014 07:42:30 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 37BFD304053 for ; Tue, 23 Sep 2014 05:42:27 -0700 (PDT) X-ASG-Debug-ID: 1411476145-04cb6c50e4e1ec0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id yGaoQDtUyCU5QuL7 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 23 Sep 2014 05:42:26 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8NCgPmF005327 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 23 Sep 2014 08:42:25 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8NCgOr9004082; Tue, 23 Sep 2014 08:42:25 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 19740120064; Tue, 23 Sep 2014 08:42:24 -0400 (EDT) From: Brian Foster To: fstests@vger.kernel.org Cc: xfs@oss.sgi.com Subject: [PATCH v3] generic/032: add xfs unwritten extent data corruption reproducer Date: Tue, 23 Sep 2014 08:42:24 -0400 X-ASG-Orig-Subj: [PATCH v3] generic/032: add xfs unwritten extent data corruption reproducer Message-Id: <1411476144-51074-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411476146 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 XFS had a data corruption problem where writeback of pages to unwritten extents would fail to run unwritten extent conversion at I/O completion. This causes subsequent reads of written, but unconverted regions to return zeroes. This occurs on sub-page block size filesystems when writeback contends for the inode lock (e.g., with a file writer). Add a test that creates the conditions to reproduce the data corruption and detect it by looking for unwritten extents after all said extents have been overwritten. Signed-off-by: Brian Foster --- v3: - Exit test (_fail) on unwritten extent detection. v2: http://oss.sgi.com/archives/xfs/2014-09/msg00315.html - Converted to generic test. - Use fiemap instead of xfs_bmap. - Added to rw group. - Various fixups: init/clean $tmp, loop syntax, redirect output to $seqres.full, use _scratch_remount. v1: http://oss.sgi.com/archives/xfs/2014-09/msg00296.html tests/generic/032 | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/032.out | 5 +++ tests/generic/group | 1 + 3 files changed, 117 insertions(+) create mode 100755 tests/generic/032 create mode 100644 tests/generic/032.out diff --git a/tests/generic/032 b/tests/generic/032 new file mode 100755 index 0000000..53fb3de --- /dev/null +++ b/tests/generic/032 @@ -0,0 +1,111 @@ +#! /bin/bash +# FS QA Test No. 032 +# +# This test implements a data corruption scenario on XFS filesystems with +# sub-page sized blocks and unwritten extents. Inode lock contention during +# writeback of pages to unwritten extents leads to failure to convert those +# extents on I/O completion. This causes data corruption as unwritten extents +# are always read back as zeroes. +# +#----------------------------------------------------------------------- +# Copyright (c) 2014 Red Hat, Inc. All Rights Reserved. +# +# This program 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. +# +# This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + kill -9 $syncpid > /dev/null 2>&1 + wait + rm -f $tmp.* +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/punch + +# real QA test starts here +rm -f $seqres.full + +_syncloop() +{ + while [ true ]; do + sync + done +} + +# Modify as appropriate. +_supported_fs generic +_supported_os Linux +_require_scratch +_require_xfs_io_command "falloc" +_require_xfs_io_command "fiemap" + +_scratch_mkfs >/dev/null 2>&1 +_scratch_mount + +# run background sync thread +_syncloop & +syncpid=$! + +for iters in $(seq 1 100) +do + rm -f $SCRATCH_MNT/file + + # create a delalloc block in each page of the first 64k of the file + for pgoff in $(seq 0 0x1000 0xf000); do + offset=$((pgoff + 0xc00)) + $XFS_IO_PROG -f \ + -c "pwrite $offset 0x1" \ + $SCRATCH_MNT/file >> $seqres.full 2>&1 + done + + # preallocate the first 64k and overwite, writing past 64k to contend + # with writeback + $XFS_IO_PROG \ + -c "falloc 0 0x10000" \ + -c "pwrite 0 0x100000" \ + -c "fsync" \ + $SCRATCH_MNT/file >> $seqres.full 2>&1 + + # Check for unwritten extents. We should have none since we wrote over + # the entire preallocated region and ran fsync. + $XFS_IO_PROG -c "fiemap -v" $SCRATCH_MNT/file | \ + tee -a $seqres.full | \ + _filter_fiemap | grep unwritten + [ $? == 0 ] && _fail "Unwritten extents found!" +done + +echo $iters iterations + +kill $syncpid +wait + +# clear page cache and dump the file +_scratch_remount +hexdump $SCRATCH_MNT/file + +status=0 +exit diff --git a/tests/generic/032.out b/tests/generic/032.out new file mode 100644 index 0000000..ca5376d --- /dev/null +++ b/tests/generic/032.out @@ -0,0 +1,5 @@ +QA output created by 032 +100 iterations +0000000 cdcd cdcd cdcd cdcd cdcd cdcd cdcd cdcd +* +0100000 diff --git a/tests/generic/group b/tests/generic/group index bdcfd9d..8e0c22a 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -31,6 +31,7 @@ 026 acl quick auto 027 auto enospc 028 auto quick +032 auto quick rw 053 acl repair auto quick 062 attr udf auto quick 068 other auto freeze dangerous stress -- 1.8.3.1 From thomas.stagge@optimare.de Tue Sep 23 07:54:10 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id EC5F17F3F for ; Tue, 23 Sep 2014 07:54:10 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8FA3D304053 for ; Tue, 23 Sep 2014 05:54:10 -0700 (PDT) X-ASG-Debug-ID: 1411476841-04bdf003a2f14b0001-NocioJ Received: from mail.optimare.de (survey.optimare.de [82.198.200.60]) by cuda.sgi.com with ESMTP id 6KCsfaOtKxSP45Ql (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 23 Sep 2014 05:54:02 -0700 (PDT) X-Barracuda-Envelope-From: thomas.stagge@optimare.de X-Barracuda-Apparent-Source-IP: 82.198.200.60 Received: from [192.168.0.129] (192.168.0.129) by mail3 (Axigen) with (RC4-SHA encrypted) ESMTPSA id 157908; Tue, 23 Sep 2014 14:54:00 +0200 Message-ID: <54216D67.6090800@optimare.de> Date: Tue, 23 Sep 2014 14:53:59 +0200 From: Thomas Stagge User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: xfs@oss.sgi.com Subject: XFS kernal crash Content-Type: multipart/alternative; boundary="------------020208010800020302070003" X-ASG-Orig-Subj: XFS kernal crash X-AxigenVirus-Level: 1 X-AxigenSpam-Level: 4 X-Barracuda-Connect: survey.optimare.de[82.198.200.60] X-Barracuda-Start-Time: 1411476842 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9787 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message This is a multi-part message in MIME format. --------------020208010800020302070003 Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 8bit Hello, we have in the last few weeks always problems with the XFS file system. XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) After a certain time there is a kernel crash which looks as follows: September 23 10:17:57 hostname kernel: [1282081.010814] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:17:59 hostname kernel: [1282082.913437] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:01 hostname kernel: [1282084.908582] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:03 hostname kernel: [1282086.691791] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:05 hostname kernel: [1282088.691319] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:07 hostname kernel: [1282090.690182] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:09 hostname kernel: [1282092.673355] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:11 hostname kernel: [1282094.596504] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:13 hostname kernel: [1282096.595971] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:15 hostname kernel: [1282098.595301] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:17 hostname kernel: [1282100.594232] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:19 hostname kernel: [1282102.433262] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:21 hostname kernel: [1282104.412432] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:23 hostname kernel: [1282106.411598] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:25 hostname kernel: [1282108.310740] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:27 hostname kernel: [1282110.289892] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:29 hostname kernel: [1282112.289106] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:31 hostname kernel: [1282114.288247] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:33 hostname kernel: [1282116.215953] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:35 hostname kernel: [1282118.198488] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:37 hostname kernel: [1282120.193686] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:39 hostname kernel: [1282122.288716] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:41 hostname kernel: [1282124.215970] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:43 hostname kernel: [1282126.307031] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:45 hostname kernel: [1282128.306190] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:47 hostname kernel: [1282130.405310] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:49 hostname kernel: [1282132.076611] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:51 hostname kernel: [1282134.027790] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:53 hostname kernel: [1282136.122911] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:55 hostname kernel: [1282138.218032] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:57 hostname kernel: [1282140.145365] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:18:59 hostname kernel: [1282142.140528] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:19:01 hostname kernel: [1282144.091708] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250) September 23 10:19:01 hostname kernel: [1282144.223485] INFO: task kswapd0: 87 blocked for more than 120 seconds. September 23 10:19:01 hostname kernel: [1282144.224156] Not tainted 3.13.0-34-generic # 60-Ubuntu ~ precise1 September 23 10:19:01 hostname kernel: [1282144.224837] "echo 0> / proc / sys / kernel / hung_task_timeout_secs" disables this message. September 23 10:19:01 hostname kernel: [1282144.225597] kswapd0 D ffff88031662a020 0 87 2 0x00000000 September 23 10:19:01 hostname kernel: [1282144.225609] ffff88019500d8f8 0000000000000002 ffff880199d94440 ffff88019500dfd8 September 23 10:19:01 hostname kernel: [1282144.225621] 0000000000014440 0000000000014440 ffff880316cd2fe0 ffff880316f3afe0 September 23 10:19:01 hostname kernel: [1282144.225629] ffff88019500d970 ffff880314119128 ffff88031411912c 00000000ffffffff September 23 10:19:01 hostname kernel: [1282144.225638] Call Trace: September 23 10:19:01 hostname kernel: [1282144.225658] [] schedule + 0x29 / 0x70 September 23 10:19:01 hostname kernel: [1282144.225669] [] schedule_preempt_disabled + 0xe / 0x10 September 23 10:19:01 hostname kernel: [1282144.225680] [] __mutex_lock_slowpath + 0x114 / 0x1b0 September 23 10:19:01 hostname kernel: [1282144.225771] []? xfs_perag_get_tag + 0x41 / 0xf0 [xfs] September 23 10:19:01 hostname kernel: [1282144.225781] [] mutex_lock + 0x23 / 0x37 September 23 10:19:01 hostname kernel: [1282144.225832] [] xfs_reclaim_inodes_ag + 0x2e0 / 0x3a0 [xfs] September 23 10:19:01 hostname kernel: [1282144.225843] []? sched_clock + 0x9 / 0x10 September 23 10:19:01 hostname kernel: [1282144.225852] []? native_smp_send_reschedule + 0x4b / 0x60 September 23 10:19:01 hostname kernel: [1282144.225862] []? ttwu_queue + 0x8D / 0xD0 September 23 10:19:01 hostname kernel: [1282144.225871] []? try_to_wake_up + 0x190 / 0x210 September 23 10:19:01 hostname kernel: [1282144.225879] []? wake_up_process + 0x27 / 0x50 uname -a hostname 3.13.0-34-generic # 60-Ubuntu SMP Wed precise1 ~ August 13 15:55:33 UTC 2014 x86_64 x86_64 x86_64 GNU / Linux xfs_repair -V xfs_repair Version 3.1.7 7 CPUs -> cat /proc/cpuinfo processor : 0 vendor_id : AuthenticAMD cpu family : 16 model : 4 model name : Quad-Core AMD Opteron(tm) Processor 2376 stepping : 2 microcode : 0x1000086 cpu MHz : 800.000 cache size : 512 KB physical id : 0 siblings : 4 core id : 0 cpu cores : 4 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 5 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm 3dnowext 3dnow constant_tsc rep_good nopl nonstop_tsc extd_apicid pni monitor cx16 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt hw_pstate npt lbrv svm_lock nrip_save bogomips : 4600.18 TLB size : 1024 4K pages clflush size : 64 cache_alignment : 64 address sizes : 48 bits physical, 48 bits virtual power management: ts ttp tm stc 100mhzsteps hwpstate cat /proc/meminfo MemTotal: 12304884 kB MemFree: 151816 kB Buffers: 1076 kB Cached: 10328496 kB SwapCached: 0 kB Active: 2658232 kB Inactive: 7766540 kB Active(anon): 42644 kB Inactive(anon): 53636 kB Active(file): 2615588 kB Inactive(file): 7712904 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 4878268 kB SwapFree: 4878268 kB Dirty: 1220 kB Writeback: 0 kB AnonPages: 95728 kB Mapped: 32208 kB Shmem: 352 kB Slab: 1412904 kB SReclaimable: 1188188 kB SUnreclaim: 224716 kB KernelStack: 3512 kB PageTables: 28816 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 11030708 kB Committed_AS: 949792 kB VmallocTotal: 34359738367 kB VmallocUsed: 310312 kB VmallocChunk: 34353030140 kB HardwareCorrupted: 0 kB AnonHugePages: 12288 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 75520 kB DirectMap2M: 3069952 kB DirectMap1G: 9437184 kB cat /proc/mounts rootfs / rootfs rw 0 0 sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0 proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0 udev /dev devtmpfs rw,relatime,size=6108796k,nr_inodes=1527199,mode=755 0 0 devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0 tmpfs /run tmpfs rw,nosuid,noexec,relatime,size=1230492k,mode=755 0 0 /dev/disk/by-uuid/d6821e50-e82b-448d-bc03-9c286ef59c8f / xfs rw,relatime,attr2,inode64,noquota 0 0 none /sys/fs/fuse/connections fusectl rw,relatime 0 0 none /sys/kernel/debug debugfs rw,relatime 0 0 none /sys/kernel/security securityfs rw,relatime 0 0 none /run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k 0 0 none /run/shm tmpfs rw,nosuid,nodev,relatime 0 0 /dev/sdc1 /extern/data0 xfs rw,relatime,attr2,inode64,noquota 0 0 rpc_pipefs /run/rpc_pipefs rpc_pipefs rw,relatime 0 0 nfsd /proc/fs/nfsd nfsd rw,relatime 0 0 cat /proc/partitions major minor #blocks name 11 0 1048575 sr0 8 0 245175336 sda 8 1 97654784 sda1 8 2 4882432 sda2 8 16 245175336 sdb 8 17 97654784 sdb1 8 18 4882432 sdb2 9 2 97589120 md2 9 1 4878272 md1 8 32 27345461248 sdc 8 33 27345461214 sdc1 xfs_info /dev/md2 Metadaten =/dev/disk/by-uuid/d6821e50-e82b-448d-bc03-9c286ef59c8f isize=256 agcount=4, agsize=6099320 blks = sectsz=512 attr=2 Daten = bsize=4096 Blöcke=24397280, imaxpct=25 = sunit=0 swidth=0 blks Benennung =Version 2 bsize=4096 ascii-ci=0 Protokoll =Intern bsize=4096 Blöcke=11912, Version=2 = sectsz=512 sunit=0 blks, lazy-count=1 Echtzeit =keine extsz=4096 Blöcke=0, rtextents=0 xfs_info /dev/md2 Metadaten =/dev/disk/by-uuid/d6821e50-e82b-448d-bc03-9c286ef59c8f isize=256 agcount=4, agsize=6099320 blks = sectsz=512 attr=2 Daten = bsize=4096 Blöcke=24397280, imaxpct=25 = sunit=0 swidth=0 blks Benennung =Version 2 bsize=4096 ascii-ci=0 Protokoll =Intern bsize=4096 Blöcke=11912, Version=2 = sectsz=512 sunit=0 blks, lazy-count=1 Echtzeit =keine extsz=4096 Blöcke=0, rtextents=0 xfs_info /dev/sdc1 Metadaten =/dev/sdc1 isize=256 agcount=26, agsize=268435455 blks = sectsz=512 attr=2 Daten = bsize=4096 Blöcke=6836365303, imaxpct=5 = sunit=0 swidth=0 blks Benennung =Version 2 bsize=4096 ascii-ci=0 Protokoll =Intern bsize=4096 Blöcke=32768, Version=2 = sectsz=512 sunit=0 blks, lazy-count=0 Echtzeit =keine extsz=4096 Blöcke=0, rtextents=0 Can you help us? Best regards, -- Mit freundlichen Grüssen, Thomas Stagge -------------------------------------- Thomas Stagge, Dipl.Ing.(FH) System Administrator OPTIMARE Systems GmbH Am Luneort 15a 27572 Bremerhaven, Germany T: +49 471 48361-27 F: +49 471 48361-11 M: +49 172 8698575 thomas.stagge@optimare.de Internet: http://www.optimare.de CEO: Dipl.-Ing. Hans J. Stahl; Sitz der Gesellschaft: Bremerhaven; Registergericht: Amtsgericht Bremen HRB 28618 HB --------------020208010800020302070003 Content-Type: text/html; charset=ISO-8859-15 Content-Transfer-Encoding: 8bit

Hello,

we have in the last few weeks always problems with the XFS file system.

XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)


After a certain time there is a kernel crash which looks as follows:
September 23 10:17:57 hostname kernel: [1282081.010814] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:17:59 hostname kernel: [1282082.913437] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:01 hostname kernel: [1282084.908582] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:03 hostname kernel: [1282086.691791] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:05 hostname kernel: [1282088.691319] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:07 hostname kernel: [1282090.690182] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:09 hostname kernel: [1282092.673355] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:11 hostname kernel: [1282094.596504] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:13 hostname kernel: [1282096.595971] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:15 hostname kernel: [1282098.595301] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:17 hostname kernel: [1282100.594232] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:19 hostname kernel: [1282102.433262] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:21 hostname kernel: [1282104.412432] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:23 hostname kernel: [1282106.411598] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:25 hostname kernel: [1282108.310740] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:27 hostname kernel: [1282110.289892] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:29 hostname kernel: [1282112.289106] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:31 hostname kernel: [1282114.288247] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:33 hostname kernel: [1282116.215953] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:35 hostname kernel: [1282118.198488] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:37 hostname kernel: [1282120.193686] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:39 hostname kernel: [1282122.288716] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:41 hostname kernel: [1282124.215970] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:43 hostname kernel: [1282126.307031] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:45 hostname kernel: [1282128.306190] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:47 hostname kernel: [1282130.405310] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:49 hostname kernel: [1282132.076611] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:51 hostname kernel: [1282134.027790] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:53 hostname kernel: [1282136.122911] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:55 hostname kernel: [1282138.218032] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:57 hostname kernel: [1282140.145365] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:18:59 hostname kernel: [1282142.140528] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:19:01 hostname kernel: [1282144.091708] XFS: possible memory allocation deadlock in kmem_alloc (mode: 0x250)
September 23 10:19:01 hostname kernel: [1282144.223485] INFO: task kswapd0: 87 blocked for more than 120 seconds.
September 23 10:19:01 hostname kernel: [1282144.224156] Not tainted 3.13.0-34-generic # 60-Ubuntu ~ precise1
September 23 10:19:01 hostname kernel: [1282144.224837] "echo 0> / proc / sys / kernel / hung_task_timeout_secs" disables this message.
September 23 10:19:01 hostname kernel: [1282144.225597] kswapd0 D ffff88031662a020 0 87 2 0x00000000
September 23 10:19:01 hostname kernel: [1282144.225609] ffff88019500d8f8 0000000000000002 ffff880199d94440 ffff88019500dfd8
September 23 10:19:01 hostname kernel: [1282144.225621] 0000000000014440 0000000000014440 ffff880316cd2fe0 ffff880316f3afe0
September 23 10:19:01 hostname kernel: [1282144.225629] ffff88019500d970 ffff880314119128 ffff88031411912c 00000000ffffffff
September 23 10:19:01 hostname kernel: [1282144.225638] Call Trace:
September 23 10:19:01 hostname kernel: [1282144.225658] [<ffffffff8175b8b9>] schedule + 0x29 / 0x70
September 23 10:19:01 hostname kernel: [1282144.225669] [<ffffffff8175bbde>] schedule_preempt_disabled + 0xe / 0x10
September 23 10:19:01 hostname kernel: [1282144.225680] [<ffffffff8175da14>] __mutex_lock_slowpath + 0x114 / 0x1b0
September 23 10:19:01 hostname kernel: [1282144.225771] [<ffffffffa0218291>]? xfs_perag_get_tag + 0x41 / 0xf0 [xfs]
September 23 10:19:01 hostname kernel: [1282144.225781] [<ffffffff8175dad3>] mutex_lock + 0x23 / 0x37
September 23 10:19:01 hostname kernel: [1282144.225832] [<ffffffffa01c7540>] xfs_reclaim_inodes_ag + 0x2e0 / 0x3a0 [xfs]
September 23 10:19:01 hostname kernel: [1282144.225843] [<ffffffff8101d0b9>]? sched_clock + 0x9 / 0x10
September 23 10:19:01 hostname kernel: [1282144.225852] [<ffffffff81042c9b>]? native_smp_send_reschedule + 0x4b / 0x60
September 23 10:19:01 hostname kernel: [1282144.225862] [<ffffffff8109cf7d>]? ttwu_queue + 0x8D / 0xD0
September 23 10:19:01 hostname kernel: [1282144.225871] [<ffffffff8109f860>]? try_to_wake_up + 0x190 / 0x210
September 23 10:19:01 hostname kernel: [1282144.225879] [<ffffffff8109f947>]? wake_up_process + 0x27 / 0x50

uname -a
hostname 3.13.0-34-generic # 60-Ubuntu SMP Wed precise1 ~ August 13 15:55:33 UTC 2014 x86_64 x86_64 x86_64 GNU / Linux


xfs_repair -V
xfs_repair Version 3.1.7


7 CPUs  -> cat /proc/cpuinfo
processor       : 0
vendor_id       : AuthenticAMD
cpu family      : 16
model           : 4
model name      : Quad-Core AMD Opteron(tm) Processor 2376
stepping        : 2
microcode       : 0x1000086
cpu MHz         : 800.000
cache size      : 512 KB
physical id     : 0
siblings        : 4
core id         : 0
cpu cores       : 4
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 5
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm 3dnowext 3dnow constant_tsc rep_good nopl nonstop_tsc extd_apicid pni monitor cx16 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt hw_pstate npt lbrv svm_lock nrip_save
bogomips        : 4600.18
TLB size        : 1024 4K pages
clflush size    : 64
cache_alignment : 64
address sizes   : 48 bits physical, 48 bits virtual
power management: ts ttp tm stc 100mhzsteps hwpstate


cat /proc/meminfo
MemTotal:       12304884 kB
MemFree:          151816 kB
Buffers:            1076 kB
Cached:         10328496 kB
SwapCached:            0 kB
Active:          2658232 kB
Inactive:        7766540 kB
Active(anon):      42644 kB
Inactive(anon):    53636 kB
Active(file):    2615588 kB
Inactive(file):  7712904 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       4878268 kB
SwapFree:        4878268 kB
Dirty:              1220 kB
Writeback:             0 kB
AnonPages:         95728 kB
Mapped:            32208 kB
Shmem:               352 kB
Slab:            1412904 kB
SReclaimable:    1188188 kB
SUnreclaim:       224716 kB
KernelStack:        3512 kB
PageTables:        28816 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    11030708 kB
Committed_AS:     949792 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      310312 kB
VmallocChunk:   34353030140 kB
HardwareCorrupted:     0 kB
AnonHugePages:     12288 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       75520 kB
DirectMap2M:     3069952 kB
DirectMap1G:     9437184 kB


 cat /proc/mounts
rootfs / rootfs rw 0 0
sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
udev /dev devtmpfs rw,relatime,size=6108796k,nr_inodes=1527199,mode=755 0 0
devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
tmpfs /run tmpfs rw,nosuid,noexec,relatime,size=1230492k,mode=755 0 0
/dev/disk/by-uuid/d6821e50-e82b-448d-bc03-9c286ef59c8f / xfs rw,relatime,attr2,inode64,noquota 0 0
none /sys/fs/fuse/connections fusectl rw,relatime 0 0
none /sys/kernel/debug debugfs rw,relatime 0 0
none /sys/kernel/security securityfs rw,relatime 0 0
none /run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k 0 0
none /run/shm tmpfs rw,nosuid,nodev,relatime 0 0
/dev/sdc1 /extern/data0 xfs rw,relatime,attr2,inode64,noquota 0 0
rpc_pipefs /run/rpc_pipefs rpc_pipefs rw,relatime 0 0
nfsd /proc/fs/nfsd nfsd rw,relatime 0 0


cat /proc/partitions
major minor  #blocks  name

  11        0    1048575 sr0
   8        0  245175336 sda
   8        1   97654784 sda1
   8        2    4882432 sda2
   8       16  245175336 sdb
   8       17   97654784 sdb1
   8       18    4882432 sdb2
   9        2   97589120 md2
   9        1    4878272 md1
   8       32 27345461248 sdc
   8       33 27345461214 sdc1


xfs_info /dev/md2
Metadaten =/dev/disk/by-uuid/d6821e50-e82b-448d-bc03-9c286ef59c8f isize=256    agcount=4, agsize=6099320 blks
          =                       sectsz=512   attr=2
Daten     =                       bsize=4096   Blöcke=24397280, imaxpct=25
          =                       sunit=0      swidth=0 blks
Benennung =Version 2              bsize=4096   ascii-ci=0
Protokoll =Intern                 bsize=4096   Blöcke=11912, Version=2
          =                       sectsz=512   sunit=0 blks, lazy-count=1
Echtzeit  =keine                  extsz=4096   Blöcke=0, rtextents=0


 xfs_info /dev/md2
Metadaten =/dev/disk/by-uuid/d6821e50-e82b-448d-bc03-9c286ef59c8f isize=256    agcount=4, agsize=6099320 blks
          =                       sectsz=512   attr=2
Daten     =                       bsize=4096   Blöcke=24397280, imaxpct=25
          =                       sunit=0      swidth=0 blks
Benennung =Version 2              bsize=4096   ascii-ci=0
Protokoll =Intern                 bsize=4096   Blöcke=11912, Version=2
          =                       sectsz=512   sunit=0 blks, lazy-count=1
Echtzeit  =keine                  extsz=4096   Blöcke=0, rtextents=0


xfs_info /dev/sdc1
Metadaten =/dev/sdc1              isize=256    agcount=26, agsize=268435455 blks
          =                       sectsz=512   attr=2
Daten     =                       bsize=4096   Blöcke=6836365303, imaxpct=5
          =                       sunit=0      swidth=0 blks
Benennung =Version 2              bsize=4096   ascii-ci=0
Protokoll =Intern                 bsize=4096   Blöcke=32768, Version=2
          =                       sectsz=512   sunit=0 blks, lazy-count=0
Echtzeit  =keine                  extsz=4096   Blöcke=0, rtextents=0


Can you help us?


Best regards,

-- 
Mit freundlichen Grüssen,

Thomas Stagge
--------------------------------------

Thomas Stagge, Dipl.Ing.(FH)
System Administrator

OPTIMARE Systems GmbH
Am Luneort 15a
27572 Bremerhaven, Germany

T: +49 471 48361-27
F: +49 471 48361-11
M: +49 172 8698575

 

thomas.stagge@optimare.de
Internet: http://www.optimare.de

CEO: Dipl.-Ing. Hans J. Stahl; Sitz der Gesellschaft: Bremerhaven; Registergericht: Amtsgericht Bremen HRB 28618 HB

--------------020208010800020302070003-- From olaf@sgi.com Tue Sep 23 08:01:26 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id DC6E87F3F for ; Tue, 23 Sep 2014 08:01:26 -0500 (CDT) Received: from xmail.sgi.com (pv-excas2-dc21.corp.sgi.com [137.38.106.9]) by relay1.corp.sgi.com (Postfix) with ESMTP id B95E38F8050; Tue, 23 Sep 2014 06:01:23 -0700 (PDT) Received: from [144.253.208.75] (144.253.208.75) by xmail.sgi.com (137.38.106.6) with Microsoft SMTP Server (TLS) id 14.3.195.1; Tue, 23 Sep 2014 08:01:23 -0500 Message-ID: <54216F20.1090302@sgi.com> Date: Tue, 23 Sep 2014 15:01:20 +0200 From: Olaf Weber Organization: SGI User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.1 MIME-Version: 1.0 To: Andi Kleen , Ben Myers CC: , , Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <87lhpbhfgg.fsf@tassilo.jf.intel.com> In-Reply-To: <87lhpbhfgg.fsf@tassilo.jf.intel.com> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 8bit X-Originating-IP: [144.253.208.75] On 22-09-14 16:55, Andi Kleen wrote: > Ben Myers writes: >> >> Strings are normalized using a trie that stores the relevant >> information. The trie itself is about 250kB in size, and lives in a >> separate module. > > So 250kB bloat -- and what does this fix exactly? > > Someone putting random ligatures into their file names and expecting > the file to be the same as before. Can't they just not do that? I like the 'office' example because it is applicable to English and easy to explain. Once you move away from English examples are much easier to come by. Take a Dutch name like 'Renée Soutendijk'. These two forms both spell Renée in UTF-8: 0x52 0x65 0x6E 0xC3 0xA9 0x65 0x52 0x65 0x6E 0x65 0xCC 0x81 0x65 The difference is LATIN SMALL LETTER E WITH ACUTE (U+00E9) LATIN SMALL LETTER E (U+0065) COMBINING ACUTE ACCENT (U+0301) and corresponds to the difference between NFC and NFD. These two forms both spell Soutendijk in UTF-8: 0x53 0x6F 0x75 0x74 0x65 0x6E 0x64 0x69 0x6A 0x6B 0x53 0x6F 0x75 0x74 0x65 0x6E 0x64 0xC4 0xB3 0x6B The difference is LATIN SMALL LETTER I (U+0069) LATIN SMALL LETTER J (U+006A) LATIN SMALL LIGATURE IJ (U+0133) and the former is the compatibility decomposition of the latter, the 'K' in NFKC/NFKD. Do accented letters count as random ligatures that people should just not use? The bulk of the table deals with Korean. Olaf -- Olaf Weber SGI Phone: +31(0)30-6696796 Veldzigt 2b Fax: +31(0)30-6696799 Technical Lead 3454 PW de Meern Vnet: 955-6796 Storage Software The Netherlands Email: olaf@sgi.com From dgc@oss.sgi.com Tue Sep 23 08:30:29 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=NO_RELAYS autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: by oss.sgi.com (Postfix, from userid 10266) id 5C0777F47; Tue, 23 Sep 2014 08:30:29 -0500 (CDT) From: xfs@oss.sgi.com To: xfs@oss.sgi.com Subject: [XFS updates] XFS development tree branch, xfs-shift-extents-rework, created. xfs-for-linus-3.17-rc3-6-g8b5279e X-Git-Refname: refs/heads/xfs-shift-extents-rework X-Git-Reftype: branch X-Git-Oldrev: 0000000000000000000000000000000000000000 X-Git-Newrev: 8b5279e33f241a074a9c8649bba8f77a2167b798 Message-Id: <20140923133029.5C0777F47@oss.sgi.com> Date: Tue, 23 Sep 2014 08:30:29 -0500 (CDT) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "XFS development tree". The branch, xfs-shift-extents-rework has been created at 8b5279e33f241a074a9c8649bba8f77a2167b798 (commit) - Log ----------------------------------------------------------------- commit 8b5279e33f241a074a9c8649bba8f77a2167b798 Author: Brian Foster Date: Tue Sep 23 15:39:05 2014 +1000 xfs: only writeback and truncate pages for the freed range xfs_free_file_space() only affects the range of the file for which space is being freed. It currently writes and truncates the page cache from the start offset of the free to EOF. Modify xfs_free_file_space() to write back and truncate page cache of just the range being freed. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner commit f71721d061e872a39b2680d13f309c1eb6893438 Author: Brian Foster Date: Tue Sep 23 15:39:05 2014 +1000 xfs: writeback and inval. file range to be shifted by collapse The collapse range operation currently writes the entire file before starting the collapse to avoid changes in the in-core extent list due to writeback causing the extent count to change. Now that collapse range is fsb based rather than extent index based it can sustain changes in the extent list during the shift sequence without disruption. Modify xfs_collapse_file_space() to writeback and invalidate pages associated with the range of the file to be shifted. xfs_free_file_space() currently has similar behavior, but the space free need only affect the region of the file that is freed and this could change in the future. Also update the comments to reflect the current implementation. We retain the eofblocks trim permanently as a best option for dealing with delalloc extents. We don't shift delalloc extents because this scenario only occurs with post-eof preallocation (since data must be flushed such that the cache can be invalidated and data can be shifted). That means said space must also be initialized before being shifted into the accessible region of the file only to be immediately truncated off as the last part of the collapse. In other words, the eofblocks trim will happen anyways, we just run it first to ensure the file remains in a consistent state throughout the collapse. Finally, detect and fail explicitly in the event of a delalloc extent during the extent shift. The implementation does not support delalloc extents and the caller is expected to prevent this scenario in advance as is done by collapse. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner commit a979bdfea10a61dce0055b4d416d640f4f5f495e Author: Brian Foster Date: Tue Sep 23 15:39:04 2014 +1000 xfs: refactor single extent shift into xfs_bmse_shift_one() helper xfs_bmap_shift_extents() has a variety of conditions and error checks that make the logic difficult to follow and indent heavy. Refactor the loop body of this function into a new xfs_bmse_shift_one() helper. This simplifies the error checks, eliminates index decrement on merge hack by pushing the index increment down into the helper, and makes the code more readable by reducing multiple levels of indentation. This is a code refactor only. The behavior of extent shift and collapse range is not modified. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner commit ddb19e3180fa42362a04e86771d758be1de0bb13 Author: Brian Foster Date: Tue Sep 23 15:38:09 2014 +1000 xfs: refactor shift-by-merge into xfs_bmse_merge() helper The extent shift mechanism in xfs_bmap_shift_extents() is complicated and handles several different, non-deterministic scenarios. These include extent shifts, extent merges and potential btree updates in either of the former scenarios. Refactor the code to be more linear and readable. The loop logic in xfs_bmap_shift_extents() and some initial error checking is adjusted slightly. The associated btree lookup and update/delete operations are condensed into single blocks of code. This reduces the number of btree-specific blocks and facilitates the separation of the merge operation into a new xfs_bmse_merge() and xfs_bmse_can_merge() helpers. This is a code refactor only. The behavior of extent shift and collapse range is not modified. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner commit 2c845f5a5f238f42376b6551a7f7716952c8f509 Author: Brian Foster Date: Tue Sep 23 15:37:09 2014 +1000 xfs: track collapse via file offset rather than extent index The collapse range implementation uses a transaction per extent shift. The progress of the overall operation is tracked via the current extent index of the in-core extent list. This is racy because the ilock must be dropped and reacquired for each transaction according to locking and log reservation rules. Therefore, writeback to prior regions of the file is possible and can change the extent count. This changes the extent to which the current index refers and causes the collapse to fail mid operation. To avoid this problem, the entire file is currently written back before the collapse operation starts. To eliminate the need to flush the entire file, use the file offset (fsb) to track the progress of the overall extent shift operation rather than the extent index. Modify xfs_bmap_shift_extents() to unconditionally convert the start_fsb parameter to an extent index and return the file offset of the extent where the shift left off, if further extents exist. The bulk of ths function can remain based on extent index as ilock is held by the caller. xfs_collapse_file_space() now uses the fsb output as the starting point for the subsequent shift. Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner commit 0d085a529b427d97710e6a41f8a4f23e1757cd12 Author: Dave Chinner Date: Tue Sep 23 15:36:27 2014 +1000 xfs: ensure WB_SYNC_ALL writeback handles partial pages correctly XFS has been having trouble with stray delayed allocation extents beyond EOF for a long time. Recent changes to the collapse range code has triggered erroneous EBUSY errors on page invalidtion for block size smaller than page size filesystems. These have been caused by dirty buffers beyond EOF on a partial page which do not get written to disk during a sync. The issue is that write-ahead in xfs_cluster_write() finds such a partial page and handles it by leaving the page dirty but pushing it into a writeback state. This used to work just fine, as the write_cache_pages() code would then find the dirty partial page in the next mapping tree lookup as the dirty tag is still set. Unfortunately, when we moved to a mark and sweep approach to writeback to fix other writeback sync issues, we broken this. THe act of marking the page as under writeback now clears the TOWRITE tag in the radix tree, even though the page is still dirty. This causes the TOWRITE tag to be cleared, and hence the next lookup on the mapping tree does not find the dirty partial page and so doesn't try to write it again. This same writeback bug was found recently in ext4 and fixed in commit 1c8349a ("ext4: fix data integrity sync in ordered mode") without communication to the wider filesystem community. We can use exactly the same fix here so the TOWRITE flag is not cleared on partial page writes. cc: stable@vger.kernel.org # dependent on 1c8349a17137b93f0a83f276c764a6df1b9a116e Root-cause-found-by: Brian Foster Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Signed-off-by: Dave Chinner ----------------------------------------------------------------------- hooks/post-receive -- XFS development tree From dgc@oss.sgi.com Tue Sep 23 08:30:47 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=NO_RELAYS autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: by oss.sgi.com (Postfix, from userid 10266) id BB95A7F51; Tue, 23 Sep 2014 08:30:47 -0500 (CDT) From: xfs@oss.sgi.com To: xfs@oss.sgi.com Subject: [XFS updates] XFS development tree branch, xfs-misc-fixes-for-3.18-2, created. v3.16-11814-g2ebff7b X-Git-Refname: refs/heads/xfs-misc-fixes-for-3.18-2 X-Git-Reftype: branch X-Git-Oldrev: 0000000000000000000000000000000000000000 X-Git-Newrev: 2ebff7bbd785c86e12956388b9e6f6bb8ea5d21e Message-Id: <20140923133047.BB95A7F51@oss.sgi.com> Date: Tue, 23 Sep 2014 08:30:47 -0500 (CDT) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "XFS development tree". The branch, xfs-misc-fixes-for-3.18-2 has been created at 2ebff7bbd785c86e12956388b9e6f6bb8ea5d21e (commit) - Log ----------------------------------------------------------------- commit 2ebff7bbd785c86e12956388b9e6f6bb8ea5d21e Author: Dave Chinner Date: Tue Sep 23 22:55:00 2014 +1000 xfs: flush entire last page of old EOF on truncate up On a sub-page sized filesystem, truncating a mapped region down leaves us in a world of hurt. We truncate the pagecache, zeroing the newly unused tail, then punch blocks out from under the page. If we then truncate the file back up immediately, we expose that unmapped hole to a dirty page mapped into the user application, and that's where it all goes wrong. In truncating the page cache, we avoid unmapping the tail page of the cache because it still contains valid data. The problem is that it also contains a hole after the truncate, but nobody told the mm subsystem that. Therefore, if the page is dirty before the truncate, we'll never get a .page_mkwrite callout after we extend the file and the application writes data into the hole on the page. Hence when we come to writing that region of the page, it has no blocks and no delayed allocation reservation and hence we toss the data away. This patch adds code to the truncate up case to solve it, by ensuring the partial page at the old EOF is always cleaned after we do any zeroing and move the EOF upwards. We can't actually serialise the page writeback and truncate against page faults (yes, that problem AGAIN) so this is really just a best effort and assumes it is extremely unlikely that someone is concurrently writing to the page at the EOF while extending the file. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Signed-off-by: Dave Chinner commit 7abbb8f928e5b7cea1edd077131b2ace665c6712 Author: Dave Chinner Date: Tue Sep 23 16:20:11 2014 +1000 xfs: xfs_swap_extent_flush can be static Fix sparse warning introduced by commit 4ef897a ("xfs: flush both inodes in xfs_swap_extents"). Signed-off-by: Fengguang Wu Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner commit 02cc18764c753befcdc163d1bc668a6599a54585 Author: Dave Chinner Date: Tue Sep 23 16:15:45 2014 +1000 xfs: xfs_buf_write_fail_rl_state can be static Fix sparse warning introduced by commit ac8809f9 ("xfs: abort metadata writeback on permanent errors"). Signed-off-by: Fengguang Wu Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner commit ea95961df714f7fc446aa4bedfc61510ed1b59cc Author: Fengguang Wu Date: Tue Sep 23 16:11:43 2014 +1000 xfs: xfs_rtget_summary can be static Fix sparse warning introduced by commit afabfd3 ("xfs: combine xfs_rtmodify_summary and xfs_rtget_summary"). Signed-off-by: Fengguang Wu Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner commit e3cf17962a757e59fed2cbcbda6373c1b35a35dd Author: Fabian Frederick Date: Tue Sep 23 16:05:55 2014 +1000 xfs: remove second xfs_quota.h inclusion in xfs_icache.c xfs_quota.h was included twice. Signed-off-by: Fabian Frederick Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner commit fb040131561a6b34cefb92cdf598218104abeda0 Author: Eric Sandeen Date: Tue Sep 23 16:05:32 2014 +1000 xfs: don't ASSERT on corrupt ftype xfs_dir3_data_get_ftype() gets the file type off disk, but ASSERTs if it's invalid: ASSERT(type < XFS_DIR3_FT_MAX); We shouldn't ASSERT on bad values read from disk. V3 dirs are CRC-protected, but V2 dirs + ftype are not. Signed-off-by: Eric Sandeen Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner commit 8af3dcd3c89aef10375bdd79d5f336b22b57487c Author: Dave Chinner Date: Tue Sep 23 15:57:59 2014 +1000 xfs: xlog_cil_force_lsn doesn't always wait correctly When running a tight mount/unmount loop on an older kernel, RedHat QE found that unmount would occasionally hang in xfs_buf_unpin_wait() on the superblock buffer. Tracing and other debug work by Eric Sandeen indicated that it was hanging on the writing of the superblock during unmount immediately after logging the superblock counters in a synchronous transaction. Further debug indicated that the synchronous transaction was not waiting for completion correctly, and we narrowed it down to xlog_cil_force_lsn() returning NULLCOMMITLSN and hence not pushing the transaction in the iclog buffer to disk correctly. While this unmount superblock write code is now very different in mainline kernels, the xlog_cil_force_lsn() code is identical, and it was bisected to the backport of commit f876e44 ("xfs: always do log forces via the workqueue"). This commit made the CIL push asynchronous for log forces and hence exposed a race condition that couldn't occur on a synchronous push. Essentially, the xlog_cil_force_lsn() relied implicitly on the fact that the sequence push would be complete by the time xlog_cil_push_now() returned, resulting in the context being pushed being in the committing list. When it was made asynchronous, it was recognised that there was a race condition in detecting whether an asynchronous push has started or not and code was added to handle it. Unfortunately, the fix was not quite right and left a race condition where it it would detect an empty CIL while a push was in progress before the context had been added to the committing list. This was incorrectly seen as a "nothing to do" condition and so would tell xfs_log_force_lsn() that there is nothing to wait for, and hence it would push the iclogbufs in memory. The fix is simple, but explaining the logic and the race condition is a lot more complex. The fix is to add the context to the committing list before we start emptying the CIL. This allows us to detect the difference between an empty "do nothing" push and a push that has not started by adding a discrete "emptying the CIL" state to avoid the transient, incorrect "empty" condition that the (unchanged) waiting code was seeing. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Signed-off-by: Dave Chinner ----------------------------------------------------------------------- hooks/post-receive -- XFS development tree From dgc@oss.sgi.com Tue Sep 23 08:31:05 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=NO_RELAYS autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: by oss.sgi.com (Postfix, from userid 10266) id 270587F55; Tue, 23 Sep 2014 08:31:05 -0500 (CDT) From: xfs@oss.sgi.com To: xfs@oss.sgi.com Subject: [XFS updates] XFS development tree branch, for-next, updated. xfs-for-linus-3.17-rc3-27-g33044dc X-Git-Refname: refs/heads/for-next X-Git-Reftype: branch X-Git-Oldrev: a4241aebe924136d6838fd516da6daa727fcd728 X-Git-Newrev: 33044dc408e6e6bb7f270c0a2e12598ef5592987 Message-Id: <20140923133105.270587F55@oss.sgi.com> Date: Tue, 23 Sep 2014 08:31:05 -0500 (CDT) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "XFS development tree". The branch, for-next has been updated 33044dc Merge branch 'xfs-misc-fixes-for-3.18-2' into for-next 2ebff7b xfs: flush entire last page of old EOF on truncate up 7abbb8f xfs: xfs_swap_extent_flush can be static 02cc187 xfs: xfs_buf_write_fail_rl_state can be static ea95961 xfs: xfs_rtget_summary can be static e3cf179 xfs: remove second xfs_quota.h inclusion in xfs_icache.c fb04013 xfs: don't ASSERT on corrupt ftype 8af3dcd xfs: xlog_cil_force_lsn doesn't always wait correctly f6d31f4 Merge branch 'xfs-shift-extents-rework' into for-next 8b5279e xfs: only writeback and truncate pages for the freed range f71721d xfs: writeback and inval. file range to be shifted by collapse a979bdf xfs: refactor single extent shift into xfs_bmse_shift_one() helper ddb19e3 xfs: refactor shift-by-merge into xfs_bmse_merge() helper 2c845f5 xfs: track collapse via file offset rather than extent index 0d085a5 xfs: ensure WB_SYNC_ALL writeback handles partial pages correctly from a4241aebe924136d6838fd516da6daa727fcd728 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 33044dc408e6e6bb7f270c0a2e12598ef5592987 Merge: f6d31f4 2ebff7b Author: Dave Chinner Date: Tue Sep 23 22:55:51 2014 +1000 Merge branch 'xfs-misc-fixes-for-3.18-2' into for-next commit f6d31f4b0462898896ba68e491662958ce37d095 Merge: a4241ae 8b5279e Author: Dave Chinner Date: Tue Sep 23 15:51:14 2014 +1000 Merge branch 'xfs-shift-extents-rework' into for-next ----------------------------------------------------------------------- Summary of changes: fs/xfs/libxfs/xfs_bmap.c | 365 ++++++++++++++++++++++++++++-------------- fs/xfs/libxfs/xfs_bmap.h | 7 +- fs/xfs/libxfs/xfs_da_format.c | 1 - fs/xfs/xfs_aops.c | 16 +- fs/xfs/xfs_bmap_util.c | 56 ++++--- fs/xfs/xfs_buf_item.c | 2 +- fs/xfs/xfs_icache.c | 1 - fs/xfs/xfs_iops.c | 30 ++++ fs/xfs/xfs_log_cil.c | 47 ++++-- fs/xfs/xfs_rtalloc.c | 2 +- 10 files changed, 360 insertions(+), 167 deletions(-) hooks/post-receive -- XFS development tree From tinguely@dhcp-128-162-232-117.americas.sgi.com Tue Sep 23 10:43:12 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 405CF7F3F for ; Tue, 23 Sep 2014 10:43:12 -0500 (CDT) Received: from dhcp-128-162-232-117.americas.sgi.com (dhcp-128-162-232-117.americas.sgi.com [128.162.232.117]) by relay3.corp.sgi.com (Postfix) with ESMTP id BD023AC006 for ; Tue, 23 Sep 2014 08:43:08 -0700 (PDT) Received: from dhcp-128-162-232-117.americas.sgi.com (localhost [127.0.0.1]) by dhcp-128-162-232-117.americas.sgi.com (8.14.5/8.14.5) with ESMTP id s8NFhAEC002931 for ; Tue, 23 Sep 2014 10:43:10 -0500 (CDT) (envelope-from tinguely@dhcp-128-162-232-117.americas.sgi.com) Received: (from tinguely@localhost) by dhcp-128-162-232-117.americas.sgi.com (8.14.5/8.14.5/Submit) id s8NFhAaV002930; Tue, 23 Sep 2014 10:43:10 -0500 (CDT) (envelope-from tinguely) Message-Id: <20140923154140.315778789@sgi.com> User-Agent: quilt/0.51-1 Date: Tue, 23 Sep 2014 10:41:29 -0500 From: Mark Tingueyl To: xfs@oss.sgi.com Subject: [PATCH] xfsprogs: fix xfsctl manual XFS_IOC_FSSETXATTR valid fields Content-Disposition: inline; filename=xfsprogs-project-id-XFS_IOC_FSSETXATTR.patch The xfsctl manual page fails to mention that fsx_projid is a setable field. Signed-off-by: Mark Tinguely --- man/man3/xfsctl.3 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) Index: b/man/man3/xfsctl.3 =================================================================== --- a/man/man3/xfsctl.3 +++ b/man/man3/xfsctl.3 @@ -245,9 +245,10 @@ Set additional attributes associated wit The final argument points to a variable of type .BR "struct fsxattr" , but only the following fields are used in this call: -.B fsx_xflags +.BR fsx_xflags , +.B fsx_extsize and -.BR fsx_extsize . +.BR fsx_projid . The .B fsx_xflags realtime file bit and the file's extent size may be changed only From sandeen@sandeen.net Tue Sep 23 11:04:05 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id EE8687F3F for ; Tue, 23 Sep 2014 11:04:05 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id CADF4304032 for ; Tue, 23 Sep 2014 09:04:02 -0700 (PDT) X-ASG-Debug-ID: 1411488238-04cbb07303f55a0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id rkERuXpCX7Op55E6 for ; Tue, 23 Sep 2014 09:03:58 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 2370F63BECCA; Tue, 23 Sep 2014 11:03:58 -0500 (CDT) Message-ID: <542199F1.4040207@sandeen.net> Date: Tue, 23 Sep 2014 11:04:01 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Mark Tingueyl , xfs@oss.sgi.com Subject: Re: [PATCH] xfsprogs: fix xfsctl manual XFS_IOC_FSSETXATTR valid fields References: <20140923154140.315778789@sgi.com> X-ASG-Orig-Subj: Re: [PATCH] xfsprogs: fix xfsctl manual XFS_IOC_FSSETXATTR valid fields In-Reply-To: <20140923154140.315778789@sgi.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1411488238 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9791 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/23/14 10:41 AM, Mark Tingueyl wrote: > The xfsctl manual page fails to mention that fsx_projid is a > setable field. > > Signed-off-by: Mark Tinguely Reviewed-by: Eric Sandeen p.s. You might want to fix your name in your email client, Mr. Tingueyl ;) > --- > man/man3/xfsctl.3 | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > Index: b/man/man3/xfsctl.3 > =================================================================== > --- a/man/man3/xfsctl.3 > +++ b/man/man3/xfsctl.3 > @@ -245,9 +245,10 @@ Set additional attributes associated wit > The final argument points to a variable of type > .BR "struct fsxattr" , > but only the following fields are used in this call: > -.B fsx_xflags > +.BR fsx_xflags , > +.B fsx_extsize > and > -.BR fsx_extsize . > +.BR fsx_projid . > The > .B fsx_xflags > realtime file bit and the file's extent size may be changed only > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs > From olaf@sgi.com Tue Sep 23 11:13:18 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 74F227F3F for ; Tue, 23 Sep 2014 11:13:18 -0500 (CDT) Received: from xmail.sgi.com (pv-excas1-dc21.corp.sgi.com [137.38.106.7]) by relay3.corp.sgi.com (Postfix) with ESMTP id B450FAC004; Tue, 23 Sep 2014 09:13:14 -0700 (PDT) Received: from [134.15.0.72] (134.15.0.72) by xmail.sgi.com (137.38.106.6) with Microsoft SMTP Server (TLS) id 14.3.195.1; Tue, 23 Sep 2014 11:13:14 -0500 Message-ID: <54219C17.3090104@sgi.com> Date: Tue, 23 Sep 2014 18:13:11 +0200 From: Olaf Weber Organization: SGI User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.1 MIME-Version: 1.0 To: Andi Kleen , Ben Myers CC: , , Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <87lhpbhfgg.fsf@tassilo.jf.intel.com> <20140922184145.GH4482@sgi.com> <20140922192958.GJ4120@two.firstfloor.org> In-Reply-To: <20140922192958.GJ4120@two.firstfloor.org> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [134.15.0.72] On 22-09-14 21:29, Andi Kleen wrote: >>> So 250kB bloat -- and what does this fix exactly? >> >> We're trying to address the size issue by only loading the module when > > I'm not sure this is really addressing it. You only pay the space cost if you use it, similar to the nls tables. >> it's needed, but yeah it's big. Open to suggestions on how best to deal >> with that. I understand the sticker shock. > > I don't even understand why you need the whole table. > > You want to not compare some special symbols, and a few other symbols > are equivalent to others. But most symbols are only identical to themselves. > > Couldn't you have a much smaller table that only expresses > the exceptions? The trie tells you whether a given sequence of bytes is a UTF-8 encoded unicode codepoint, and if so, it gives the unicode version in which the codepoint was assigned an interpretation (if any), the canonical combining class (required for normalization), and the decomposition and case fold (if any). A big part of the table does decompositions for Korean: eliminating the Hangul decompositions removes 156320 bytes, leaving 89936 bytes. Hangul decomposition uses two or three unicode code points and a terminating NUL byte in a UTF-8 string. The code points each require a three-byte UTF-8 sequence, so the total is 7 bytes per 2-part decomposition, and 10 bytes per 3-part decomposition. With that in mind, the 156320 additional bytes spent on Hangul are accounted for as follows: 22344 bytes : 11172 leaves * 2 byte leaf size 2793 bytes : 399 2-part decompositions at 7 bytes each 107730 bytes : 10773 3-part decompositions at 10 bytes each This adds up to 132867 bytes of data, with the remainder, 23453 bytes, spent on additional internal trie nodes. >> As far as telling the customer "don't do that", my guess is that they >> would just go elsewhere. There are several other options for >> filesystems that support unicode. > > They could put some code into their user app that generates > an unique representation. This assumes a single app, and that they control the source of that app. Olaf -- Olaf Weber SGI Phone: +31(0)30-6696796 Veldzigt 2b Fax: +31(0)30-6696799 Technical Lead 3454 PW de Meern Vnet: 955-6796 Storage Software The Netherlands Email: olaf@sgi.com From eflorac@intellique.com Tue Sep 23 11:39:25 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 3C3A77F3F for ; Tue, 23 Sep 2014 11:39:25 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id C92B4AC004 for ; Tue, 23 Sep 2014 09:39:24 -0700 (PDT) X-ASG-Debug-ID: 1411490362-04bdf003a0fedd0001-NocioJ Received: from mail1.g1.pair.com (mail1.g1.pair.com [66.39.3.162]) by cuda.sgi.com with ESMTP id YutR1CPUeFuoJ301 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 23 Sep 2014 09:39:22 -0700 (PDT) X-Barracuda-Envelope-From: eflorac@intellique.com X-Barracuda-Apparent-Source-IP: 66.39.3.162 Received: from localhost (localhost [127.0.0.1]) by mail1.g1.pair.com (Postfix) with SMTP id BC4C8308A1 for ; Tue, 23 Sep 2014 12:39:21 -0400 (EDT) Received: from harpe.intellique.com (labo.djinux.com [82.225.196.72]) by mail1.g1.pair.com (Postfix) with ESMTPSA id E8C0030A24 for ; Tue, 23 Sep 2014 12:39:20 -0400 (EDT) Date: Tue, 23 Sep 2014 18:41:49 +0200 From: Emmanuel Florac To: xfs@oss.sgi.com Subject: compiling xfs-progs 3.2.x Message-ID: <20140923184149.05a57dba@harpe.intellique.com> X-ASG-Orig-Subj: compiling xfs-progs 3.2.x Organization: Intellique X-Mailer: Claws Mail 3.10.0 (GTK+ 2.24.20; i486-slackware-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail1.g1.pair.com[66.39.3.162] X-Barracuda-Start-Time: 1411490362 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9792 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi list, xfs-progs 3.1.x compile easily, however I can't get around compiling 3.2.x (debian 7.6) : ./configure ./configure: line 2098: AC_PROG_LIBTOOL: command not found ./configure: line 2204: syntax error near unexpected token `xfsprogs' ./configure: line 2204: `AC_PACKAGE_GLOBALS(xfsprogs)' Any hint on where to start would be appreciated. Libtool version is the same as testing and unstable (2.4.2). Thanks, -- ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From sandeen@sandeen.net Tue Sep 23 12:25:38 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 44B3229DF9 for ; Tue, 23 Sep 2014 12:25:38 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 226098F8052 for ; Tue, 23 Sep 2014 10:25:34 -0700 (PDT) X-ASG-Debug-ID: 1411493132-04cbb07302fa260001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id aJxQaOYC7vlXRpbu for ; Tue, 23 Sep 2014 10:25:32 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 0B4D863BECCA; Tue, 23 Sep 2014 12:25:31 -0500 (CDT) Message-ID: <5421AD0F.4040109@sandeen.net> Date: Tue, 23 Sep 2014 12:25:35 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Emmanuel Florac , xfs@oss.sgi.com Subject: Re: compiling xfs-progs 3.2.x References: <20140923184149.05a57dba@harpe.intellique.com> X-ASG-Orig-Subj: Re: compiling xfs-progs 3.2.x In-Reply-To: <20140923184149.05a57dba@harpe.intellique.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1411493132 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9793 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/23/14 11:41 AM, Emmanuel Florac wrote: > > Hi list, > xfs-progs 3.1.x compile easily, however I can't get around compiling > 3.2.x (debian 7.6) : > > ./configure > ./configure: line 2098: AC_PROG_LIBTOOL: command not found > ./configure: line 2204: syntax error near unexpected token `xfsprogs' > ./configure: line 2204: `AC_PACKAGE_GLOBALS(xfsprogs)' > > Any hint on where to start would be appreciated. Libtool version is the > same as testing and unstable (2.4.2). > > Thanks, > I'm not at all autoconf savvy, so just guessing here. there were very few changes to configure.ac since v3.1.11: diff --git a/configure.ac b/configure.ac index b968977..ae17c68 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([xfsprogs], [3.1.11]) +AC_INIT([xfsprogs], [3.2.0-alpha2]) AC_PREREQ(2.50) AC_CONFIG_AUX_DIR([.]) AC_CONFIG_MACRO_DIR([m4]) @@ -112,12 +112,14 @@ AC_HAVE_FIEMAP AC_HAVE_PREADV AC_HAVE_SYNC_FILE_RANGE AC_HAVE_BLKID_TOPO($enable_blkid) +AC_HAVE_READDIR AC_CHECK_SIZEOF([long]) AC_CHECK_SIZEOF([char *]) AC_TYPE_PSINT AC_TYPE_PSUNSIGNED AC_TYPE_U32 +AC_TYPE_UMODE_T AC_MANUAL_FORMAT AC_CONFIG_FILES([include/builddefs]) if you do a make realclean & re-make, does it help? (if you check out v3.1.11 and do the same, does it still build?) -Eric From roger@filmlight.ltd.uk Tue Sep 23 13:34:26 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 0C44E29DF9 for ; Tue, 23 Sep 2014 13:34:26 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 90297AC007 for ; Tue, 23 Sep 2014 11:34:25 -0700 (PDT) X-ASG-Debug-ID: 1411497260-04cbb07304fda40001-NocioJ Received: from a.mx.filmlight.ltd.uk (a.mx.filmlight.ltd.uk [77.107.81.250]) by cuda.sgi.com with SMTP id vF9YNc75bLkbQ4Ad for ; Tue, 23 Sep 2014 11:34:20 -0700 (PDT) X-Barracuda-Envelope-From: roger@filmlight.ltd.uk X-Barracuda-Apparent-Source-IP: 77.107.81.250 Received: (dqd 32277 invoked from network); 23 Sep 2014 18:34:20 -0000 Received: from montana.filmlight.ltd.uk (HELO ?10.44.0.132?) (roger@10.44.0.132) by a.mx.filmlight.ltd.uk with SMTP; 23 Sep 2014 18:34:20 -0000 Subject: Re: [PATCH 07a/13] xfsprogs: add trie generator for UTF-8. From: Roger Willcocks X-ASG-Orig-Subj: Re: [PATCH 07a/13] xfsprogs: add trie generator for UTF-8. To: Ben Myers Cc: linux-fsdevel@vger.kernel.org, tinguely@sgi.com, olaf@sgi.com, xfs@oss.sgi.com In-Reply-To: <20140919160612.GF4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> <20140919160612.GF4482@sgi.com> Content-Type: text/plain Date: Tue, 23 Sep 2014 19:34:19 +0100 Message-Id: <1411497259.4842.163.camel@localhost.localdomain> Mime-Version: 1.0 X-Mailer: Evolution 2.12.3 (2.12.3-19.el5) Content-Transfer-Encoding: 7bit X-Barracuda-Connect: a.mx.filmlight.ltd.uk[77.107.81.250] X-Barracuda-Start-Time: 1411497260 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9795 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, 2014-09-19 at 11:06 -0500, Ben Myers wrote: > +#define AGE_NAME "DerivedAge.txt" > +#define CCC_NAME "DerivedCombiningClass.txt" > +#define PROP_NAME "DerivedCoreProperties.txt" > +#define DATA_NAME "UnicodeData.txt" > +#define FOLD_NAME "CaseFolding.txt" > +#define NORM_NAME "NormalizationCorrections.txt" > +#define TEST_NAME "NormalizationTest.txt" Is there a reason why you're using multiple text-based data files (and hand-parsing them) when there's an xml formatted flat file available ? http://www.unicode.org/Public/UCD/latest/ucdxml/ And a 2nd question - why does the trie need to encode "the the unicode version in which the codepoint was assigned an interpretation" ? -- Roger Willcocks From bpm@sgi.com Tue Sep 23 13:57:21 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 9294F29DF9 for ; Tue, 23 Sep 2014 13:57:21 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5E460304051; Tue, 23 Sep 2014 11:57:21 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 202804266DC; Tue, 23 Sep 2014 13:57:21 -0500 (CDT) Date: Tue, 23 Sep 2014 13:57:21 -0500 From: Ben Myers To: Dave Chinner Cc: linux-fsdevel@vger.kernel.org, tinguely@sgi.com, olaf@sgi.com, xfs@oss.sgi.com Subject: Re: [PATCH 07/10] xfs: add trie generator and supporting code for UTF-8. Message-ID: <20140923185721.GV19952@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918201518.GJ4482@sgi.com> <20140922205714.GN4267@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140922205714.GN4267@dastard> User-Agent: Mutt/1.5.20 (2009-06-14) On Tue, Sep 23, 2014 at 06:57:14AM +1000, Dave Chinner wrote: > On Thu, Sep 18, 2014 at 03:15:19PM -0500, Ben Myers wrote: > > From: Olaf Weber > > > > mkutf8data.c is the source for a program that generates utf8data.h, which > > contains the trie that utf8norm.c uses. The trie is generated from the > > Unicode 7.0.0 data files. The format of the utf8data[] table is described > > in utf8norm.c. > > > > Supporting functions for UTF-8 normalization are in utf8norm.c with the > > header utf8norm.h. Two normalization forms are supported: nfkdi and nfkdicf. > > > > nfkdi: > > - Apply unicode normalization form NFKD. > > - Remove any Default_Ignorable_Code_Point. > > > > nfkdicf: > > - Apply unicode normalization form NFKD. > > - Remove any Default_Ignorable_Code_Point. > > - Apply a full casefold (C + F). > > > > For the purposes of the code, a string is valid UTF-8 if: > > > > - The values encoded are 0x1..0x10FFFF. > > - The surrogate codepoints 0xD800..0xDFFFF are not encoded. > > - The shortest possible encoding is used for all values. > > > > The supporting functions work on null-terminated strings (utf8 prefix) and > > on length-limited strings (utf8n prefix). > > > > Signed-off-by: Olaf Weber > > > > --- > > [v2: the trie is now separated into utf8norm.ko; > > utf8version is now a function and exported; > > introduced CONFIG_XFS_UTF8. -bpm] > > --- > > fs/xfs/Kconfig | 8 + > > fs/xfs/Makefile | 2 +- > > fs/xfs/utf8norm/Makefile | 37 + > > fs/xfs/utf8norm/mkutf8data.c | 3239 ++++++++++++++++++++++++++++++++++++++++++ > > fs/xfs/utf8norm/utf8norm.c | 649 +++++++++ > > fs/xfs/utf8norm/utf8norm.h | 116 ++ > > Again, nothing XFS specific here. It's being built as a separate > module and the only thing that XFS uses are exported functions, so > it really should be generic library code.... I'll get this moved to lib/ as you suggested elsewhere in the thread. Thanks, Ben From eflorac@intellique.com Tue Sep 23 14:28:37 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C783829DF9 for ; Tue, 23 Sep 2014 14:28:37 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3E06BAC006 for ; Tue, 23 Sep 2014 12:28:34 -0700 (PDT) X-ASG-Debug-ID: 1411500511-04cb6c50e4f7980001-NocioJ Received: from smtp5-g21.free.fr (smtp5-g21.free.fr [212.27.42.5]) by cuda.sgi.com with ESMTP id B8mNlFzCI1FzdVDw (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 23 Sep 2014 12:28:32 -0700 (PDT) X-Barracuda-Envelope-From: eflorac@intellique.com X-Barracuda-Apparent-Source-IP: 212.27.42.5 Received: from galadriel.home (unknown [82.235.234.79]) by smtp5-g21.free.fr (Postfix) with ESMTP id E98C5D480B1; Tue, 23 Sep 2014 21:28:13 +0200 (CEST) Date: Tue, 23 Sep 2014 21:28:48 +0200 From: Emmanuel Florac To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: compiling xfs-progs 3.2.x Message-ID: <20140923212848.1e540bc6@galadriel.home> X-ASG-Orig-Subj: Re: compiling xfs-progs 3.2.x In-Reply-To: <5421AD0F.4040109@sandeen.net> References: <20140923184149.05a57dba@harpe.intellique.com> <5421AD0F.4040109@sandeen.net> Organization: Intellique X-Mailer: Claws Mail 3.10.0 (GTK+ 2.24.20; i486-slackware-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: smtp5-g21.free.fr[212.27.42.5] X-Barracuda-Start-Time: 1411500512 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9797 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Le Tue, 23 Sep 2014 12:25:35 -0500 vous =C3=A9criviez: > if you do a make realclean & re-make, does it help?=20 Crap, that was it :) Thank you so much Eric. --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From bfoster@redhat.com Tue Sep 23 14:29:19 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 7B61929DF9 for ; Tue, 23 Sep 2014 14:29:19 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 5A28C8F8039 for ; Tue, 23 Sep 2014 12:29:16 -0700 (PDT) X-ASG-Debug-ID: 1411500541-04cbb07301101060001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id s6N2I42zC6bWDsPz (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 23 Sep 2014 12:29:02 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8NJT04E028479 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 23 Sep 2014 15:29:01 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8NJT0ri020635 for ; Tue, 23 Sep 2014 15:29:00 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id AB412120064; Tue, 23 Sep 2014 15:28:58 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [RFC PATCH] xfs: borrow indirect blocks from freed extent when available Date: Tue, 23 Sep 2014 15:28:58 -0400 X-ASG-Orig-Subj: [RFC PATCH] xfs: borrow indirect blocks from freed extent when available Message-Id: <1411500538-6831-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411500541 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com xfs_bmap_del_extent() handles extent removal from the in-core and on-disk extent lists. When removing a delalloc range, it updates the indirect block reservation appropriately based on the removal. It currently enforces that the new indirect block reservation is less than or equal to the original. This is normally the case in all situations except for when the removed range creates a hole in a single delalloc extent, thus splitting a single delalloc extent in two. The indirect block reservation is divided evenly between the two new extents in this scenario. However, it is possible with small enough extents to split an indlen==1 extent into two such slightly smaller extents. This leaves one extent with 0 indirect blocks and leads to assert failures in other areas (e.g., xfs_bunmapi() if the extent happens to be removed). Refactor xfs_bunmapi() to make the updates that must be consistent against the inode (e.g., delalloc block counter, quota reservation) right before the extent is deleted. Move the sb block counter update after the extent is deleted and update xfs_bmap_del_extent() to steal some blocks from the freed extent if a larger overall indirect reservation is required by the extent removal. Signed-off-by: Brian Foster --- Hi all, I'm seeing the following assert more frequently with fsx and the recent xfs_free_file_space() changes (at least on 1k fsb fs'): XFS: Assertion failed: startblockval(del.br_startblock) > 0, file: fs/xfs/libxfs/xfs_bmap.c, line: 5281 This occurs for the reason described in the commit log description. This is a quick experiment I wanted to test to verify the problem goes away (so far, so good). Very lightly tested so far. I'm not too fond of changing br_blockcount like this. It seems like a potential landmine. Alternative approaches could be to kill the assert if we think indlen==0 extents is not a huge problem in this scenario, update the counters independently in xfs_bmap_del_extent() to get the needed blocks or pass a separate output parameter rather than messing with br_blockcount (e.g., '*ofreedblks'). The latter might mean we could just move the entire hunk that updates the inode/quota and whatnot rather than splitting it up. I wanted to put this on the list for comments. Thoughts? Other ideas? Thanks. Brian fs/xfs/libxfs/xfs_bmap.c | 64 ++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 86df952..1858e6b 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -4969,6 +4969,11 @@ xfs_bmap_del_extent( temp2 = xfs_bmap_worst_indlen(ip, temp2); new.br_startblock = nullstartblock((int)temp2); da_new = temp + temp2; + /* pull blocks from extent to make up the difference */ + while (da_new > da_old && del->br_blockcount) { + del->br_blockcount--; + da_new--; + } while (da_new > da_old) { if (temp) { temp--; @@ -5277,9 +5282,37 @@ xfs_bunmapi( goto nodelete; } } + + /* + * If it's the case where the directory code is running + * with no block reservation, and the deleted block is in + * the middle of its extent, and the resulting insert + * of an extent would cause transformation to btree format, + * then reject it. The calling code will then swap + * blocks around instead. + * We have to do this now, rather than waiting for the + * conversion to btree format, since the transaction + * will be dirty. + */ + if (!wasdel && xfs_trans_get_block_res(tp) == 0 && + XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && + XFS_IFORK_NEXTENTS(ip, whichfork) >= /* Note the >= */ + XFS_IFORK_MAXEXT(ip, whichfork) && + del.br_startoff > got.br_startoff && + del.br_startoff + del.br_blockcount < + got.br_startoff + got.br_blockcount) { + error = -ENOSPC; + goto error0; + } + + /* + * Unreserve quota and update realtime free space, if + * appropriate. If delayed allocation, update the inode delalloc + * counter now and wait to update the sb counters as + * xfs_bmap_del_extent() might need to borrow some blocks. + */ if (wasdel) { ASSERT(startblockval(del.br_startblock) > 0); - /* Update realtime/data freespace, unreserve quota */ if (isrt) { xfs_filblks_t rtexts; @@ -5291,8 +5324,6 @@ xfs_bunmapi( ip, -((long)del.br_blockcount), 0, XFS_QMOPT_RES_RTBLKS); } else { - xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, - (int64_t)del.br_blockcount, 0); (void)xfs_trans_reserve_quota_nblks(NULL, ip, -((long)del.br_blockcount), 0, XFS_QMOPT_RES_REGBLKS); @@ -5303,32 +5334,17 @@ xfs_bunmapi( XFS_BTCUR_BPRV_WASDEL; } else if (cur) cur->bc_private.b.flags &= ~XFS_BTCUR_BPRV_WASDEL; - /* - * If it's the case where the directory code is running - * with no block reservation, and the deleted block is in - * the middle of its extent, and the resulting insert - * of an extent would cause transformation to btree format, - * then reject it. The calling code will then swap - * blocks around instead. - * We have to do this now, rather than waiting for the - * conversion to btree format, since the transaction - * will be dirty. - */ - if (!wasdel && xfs_trans_get_block_res(tp) == 0 && - XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && - XFS_IFORK_NEXTENTS(ip, whichfork) >= /* Note the >= */ - XFS_IFORK_MAXEXT(ip, whichfork) && - del.br_startoff > got.br_startoff && - del.br_startoff + del.br_blockcount < - got.br_startoff + got.br_blockcount) { - error = -ENOSPC; - goto error0; - } + error = xfs_bmap_del_extent(ip, tp, &lastx, flist, cur, &del, &tmp_logflags, whichfork); logflags |= tmp_logflags; if (error) goto error0; + + if (!isrt && wasdel) + xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, + (int64_t) del.br_blockcount, 0); + bno = del.br_startoff - 1; nodelete: /* -- 1.8.3.1 From andi@firstfloor.org Tue Sep 23 15:02:21 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E47D329DF9 for ; Tue, 23 Sep 2014 15:02:20 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 70C1BAC006 for ; Tue, 23 Sep 2014 13:02:17 -0700 (PDT) X-ASG-Debug-ID: 1411502533-04cb6c50e5f9650001-NocioJ Received: from one.firstfloor.org (one.firstfloor.org [193.170.194.197]) by cuda.sgi.com with ESMTP id u0MWESpKdvae4WRV (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 23 Sep 2014 13:02:14 -0700 (PDT) X-Barracuda-Envelope-From: andi@firstfloor.org X-Barracuda-Apparent-Source-IP: 193.170.194.197 Received: by one.firstfloor.org (Postfix, from userid 503) id BF2FC869B6; Tue, 23 Sep 2014 22:02:12 +0200 (CEST) Date: Tue, 23 Sep 2014 22:02:12 +0200 From: Andi Kleen To: Olaf Weber Cc: Andi Kleen , Ben Myers , linux-fsdevel@vger.kernel.org, tinguely@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140923200212.GA15923@two.firstfloor.org> X-ASG-Orig-Subj: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <87lhpbhfgg.fsf@tassilo.jf.intel.com> <54216F20.1090302@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <54216F20.1090302@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) X-Barracuda-Connect: one.firstfloor.org[193.170.194.197] X-Barracuda-Start-Time: 1411502534 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9797 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- > The bulk of the table deals with Korean. Is a table of Korean exceptions 250k too? If not please find some other way to compress this. I'm sure there is redundancy somewhere. -Andi From andi@firstfloor.org Tue Sep 23 15:15:47 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 2C1AE29DF9 for ; Tue, 23 Sep 2014 15:15:47 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 0BE8A304032 for ; Tue, 23 Sep 2014 13:15:43 -0700 (PDT) X-ASG-Debug-ID: 1411503340-04bdf003a110a670001-NocioJ Received: from one.firstfloor.org (one.firstfloor.org [193.170.194.197]) by cuda.sgi.com with ESMTP id mZTA34kEFsGX1Baa (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 23 Sep 2014 13:15:42 -0700 (PDT) X-Barracuda-Envelope-From: andi@firstfloor.org X-Barracuda-Apparent-Source-IP: 193.170.194.197 Received: by one.firstfloor.org (Postfix, from userid 503) id 8258C869B6; Tue, 23 Sep 2014 22:15:40 +0200 (CEST) Date: Tue, 23 Sep 2014 22:15:40 +0200 From: Andi Kleen To: Olaf Weber Cc: Andi Kleen , Ben Myers , linux-fsdevel@vger.kernel.org, tinguely@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140923201540.GB15923@two.firstfloor.org> X-ASG-Orig-Subj: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <87lhpbhfgg.fsf@tassilo.jf.intel.com> <20140922184145.GH4482@sgi.com> <20140922192958.GJ4120@two.firstfloor.org> <54219C17.3090104@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <54219C17.3090104@sgi.com> User-Agent: Mutt/1.5.20 (2009-06-14) X-Barracuda-Connect: one.firstfloor.org[193.170.194.197] X-Barracuda-Start-Time: 1411503341 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9797 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- > You only pay the space cost if you use it, similar to the nls tables. The way Linux module loading works these things are loaded by default, not when someone needs it. So no, you (or rather every unfortunate Linux XFS user) would pay it always, unless you black list the module or rebuild the kernel. > A big part of the table does decompositions for Korean: eliminating > the Hangul decompositions removes 156320 bytes, leaving 89936 bytes. Are there regular ranges or other redundancies in the Korean encoding that could be used to compress paths? Doing some basic research other people already answered this: Please use the ICU or google tables referenced below. Apparently smaller is possible too, but 40-50k seems more reasonable. I'm just gonna make the claim that whatever performance you get from a larger table is dwarfed by the cache miss overhead. ---- http://macchiato.com/unicode/normalization_footprint.htm http://www.macchiato.com/unicode/nfc-faq NFC normalization requires large tables, right? Like many other cases, there is a tradeoff between size and performance. You can use very small tables, at some cost in performance. (Even there, the actual performance cost depends on how often normalization needs to be invoked, as discussed above.) To see an analysis of the situation, see Normalization Footprint. It is a bit out of date, but gives a sense of the magnitude. For comparison, ICU's optimized tables for NFC take 44 kB (UTF-16) and Google's optimized tables for NFC take 46 kB (UTF-8). -Andi From bpm@sgi.com Tue Sep 23 15:45:14 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 0197B29DF9 for ; Tue, 23 Sep 2014 15:45:14 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay3.corp.sgi.com (Postfix) with ESMTP id 765E7AC007; Tue, 23 Sep 2014 13:45:13 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 186974266DC; Tue, 23 Sep 2014 15:45:13 -0500 (CDT) Date: Tue, 23 Sep 2014 15:45:13 -0500 From: Ben Myers To: Andi Kleen Cc: Olaf Weber , linux-fsdevel@vger.kernel.org, tinguely@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140923204512.GI4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <87lhpbhfgg.fsf@tassilo.jf.intel.com> <20140922184145.GH4482@sgi.com> <20140922192958.GJ4120@two.firstfloor.org> <54219C17.3090104@sgi.com> <20140923201540.GB15923@two.firstfloor.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140923201540.GB15923@two.firstfloor.org> User-Agent: Mutt/1.5.20 (2009-06-14) Hi Andi, On Tue, Sep 23, 2014 at 10:15:40PM +0200, Andi Kleen wrote: > > You only pay the space cost if you use it, similar to the nls tables. > > The way Linux module loading works these things are loaded by default, > not when someone needs it. > > So no, you (or rather every unfortunate Linux XFS user) would pay it always, > unless you black list the module or rebuild the kernel. The suggestion to use symbol_get was made in response to the initial post of the series. In my testing the normalization module did not load until I attempted to mount a filesystem which required it. Seems to work ok. See patch 10, "xfs: implement demand load of utf8norm.ko". Thanks, Ben From david@fromorbit.com Tue Sep 23 16:58:27 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D70C529DF9 for ; Tue, 23 Sep 2014 16:58:26 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5302AAC004 for ; Tue, 23 Sep 2014 14:58:26 -0700 (PDT) X-ASG-Debug-ID: 1411509500-04cbb07303108820001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id 7E8smsQ5TM95Ictg for ; Tue, 23 Sep 2014 14:58:20 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtdFAP/rIVR5LM9HPGdsb2JhbABggw6BKoc4rWsBAQEBAQaWEoVqAgIBAQGBDBcBBgEBAQE4OIQDAQEBAwEnExwjBQsIAw4KCSUPBSUDBxoTiDYHwncBFxiFdYktTQeDLoEdBYYilnmZSCsvgQeBQwEBAQ Received: from ppp121-44-207-71.lns20.syd7.internode.on.net (HELO dastard) ([121.44.207.71]) by ipmail04.adl6.internode.on.net with ESMTP; 24 Sep 2014 07:28:19 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XWY6C-0000Z9-W4; Wed, 24 Sep 2014 07:58:17 +1000 Date: Wed, 24 Sep 2014 07:58:16 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [RFC PATCH] xfs: borrow indirect blocks from freed extent when available Message-ID: <20140923215816.GC4322@dastard> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: borrow indirect blocks from freed extent when available References: <1411500538-6831-1-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411500538-6831-1-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411509500 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9801 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 23, 2014 at 03:28:58PM -0400, Brian Foster wrote: > xfs_bmap_del_extent() handles extent removal from the in-core and > on-disk extent lists. When removing a delalloc range, it updates the > indirect block reservation appropriately based on the removal. It > currently enforces that the new indirect block reservation is less than > or equal to the original. This is normally the case in all situations > except for when the removed range creates a hole in a single delalloc > extent, thus splitting a single delalloc extent in two. > > The indirect block reservation is divided evenly between the two new > extents in this scenario. However, it is possible with small enough > extents to split an indlen==1 extent into two such slightly smaller > extents. This leaves one extent with 0 indirect blocks and leads to > assert failures in other areas (e.g., xfs_bunmapi() if the extent > happens to be removed). I had long suspected we had an issue in this code, but was never able to nail down a reproducer that triggered it. Do you have a reproducer, or did you find this by reading/tracing the code? > Refactor xfs_bunmapi() to make the updates that must be consistent > against the inode (e.g., delalloc block counter, quota reservation) > right before the extent is deleted. Move the sb block counter update > after the extent is deleted and update xfs_bmap_del_extent() to steal > some blocks from the freed extent if a larger overall indirect > reservation is required by the extent removal. > > Signed-off-by: Brian Foster > --- > > Hi all, > > I'm seeing the following assert more frequently with fsx and the recent > xfs_free_file_space() changes (at least on 1k fsb fs'): > > XFS: Assertion failed: startblockval(del.br_startblock) > 0, file: fs/xfs/libxfs/xfs_bmap.c, line: 5281 > > This occurs for the reason described in the commit log description. This > is a quick experiment I wanted to test to verify the problem goes away > (so far, so good). Very lightly tested so far. I suspect it's also the cause of these occasional assert failures that I see: XFS: Assertion failed: tp->t_blk_res_used <= tp->t_blk_res, file: fs/xfs/xfs_trans.c, line: 327 during delalloc conversion because there wasn't a space reservation for the blocks allocated (i.e. indlen was zero) and so we overrun the transaction block reservation. > I'm not too fond of changing br_blockcount like this. It seems like a > potential landmine. Alternative approaches could be to kill the assert > if we think indlen==0 extents is not a huge problem in this scenario, A delalloc extent always needs a reservation.... > update the counters independently in xfs_bmap_del_extent() to get the > needed blocks or pass a separate output parameter rather than messing > with br_blockcount (e.g., '*ofreedblks'). The latter might mean we could > just move the entire hunk that updates the inode/quota and whatnot > rather than splitting it up. > > I wanted to put this on the list for comments. Thoughts? Other ideas? > Thanks. > > Brian > > fs/xfs/libxfs/xfs_bmap.c | 64 ++++++++++++++++++++++++++++++------------------ > 1 file changed, 40 insertions(+), 24 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > index 86df952..1858e6b 100644 > --- a/fs/xfs/libxfs/xfs_bmap.c > +++ b/fs/xfs/libxfs/xfs_bmap.c > @@ -4969,6 +4969,11 @@ xfs_bmap_del_extent( > temp2 = xfs_bmap_worst_indlen(ip, temp2); > new.br_startblock = nullstartblock((int)temp2); > da_new = temp + temp2; > + /* pull blocks from extent to make up the difference */ > + while (da_new > da_old && del->br_blockcount) { > + del->br_blockcount--; > + da_new--; > + } > while (da_new > da_old) { > if (temp) { > temp--; So this is the crux of the fix, right? The block stealing from the deleted extent? I have no objections to doing this given that we already munge the indirect reservations inteh loop below, but I think we should make this cleaner and more understandable. i.e. refactor the indlen adjustment code into a helper, and integrate the block stealing into the existing adjustment loop? > @@ -5277,9 +5282,37 @@ xfs_bunmapi( > goto nodelete; > } > } > + > + /* > + * If it's the case where the directory code is running > + * with no block reservation, and the deleted block is in > + * the middle of its extent, and the resulting insert > + * of an extent would cause transformation to btree format, > + * then reject it. The calling code will then swap > + * blocks around instead. > + * We have to do this now, rather than waiting for the > + * conversion to btree format, since the transaction > + * will be dirty. > + */ > + if (!wasdel && xfs_trans_get_block_res(tp) == 0 && > + XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && > + XFS_IFORK_NEXTENTS(ip, whichfork) >= /* Note the >= */ > + XFS_IFORK_MAXEXT(ip, whichfork) && > + del.br_startoff > got.br_startoff && > + del.br_startoff + del.br_blockcount < > + got.br_startoff + got.br_blockcount) { > + error = -ENOSPC; > + goto error0; > + } > + > + /* > + * Unreserve quota and update realtime free space, if > + * appropriate. If delayed allocation, update the inode delalloc > + * counter now and wait to update the sb counters as > + * xfs_bmap_del_extent() might need to borrow some blocks. > + */ > if (wasdel) { > ASSERT(startblockval(del.br_startblock) > 0); > - /* Update realtime/data freespace, unreserve quota */ > if (isrt) { > xfs_filblks_t rtexts; > Perhaps this should be separated into it's own patch that is applied first? It doesn't seem to be directly related to the accounting fix... Cheers, Dave. -- Dave Chinner david@fromorbit.com From diane@caltech.edu Tue Sep 23 17:03:04 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 6718929DF9 for ; Tue, 23 Sep 2014 17:03:04 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4711E8F8054 for ; Tue, 23 Sep 2014 15:03:04 -0700 (PDT) X-ASG-Debug-ID: 1411509779-04bdf003a110f3f0001-NocioJ Received: from chaos.caltech.edu (chaos.caltech.edu [131.215.34.119]) by cuda.sgi.com with ESMTP id GeCfvKZEcy0TT04h (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO) for ; Tue, 23 Sep 2014 15:02:59 -0700 (PDT) X-Barracuda-Envelope-From: diane@caltech.edu X-Barracuda-Apparent-Source-IP: 131.215.34.119 Received: from [50.1.221.254] (helo=myrada.localnet) by chaos.caltech.edu with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.80) (envelope-from ) id 1XWYAl-0005CP-3e for xfs@oss.sgi.com; Tue, 23 Sep 2014 15:02:59 -0700 From: Diane Trout To: xfs@oss.sgi.com Subject: Corrupted file system Date: Tue, 23 Sep 2014 15:02:57 -0700 X-ASG-Orig-Subj: Corrupted file system Message-ID: <5839367.DyqsVHbRuQ@myrada> User-Agent: KMail/4.14 (Linux/3.14-2-amd64; KDE/4.14.0; x86_64; ; ) MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" X-Barracuda-Connect: chaos.caltech.edu[131.215.34.119] X-Barracuda-Start-Time: 1411509779 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9801 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi, I had a raid failure at work that ended up corrupting an xfs filesystem the tail of the xfs_repair command looks like the below. I was able to generate a metadata dump but is there a point to making it available? It does crash repeatedly at the same place (I'm not subscribed to the list, so could you reply directly as well?) disconnected inode 15276, moving to lost+found disconnected inode 15277, moving to lost+found disconnected inode 15278, moving to lost+found disconnected inode 15279, moving to lost+found disconnected inode 15280, moving to lost+found disconnected inode 15281, moving to lost+found disconnected inode 15282, moving to lost+found disconnected inode 15283, moving to lost+found disconnected inode 15284, moving to lost+found disconnected inode 15286, moving to lost+found disconnected inode 15287, moving to lost+found disconnected inode 15288, moving to lost+found disconnected inode 15289, moving to lost+found disconnected inode 15290, moving to lost+found disconnected inode 15291, moving to lost+found disconnected inode 15292, moving to lost+found disconnected inode 15293, moving to lost+found disconnected inode 15294, moving to lost+found disconnected inode 15295, moving to lost+found disconnected inode 15360, moving to lost+found corrupt dinode 15360, extent total = 1, nblocks = 0. This is a bug. Please capture the filesystem metadata with xfs_metadump and report it to xfs@oss.sgi.com. cache_node_purge: refcount was 1, not zero (node=0x7f369883e6f0) fatal error -- 117 - couldn't iget disconnected inode From scaron@umich.edu Tue Sep 23 17:12:26 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 53DC729DF9 for ; Tue, 23 Sep 2014 17:12:26 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 316FE8F804B for ; Tue, 23 Sep 2014 15:12:26 -0700 (PDT) X-ASG-Debug-ID: 1411510343-04cbb073011090d0001-NocioJ Received: from mail-wi0-f171.google.com (mail-wi0-f171.google.com [209.85.212.171]) by cuda.sgi.com with ESMTP id rE14Z9Vxog1xz3Vr (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Tue, 23 Sep 2014 15:12:24 -0700 (PDT) X-Barracuda-Envelope-From: scaron@umich.edu X-Barracuda-Apparent-Source-IP: 209.85.212.171 Received: by mail-wi0-f171.google.com with SMTP id ho1so5813071wib.10 for ; Tue, 23 Sep 2014 15:12:23 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=W1ozXICjc4+Mbem/Pft8QUXJ/3szkm+LH6NgBWw1s9E=; b=E4wQH3+cL/nBhktGBbI8w+bUKiX+BVkVnx0vVokudCrqEhDbqVyREI37WrraFOH0hs PKB4bC9KMPzQJZnAD1iHk6T6Qv+6dmAMtxNzvXFULAKA2Bk4S3hPLazL2nGl5rKkiGWJ vf7kxPB94V2i4bGswS9oyJHPp7JM/CmhpSgxnZAqmWZQcNxloefmAJrhjx1t3V5PeO4i wSZ0ZXZclo8SxY4BLdvq8/fAKVepbLWcJgUCy7rapqzWKJSrNChdveJspDlLMJnlM9Ti 1ZDKcSQEkp5TzmydRZF3dFfjpFxgPrNiob7aqBpL6O6JSQRZqe5JMG7JR5cgME142PR3 vroQ== X-Gm-Message-State: ALoCoQmmC1akWxX8vQ7iWQKincLcITMV7izWaLbY2XB9Lnv23fwEGj/pfrDA/4bcQYiZpuplxZRC MIME-Version: 1.0 X-Received: by 10.180.93.99 with SMTP id ct3mr26790915wib.0.1411510342982; Tue, 23 Sep 2014 15:12:22 -0700 (PDT) Received: by 10.27.178.161 with HTTP; Tue, 23 Sep 2014 15:12:22 -0700 (PDT) In-Reply-To: <5839367.DyqsVHbRuQ@myrada> References: <5839367.DyqsVHbRuQ@myrada> Date: Tue, 23 Sep 2014 18:12:22 -0400 Message-ID: Subject: Re: Corrupted file system From: Sean Caron X-ASG-Orig-Subj: Re: Corrupted file system To: Diane Trout , Sean Caron Cc: "xfs@oss.sgi.com" Content-Type: multipart/alternative; boundary=f46d043c08e8972c060503c2dc8f X-Barracuda-Connect: mail-wi0-f171.google.com[209.85.212.171] X-Barracuda-Start-Time: 1411510343 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9801 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message --f46d043c08e8972c060503c2dc8f Content-Type: text/plain; charset=UTF-8 Hi Diane, Probably best to reformat and restore from a backup at this point. I'm notorious for my views on xfs_repair but most folks here will agree that in the case where there has been a major underlying array failure, there is not much it can do to help. Better to just mount ro,noreplaylog and get what you can in these sorts of scenarios, IMO. "Did you try the latest copy of xfs_repair"? Sometimes it will get further or not crash, but it likely will still maul whatever's left of your filesystem. Best of luck, Sean On Tue, Sep 23, 2014 at 6:02 PM, Diane Trout wrote: > Hi, > > I had a raid failure at work that ended up corrupting an xfs filesystem the > tail of the xfs_repair command looks like the below. I was able to > generate a > metadata dump but is there a point to making it available? > > It does crash repeatedly at the same place > > (I'm not subscribed to the list, so could you reply directly as well?) > > disconnected inode 15276, moving to lost+found > disconnected inode 15277, moving to lost+found > disconnected inode 15278, moving to lost+found > disconnected inode 15279, moving to lost+found > disconnected inode 15280, moving to lost+found > disconnected inode 15281, moving to lost+found > disconnected inode 15282, moving to lost+found > disconnected inode 15283, moving to lost+found > disconnected inode 15284, moving to lost+found > disconnected inode 15286, moving to lost+found > disconnected inode 15287, moving to lost+found > disconnected inode 15288, moving to lost+found > disconnected inode 15289, moving to lost+found > disconnected inode 15290, moving to lost+found > disconnected inode 15291, moving to lost+found > disconnected inode 15292, moving to lost+found > disconnected inode 15293, moving to lost+found > disconnected inode 15294, moving to lost+found > disconnected inode 15295, moving to lost+found > disconnected inode 15360, moving to lost+found > corrupt dinode 15360, extent total = 1, nblocks = 0. This is a bug. > Please capture the filesystem metadata with xfs_metadump and > report it to xfs@oss.sgi.com. > cache_node_purge: refcount was 1, not zero (node=0x7f369883e6f0) > > fatal error -- 117 - couldn't iget disconnected inode > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs > --f46d043c08e8972c060503c2dc8f Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi Diane,

Probably best to reformat and= restore from a backup at this point. I'm notorious for my views on xfs= _repair but most folks here will agree that in the case where there has bee= n a major underlying array failure, there is not much it can do to help. Be= tter to just mount ro,noreplaylog and get what you can in these sorts of sc= enarios, IMO.

"Did you try the latest copy of= xfs_repair"? Sometimes it will get further or not crash, but it likel= y will still maul whatever's left of your filesystem.

Best of luck,

Sean


On Tue, Sep 23= , 2014 at 6:02 PM, Diane Trout <diane@caltech.edu> wrote:
Hi,

I had a raid failure at work that ended up corrupting an xfs filesystem the=
tail of the xfs_repair command looks like the below. I was able to generate= a
metadata dump but is there a point to making it available?

It does crash repeatedly at the same place

(I'm not subscribed to the list, so could you reply directly as well?)<= br>
disconnected inode 15276, moving to lost+found
disconnected inode 15277, moving to lost+found
disconnected inode 15278, moving to lost+found
disconnected inode 15279, moving to lost+found
disconnected inode 15280, moving to lost+found
disconnected inode 15281, moving to lost+found
disconnected inode 15282, moving to lost+found
disconnected inode 15283, moving to lost+found
disconnected inode 15284, moving to lost+found
disconnected inode 15286, moving to lost+found
disconnected inode 15287, moving to lost+found
disconnected inode 15288, moving to lost+found
disconnected inode 15289, moving to lost+found
disconnected inode 15290, moving to lost+found
disconnected inode 15291, moving to lost+found
disconnected inode 15292, moving to lost+found
disconnected inode 15293, moving to lost+found
disconnected inode 15294, moving to lost+found
disconnected inode 15295, moving to lost+found
disconnected inode 15360, moving to lost+found
corrupt dinode 15360, extent total =3D 1, nblocks =3D 0.=C2=A0 This is a bu= g.
Please capture the filesystem metadata with xfs_metadump and
report it to xfs@oss.sgi.com.
cache_node_purge: refcount was 1, not zero (node=3D0x7f369883e6f0)

fatal error -- 117 - couldn't iget disconnected inode


_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http:= //oss.sgi.com/mailman/listinfo/xfs

--f46d043c08e8972c060503c2dc8f-- From diane@caltech.edu Tue Sep 23 17:29:54 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BB00429DF9 for ; Tue, 23 Sep 2014 17:29:54 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 33B4AAC008 for ; Tue, 23 Sep 2014 15:29:48 -0700 (PDT) X-ASG-Debug-ID: 1411511385-04cbb07301109bb0001-NocioJ Received: from chaos.caltech.edu (chaos.caltech.edu [131.215.34.119]) by cuda.sgi.com with ESMTP id 4MjiRUEpbiwXVJJ4 (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO) for ; Tue, 23 Sep 2014 15:29:46 -0700 (PDT) X-Barracuda-Envelope-From: diane@caltech.edu X-Barracuda-Apparent-Source-IP: 131.215.34.119 Received: from [50.1.221.254] (helo=myrada.localnet) by chaos.caltech.edu with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.80) (envelope-from ) id 1XWYaf-0005G2-1q; Tue, 23 Sep 2014 15:29:45 -0700 From: Diane Trout To: Sean Caron Cc: "xfs@oss.sgi.com" Subject: Re: Corrupted file system Date: Tue, 23 Sep 2014 15:29:43 -0700 X-ASG-Orig-Subj: Re: Corrupted file system Message-ID: <6825577.fQrC5yyUIR@myrada> User-Agent: KMail/4.14 (Linux/3.14-2-amd64; KDE/4.14.0; x86_64; ; ) In-Reply-To: References: <5839367.DyqsVHbRuQ@myrada> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" X-Barracuda-Connect: chaos.caltech.edu[131.215.34.119] X-Barracuda-Start-Time: 1411511386 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9802 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hello, Yes, I had my doubts about that there's anything reasonable one could do after part of the file system was randomized. I'll trying updating to xfsprogs 3.2.1 and see if that does any better. Thank you for the advice. Diane On Tuesday, September 23, 2014 18:12:22 Sean Caron wrote: > Hi Diane, > > Probably best to reformat and restore from a backup at this point. I'm > notorious for my views on xfs_repair but most folks here will agree that in > the case where there has been a major underlying array failure, there is > not much it can do to help. Better to just mount ro,noreplaylog and get > what you can in these sorts of scenarios, IMO. > > "Did you try the latest copy of xfs_repair"? Sometimes it will get further > or not crash, but it likely will still maul whatever's left of your > filesystem. > > Best of luck, > > Sean > > On Tue, Sep 23, 2014 at 6:02 PM, Diane Trout wrote: > > Hi, > > > > I had a raid failure at work that ended up corrupting an xfs filesystem > > the > > tail of the xfs_repair command looks like the below. I was able to > > generate a > > metadata dump but is there a point to making it available? > > > > It does crash repeatedly at the same place > > > > (I'm not subscribed to the list, so could you reply directly as well?) > > > > disconnected inode 15276, moving to lost+found > > disconnected inode 15277, moving to lost+found > > disconnected inode 15278, moving to lost+found > > disconnected inode 15279, moving to lost+found > > disconnected inode 15280, moving to lost+found > > disconnected inode 15281, moving to lost+found > > disconnected inode 15282, moving to lost+found > > disconnected inode 15283, moving to lost+found > > disconnected inode 15284, moving to lost+found > > disconnected inode 15286, moving to lost+found > > disconnected inode 15287, moving to lost+found > > disconnected inode 15288, moving to lost+found > > disconnected inode 15289, moving to lost+found > > disconnected inode 15290, moving to lost+found > > disconnected inode 15291, moving to lost+found > > disconnected inode 15292, moving to lost+found > > disconnected inode 15293, moving to lost+found > > disconnected inode 15294, moving to lost+found > > disconnected inode 15295, moving to lost+found > > disconnected inode 15360, moving to lost+found > > corrupt dinode 15360, extent total = 1, nblocks = 0. This is a bug. > > Please capture the filesystem metadata with xfs_metadump and > > report it to xfs@oss.sgi.com. > > cache_node_purge: refcount was 1, not zero (node=0x7f369883e6f0) > > > > fatal error -- 117 - couldn't iget disconnected inode > > > > > > _______________________________________________ > > xfs mailing list > > xfs@oss.sgi.com > > http://oss.sgi.com/mailman/listinfo/xfs From sandeen@sandeen.net Tue Sep 23 18:12:42 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 001727F4E for ; Tue, 23 Sep 2014 18:12:42 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id D448D304039 for ; Tue, 23 Sep 2014 16:12:38 -0700 (PDT) X-ASG-Debug-ID: 1411513953-04cb6c50e61010b0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id BQnRmRpq4WElZ5H3 for ; Tue, 23 Sep 2014 16:12:34 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 9D432602D74F; Tue, 23 Sep 2014 18:12:33 -0500 (CDT) Message-ID: <5421FE61.30508@sandeen.net> Date: Tue, 23 Sep 2014 18:12:33 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Diane Trout , Sean Caron CC: "xfs@oss.sgi.com" Subject: Re: Corrupted file system References: <5839367.DyqsVHbRuQ@myrada> <6825577.fQrC5yyUIR@myrada> X-ASG-Orig-Subj: Re: Corrupted file system In-Reply-To: <6825577.fQrC5yyUIR@myrada> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1411513954 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9802 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/23/14 5:29 PM, Diane Trout wrote: > Hello, > > Yes, I had my doubts about that there's anything reasonable one could do after > part of the file system was randomized. I'll trying updating to xfsprogs 3.2.1 > and see if that does any better. Yes - you didn't mention which version you used, but I'd definitely try something current. The bug rings a bell, maybe fixed now. To be safe, you can always make an xfs_metadump image (use -o to not obfuscate filenames for convenience), xfs_mdrestore that, and point repair at that fs image. Then you'll see what it *would* do before you *do* do. ;) But yeah, depending on the damage done to the storage, you may be in trouble that repair can't help with. Depends on the failure, though. -Eric From tessarek@evermeet.cx Tue Sep 23 19:46:43 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 170C77F3F for ; Tue, 23 Sep 2014 19:46:43 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 05113304048 for ; Tue, 23 Sep 2014 17:46:39 -0700 (PDT) X-ASG-Debug-ID: 1411519596-04cb6c50e6104140001-NocioJ Received: from atvie01s.evermeet.cx (evermeet.cx [77.244.245.66]) by cuda.sgi.com with ESMTP id pAAVrkwyonDJ2QtJ (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 23 Sep 2014 17:46:37 -0700 (PDT) X-Barracuda-Envelope-From: tessarek@evermeet.cx X-Barracuda-Apparent-Source-IP: 77.244.245.66 Received: from [10.0.0.40] (135-23-85-229.cpe.pppoe.ca [135.23.85.229]) (authenticated bits=0) by atvie01s.evermeet.cx (8.14.9/8.14.9) with ESMTP id s8O0kXKW008177 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Wed, 24 Sep 2014 02:46:34 +0200 Message-ID: <5422146A.90206@evermeet.cx> Date: Tue, 23 Sep 2014 20:46:34 -0400 From: Helmut Tessarek User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:31.0) Gecko/20100101 Thunderbird/31.1.1 MIME-Version: 1.0 To: xfs@oss.sgi.com Subject: How to format RAID1 correctly OpenPGP: id=C11F128D X-ASG-Orig-Subj: How to format RAID1 correctly Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: evermeet.cx[77.244.245.66] X-Barracuda-Start-Time: 1411519597 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-BRTS-Evidence: pkqs.net X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9805 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- The information provided in the FAQ and on several web sites is not really useful regarding RAID1. According to the FAQ (entry 35): The correct options to format a RAID1 (2 disks) with 64k chunk size is: mkfs.xfs -d su=64k -d sw=1 /dev/mapper/data But it also states that it would be automatically detected and used correctly, yet mkfs.xfs /dev/mapper/data yields a different result: [root@atvie01s ~]# mkfs.xfs -f /dev/mapper/data meta-data=/dev/mapper/data isize=256 agcount=4, agsize=244173876 blks = sectsz=4096 attr=2, projid32bit=1 = crc=0 finobt=0 data = bsize=4096 blocks=976695504, imaxpct=5 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=0 log =internal log bsize=4096 blocks=476902, version=2 = sectsz=4096 sunit=1 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 Formel 1: [root@atvie01s ~]# mkfs.xfs -f -d su=64k -d sw=1 /dev/mapper/data meta-data=/dev/mapper/data isize=256 agcount=32, agsize=30521728 blks = sectsz=4096 attr=2, projid32bit=1 = crc=0 finobt=0 data = bsize=4096 blocks=976695296, imaxpct=5 = sunit=16 swidth=16 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=0 log =internal log bsize=4096 blocks=476902, version=2 = sectsz=4096 sunit=1 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 Another inconsistency is that RAID1 doesn't use striping, so the chunk size should be irrelevant in the first place. So what is ultimately the correct way to format a RAID1? Cheers, K. C. -- regards Helmut K. C. Tessarek lookup http://sks.pkqs.net for KeyID 0xC11F128D /* Thou shalt not follow the NULL pointer for chaos and madness await thee at its end. */ From tessarek@evermeet.cx Tue Sep 23 21:05:16 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 768397F3F for ; Tue, 23 Sep 2014 21:05:16 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5BAA9304048 for ; Tue, 23 Sep 2014 19:05:13 -0700 (PDT) X-ASG-Debug-ID: 1411524304-04cbb073031115d0001-NocioJ Received: from atvie01s.evermeet.cx (evermeet.cx [77.244.245.66]) by cuda.sgi.com with ESMTP id gvDLIWajZ4uNoz7T (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 23 Sep 2014 19:05:05 -0700 (PDT) X-Barracuda-Envelope-From: tessarek@evermeet.cx X-Barracuda-Apparent-Source-IP: 77.244.245.66 Received: from [10.0.0.40] (135-23-85-229.cpe.pppoe.ca [135.23.85.229]) (authenticated bits=0) by atvie01s.evermeet.cx (8.14.9/8.14.9) with ESMTP id s8O252Cq008420 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Wed, 24 Sep 2014 04:05:04 +0200 Message-ID: <542226CD.6050106@evermeet.cx> Date: Tue, 23 Sep 2014 22:05:01 -0400 From: Helmut Tessarek User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:31.0) Gecko/20100101 Thunderbird/31.1.1 MIME-Version: 1.0 To: xfs@oss.sgi.com Subject: Re: How to format RAID1 correctly References: <5422146A.90206@evermeet.cx> X-ASG-Orig-Subj: Re: How to format RAID1 correctly In-Reply-To: <5422146A.90206@evermeet.cx> OpenPGP: id=C11F128D Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: evermeet.cx[77.244.245.66] X-Barracuda-Start-Time: 1411524305 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-BRTS-Evidence: pkqs.net X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9809 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 23.09.14 20:46 , Helmut Tessarek wrote: > So what is ultimately the correct way to format a RAID1? According to sandeen in #xfs the correct way is: mkfs.xfs /dev/md0 Makes sense, since no striping is involved. Just wanted to clarify and I did. Cheers, K. C. -- regards Helmut K. C. Tessarek lookup http://sks.pkqs.net for KeyID 0xC11F128D /* Thou shalt not follow the NULL pointer for chaos and madness await thee at its end. */ From sandeen@sandeen.net Tue Sep 23 21:07:37 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1360B7F3F for ; Tue, 23 Sep 2014 21:07:37 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id A1F67AC006 for ; Tue, 23 Sep 2014 19:07:33 -0700 (PDT) X-ASG-Debug-ID: 1411524451-04bdf0039f117490001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id hB9ThZMKbyeZjNF6 for ; Tue, 23 Sep 2014 19:07:32 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 8B67E63D2063; Tue, 23 Sep 2014 21:07:31 -0500 (CDT) Message-ID: <54222763.40107@sandeen.net> Date: Tue, 23 Sep 2014 21:07:31 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Helmut Tessarek , xfs@oss.sgi.com Subject: Re: How to format RAID1 correctly References: <5422146A.90206@evermeet.cx> X-ASG-Orig-Subj: Re: How to format RAID1 correctly In-Reply-To: <5422146A.90206@evermeet.cx> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1411524451 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9809 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/23/14 7:46 PM, Helmut Tessarek wrote: > The information provided in the FAQ and on several web sites is not really > useful regarding RAID1. > > According to the FAQ (entry 35): > The correct options to format a RAID1 (2 disks) with 64k chunk size is: > mkfs.xfs -d su=64k -d sw=1 /dev/mapper/data I don't see that text in the faq... where is it? I see: > So if your RAID controller has a stripe size of 64KB, and you have a RAID-6 with 8 disks, use > > su = 64k > sw = 6 (RAID-6 of 8 disks has 6 data disks) but! your raid doesn't have a 64k stripe, so that doesn't apply. > But it also states that it would be automatically detected and used correctly, > yet > mkfs.xfs /dev/mapper/data > yields a different result: > > [root@atvie01s ~]# mkfs.xfs -f /dev/mapper/data > > meta-data=/dev/mapper/data isize=256 agcount=4, > agsize=244173876 blks > = sectsz=4096 attr=2, projid32bit=1 > = crc=0 finobt=0 > data = bsize=4096 blocks=976695504, imaxpct=5 > = sunit=0 swidth=0 blks no geometry because md0 raid1 doesn't export any stripe geometry. > Formel 1: > > [root@atvie01s ~]# mkfs.xfs -f -d su=64k -d sw=1 /dev/mapper/data > > meta-data=/dev/mapper/data isize=256 agcount=32, > agsize=30521728 blks > = sectsz=4096 attr=2, projid32bit=1 > = crc=0 finobt=0 > data = bsize=4096 blocks=976695296, imaxpct=5 > = sunit=16 swidth=16 blks You specified it, so mkfs obeyed. > naming =version 2 bsize=4096 ascii-ci=0 ftype=0 > log =internal log bsize=4096 blocks=476902, version=2 > = sectsz=4096 sunit=1 blks, lazy-count=1 > realtime =none extsz=4096 blocks=0, rtextents=0 > > > Another inconsistency is that RAID1 doesn't use striping, so the chunk size > should be irrelevant in the first place. agreed - but I don't see anything in the faq about raid1 stripes. Am I missing something? > So what is ultimately the correct way to format a RAID1? for software md raid over individual disks, bare mkfs should do the right thing. -Eric From tessarek@evermeet.cx Tue Sep 23 21:11:44 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 048007F3F for ; Tue, 23 Sep 2014 21:11:44 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id D2F628F8039 for ; Tue, 23 Sep 2014 19:11:43 -0700 (PDT) X-ASG-Debug-ID: 1411524701-04cb6c50e4106a30001-NocioJ Received: from atvie01s.evermeet.cx (evermeet.cx [77.244.245.66]) by cuda.sgi.com with ESMTP id MsFaggxQmvLN0OjN (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 23 Sep 2014 19:11:42 -0700 (PDT) X-Barracuda-Envelope-From: tessarek@evermeet.cx X-Barracuda-Apparent-Source-IP: 77.244.245.66 Received: from [10.0.0.40] (135-23-85-229.cpe.pppoe.ca [135.23.85.229]) (authenticated bits=0) by atvie01s.evermeet.cx (8.14.9/8.14.9) with ESMTP id s8O2BdiM008542 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Wed, 24 Sep 2014 04:11:40 +0200 Message-ID: <5422285B.6010306@evermeet.cx> Date: Tue, 23 Sep 2014 22:11:39 -0400 From: Helmut Tessarek User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:31.0) Gecko/20100101 Thunderbird/31.1.1 MIME-Version: 1.0 To: Eric Sandeen , xfs@oss.sgi.com Subject: Re: How to format RAID1 correctly References: <5422146A.90206@evermeet.cx> <54222763.40107@sandeen.net> X-ASG-Orig-Subj: Re: How to format RAID1 correctly In-Reply-To: <54222763.40107@sandeen.net> OpenPGP: id=C11F128D Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: evermeet.cx[77.244.245.66] X-Barracuda-Start-Time: 1411524701 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9808 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 23.09.14 22:07 , Eric Sandeen wrote: > but! your raid doesn't have a 64k stripe, so that doesn't apply. Yep, that's true, but see below. > no geometry because md0 raid1 doesn't export any stripe geometry. [root@atvie01s ~]# cat /proc/mdstat Personalities : [raid1] md0 : active raid1 sdb1[0] sdd1[1] 3906784064 blocks super 1.2 [2/2] [UU] bitmap: 0/30 pages [0KB], 65536KB chunk So for some reason it shows a 64k chunk size even for RAID1. That was what got me confused. -- regards Helmut K. C. Tessarek lookup http://sks.pkqs.net for KeyID 0xC11F128D /* Thou shalt not follow the NULL pointer for chaos and madness await thee at its end. */ From sandeen@sandeen.net Tue Sep 23 21:21:27 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 185A97F3F for ; Tue, 23 Sep 2014 21:21:27 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 97A66AC004 for ; Tue, 23 Sep 2014 19:21:26 -0700 (PDT) X-ASG-Debug-ID: 1411525285-04cb6c50e7106f80001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id vMWRR3dQ5IdqOgFH for ; Tue, 23 Sep 2014 19:21:25 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 248B063D22A4; Tue, 23 Sep 2014 21:21:25 -0500 (CDT) Message-ID: <54222AA4.5010501@sandeen.net> Date: Tue, 23 Sep 2014 21:21:24 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Helmut Tessarek , xfs@oss.sgi.com Subject: Re: How to format RAID1 correctly References: <5422146A.90206@evermeet.cx> <54222763.40107@sandeen.net> <5422285B.6010306@evermeet.cx> X-ASG-Orig-Subj: Re: How to format RAID1 correctly In-Reply-To: <5422285B.6010306@evermeet.cx> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1411525285 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9809 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/23/14 9:11 PM, Helmut Tessarek wrote: > On 23.09.14 22:07 , Eric Sandeen wrote: >> but! your raid doesn't have a 64k stripe, so that doesn't apply. > > Yep, that's true, but see below. > >> no geometry because md0 raid1 doesn't export any stripe geometry. > > [root@atvie01s ~]# cat /proc/mdstat > Personalities : [raid1] > md0 : active raid1 sdb1[0] sdd1[1] > 3906784064 blocks super 1.2 [2/2] [UU] > bitmap: 0/30 pages [0KB], 65536KB chunk > > So for some reason it shows a 64k chunk size even for RAID1. > > That was what got me confused. Hm, 65536KB sounds like 64MB... Anyway, mkfs.xfs picks up the queue's minimum IO size for sunit, and optimal io size for swidth. So: blkid # blockdev --getiomin --getioopt /dev/md0 (which here returns: 512 0 here) will show you what your raid's queue is actually reporting, and what mkfs.xfs will pick up. -Eric From tessarek@evermeet.cx Tue Sep 23 21:30:24 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C3C707F3F for ; Tue, 23 Sep 2014 21:30:24 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id A19E88F804B for ; Tue, 23 Sep 2014 19:30:24 -0700 (PDT) X-ASG-Debug-ID: 1411525822-04cb6c50e4107320001-NocioJ Received: from atvie01s.evermeet.cx (evermeet.cx [77.244.245.66]) by cuda.sgi.com with ESMTP id uvNyAjx0YGz07iph (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 23 Sep 2014 19:30:23 -0700 (PDT) X-Barracuda-Envelope-From: tessarek@evermeet.cx X-Barracuda-Apparent-Source-IP: 77.244.245.66 Received: from [10.0.0.40] (135-23-85-229.cpe.pppoe.ca [135.23.85.229]) (authenticated bits=0) by atvie01s.evermeet.cx (8.14.9/8.14.9) with ESMTP id s8O2UKcW009210 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Wed, 24 Sep 2014 04:30:21 +0200 Message-ID: <54222CBC.7010203@evermeet.cx> Date: Tue, 23 Sep 2014 22:30:20 -0400 From: Helmut Tessarek User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:31.0) Gecko/20100101 Thunderbird/31.1.1 MIME-Version: 1.0 To: Eric Sandeen , xfs@oss.sgi.com Subject: Re: How to format RAID1 correctly References: <5422146A.90206@evermeet.cx> <54222763.40107@sandeen.net> <5422285B.6010306@evermeet.cx> <54222AA4.5010501@sandeen.net> X-ASG-Orig-Subj: Re: How to format RAID1 correctly In-Reply-To: <54222AA4.5010501@sandeen.net> OpenPGP: id=C11F128D Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: evermeet.cx[77.244.245.66] X-Barracuda-Start-Time: 1411525822 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9809 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 23.09.14 22:21 , Eric Sandeen wrote: > blkid # blockdev --getiomin --getioopt /dev/md0 > > (which here returns: > 512 > 0 > here) > > will show you what your raid's queue is actually reporting, > and what mkfs.xfs will pick up. [root@atvie01s ~]# blockdev --getiomin --getioopt /dev/md0 4096 0 -- regards Helmut K. C. Tessarek lookup http://sks.pkqs.net for KeyID 0xC11F128D /* Thou shalt not follow the NULL pointer for chaos and madness await thee at its end. */ From stan@hardwarefreak.com Tue Sep 23 22:05:18 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id F149E7F3F for ; Tue, 23 Sep 2014 22:05:18 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id D058D8F8054 for ; Tue, 23 Sep 2014 20:05:18 -0700 (PDT) X-ASG-Debug-ID: 1411527914-04bdf003a21190f0001-NocioJ Received: from greer.hardwarefreak.com (mo-65-41-216-221.sta.embarqhsd.net [65.41.216.221]) by cuda.sgi.com with ESMTP id sZ3ZSKP8yf7oIjlG for ; Tue, 23 Sep 2014 20:05:14 -0700 (PDT) X-Barracuda-Envelope-From: stan@hardwarefreak.com X-Barracuda-Apparent-Source-IP: 65.41.216.221 X-Barracuda-User-Whitelist: xfs@oss.sgi.com Received: from [192.168.100.53] (mo-65-41-216-221.sta.embarqhsd.net [65.41.216.221]) by greer.hardwarefreak.com (Postfix) with ESMTPA id DF3FA6C052; Tue, 23 Sep 2014 22:05:13 -0500 (CDT) Message-ID: <542234F6.4080000@hardwarefreak.com> Date: Tue, 23 Sep 2014 22:05:26 -0500 From: stan hoeppner User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Icedove/24.7.0 MIME-Version: 1.0 To: Helmut Tessarek , Eric Sandeen , xfs@oss.sgi.com Subject: Re: How to format RAID1 correctly References: <5422146A.90206@evermeet.cx> <54222763.40107@sandeen.net> <5422285B.6010306@evermeet.cx> X-ASG-Orig-Subj: Re: How to format RAID1 correctly In-Reply-To: <5422285B.6010306@evermeet.cx> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mo-65-41-216-221.sta.embarqhsd.net[65.41.216.221] X-Barracuda-Start-Time: 1411527914 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On 09/23/2014 09:11 PM, Helmut Tessarek wrote: > On 23.09.14 22:07 , Eric Sandeen wrote: >> but! your raid doesn't have a 64k stripe, so that doesn't apply. > > Yep, that's true, but see below. > >> no geometry because md0 raid1 doesn't export any stripe geometry. > > [root@atvie01s ~]# cat /proc/mdstat > Personalities : [raid1] > md0 : active raid1 sdb1[0] sdd1[1] > 3906784064 blocks super 1.2 [2/2] [UU] > bitmap: 0/30 pages [0KB], 65536KB chunk > > So for some reason it shows a 64k chunk size even for RAID1. > > That was what got me confused. It confuses many people who are new to md RAID1. The above is the *bitmap* chunk size, not the array chunk size. There is no array chunk size for RAID1 as there is no striping. You must have striping to have chunks. With md RAID1 every 4KB page write is simply mirrored to each physical disk. Cheers, Stan From tessarek@evermeet.cx Tue Sep 23 22:16:11 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 3B0237F3F for ; Tue, 23 Sep 2014 22:16:11 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id BF180AC004 for ; Tue, 23 Sep 2014 20:16:07 -0700 (PDT) X-ASG-Debug-ID: 1411528564-04cb6c50e4108860001-NocioJ Received: from atvie01s.evermeet.cx (evermeet.cx [77.244.245.66]) by cuda.sgi.com with ESMTP id h4MDOaj9xWUuApug (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 23 Sep 2014 20:16:05 -0700 (PDT) X-Barracuda-Envelope-From: tessarek@evermeet.cx X-Barracuda-Apparent-Source-IP: 77.244.245.66 Received: from [10.0.0.40] (135-23-85-229.cpe.pppoe.ca [135.23.85.229]) (authenticated bits=0) by atvie01s.evermeet.cx (8.14.9/8.14.9) with ESMTP id s8O3FuRS010678 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Wed, 24 Sep 2014 05:15:58 +0200 Message-ID: <5422376D.3000204@evermeet.cx> Date: Tue, 23 Sep 2014 23:15:57 -0400 From: Helmut Tessarek User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:31.0) Gecko/20100101 Thunderbird/31.1.1 MIME-Version: 1.0 To: stan hoeppner , Eric Sandeen , xfs@oss.sgi.com Subject: Re: How to format RAID1 correctly References: <5422146A.90206@evermeet.cx> <54222763.40107@sandeen.net> <5422285B.6010306@evermeet.cx> <542234F6.4080000@hardwarefreak.com> X-ASG-Orig-Subj: Re: How to format RAID1 correctly In-Reply-To: <542234F6.4080000@hardwarefreak.com> OpenPGP: id=C11F128D Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: evermeet.cx[77.244.245.66] X-Barracuda-Start-Time: 1411528565 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9810 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 23.09.14 23:05 , stan hoeppner wrote: > It confuses many people who are new to md RAID1. The above is the > *bitmap* chunk size, not the array chunk size. There is no array chunk > size for RAID1 as there is no striping. You must have striping to have > chunks. With md RAID1 every 4KB page write is simply mirrored to each > physical disk. Thanks for the info. I'm used to big ass storage subsystems, but new to SW RAID. I seems I have some catching up to do. -- regards Helmut K. C. Tessarek lookup http://sks.pkqs.net for KeyID 0xC11F128D /* Thou shalt not follow the NULL pointer for chaos and madness await thee at its end. */ From stan@hardwarefreak.com Tue Sep 23 23:09:01 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id DD8067F3F for ; Tue, 23 Sep 2014 23:09:01 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id CB94E304032 for ; Tue, 23 Sep 2014 21:08:58 -0700 (PDT) X-ASG-Debug-ID: 1411531737-04cb6c50e7109ee0001-NocioJ Received: from greer.hardwarefreak.com (mo-65-41-216-221.sta.embarqhsd.net [65.41.216.221]) by cuda.sgi.com with ESMTP id h44o89fdek3uFVET for ; Tue, 23 Sep 2014 21:08:57 -0700 (PDT) X-Barracuda-Envelope-From: stan@hardwarefreak.com X-Barracuda-Apparent-Source-IP: 65.41.216.221 X-Barracuda-User-Whitelist: xfs@oss.sgi.com Received: from [192.168.100.53] (mo-65-41-216-221.sta.embarqhsd.net [65.41.216.221]) by greer.hardwarefreak.com (Postfix) with ESMTPA id 23D756C0E9; Tue, 23 Sep 2014 23:08:57 -0500 (CDT) Message-ID: <542243E6.1040302@hardwarefreak.com> Date: Tue, 23 Sep 2014 23:09:10 -0500 From: Stan Hoeppner User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Icedove/24.7.0 MIME-Version: 1.0 To: Helmut Tessarek , Eric Sandeen , xfs@oss.sgi.com Subject: Re: How to format RAID1 correctly References: <5422146A.90206@evermeet.cx> <54222763.40107@sandeen.net> <5422285B.6010306@evermeet.cx> <542234F6.4080000@hardwarefreak.com> <5422376D.3000204@evermeet.cx> X-ASG-Orig-Subj: Re: How to format RAID1 correctly In-Reply-To: <5422376D.3000204@evermeet.cx> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mo-65-41-216-221.sta.embarqhsd.net[65.41.216.221] X-Barracuda-Start-Time: 1411531737 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On 09/23/2014 10:15 PM, Helmut Tessarek wrote: > On 23.09.14 23:05 , stan hoeppner wrote: >> It confuses many people who are new to md RAID1. The above is the >> *bitmap* chunk size, not the array chunk size. There is no array chunk >> size for RAID1 as there is no striping. You must have striping to have >> chunks. With md RAID1 every 4KB page write is simply mirrored to each >> physical disk. > > Thanks for the info. I'm used to big ass storage subsystems, but new to SW > RAID. I seems I have some catching up to do. If you create any striped arrays, especially parity arrays, with md make sure to manually specify chunk size and match it to your workload. The current default is 512KB. This is too large for a great many workloads, specifically those that are metadata heavy or manipulate many small files. 512KB wastes space and with parity arrays causes RMW, hammering throughput and increasing latency. Cheers, Stan From arekm@maven.pl Wed Sep 24 02:03:56 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B521D7F3F for ; Wed, 24 Sep 2014 02:03:56 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 600C1AC004 for ; Wed, 24 Sep 2014 00:03:53 -0700 (PDT) X-ASG-Debug-ID: 1411542229-04bdf003a11213c0001-NocioJ Received: from mail-lb0-f170.google.com (mail-lb0-f170.google.com [209.85.217.170]) by cuda.sgi.com with ESMTP id SFODCmnDmcretLbj (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Wed, 24 Sep 2014 00:03:50 -0700 (PDT) X-Barracuda-Envelope-From: arekm@maven.pl X-Barracuda-Apparent-Source-IP: 209.85.217.170 Received: by mail-lb0-f170.google.com with SMTP id z11so4700026lbi.1 for ; Wed, 24 Sep 2014 00:03:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=maven.pl; s=maven; h=from:to:subject:date:user-agent:mime-version:content-type :content-transfer-encoding:message-id; bh=37LYVnuTyW+gBQudynO9zn6h7RgxrBMcNvKJgcX5Jzk=; b=RUfd2Tu2z0Z4PrSQ8ngLs4ADpIoNMVCOurTAZEZC2BWoTPkav2Gj8mmaFL59+uG27U xVmfBWesCDFXZpCOmCT3dMgCWGlnU3nDfa+u8aVklTbagdvxWSTFuQpOEmcZhnPlCoLN VAsii0e+2+poFhM+4BfEvGUC37F+/25wXSYEI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:user-agent:mime-version :content-type:content-transfer-encoding:message-id; bh=37LYVnuTyW+gBQudynO9zn6h7RgxrBMcNvKJgcX5Jzk=; b=EhVPTb9zeSgQsloItlKcj5SPTwc6A3MB7L/Kf4D6EomDBPdCfaWBLVLHk05MnPcRMV /u7ABdfggupKV5BmDSQsYb1BkvnfHlvJGotKgfK43voCCc/tj62dRWwG3fq2I5Huzctv Vk66BCqsSHkfgZHg9H/5AmHH5cDuSl6uE+RzI1BJriBfLzVr/TwCzeDS40Z+4uYNzSbg 6iDCyzy4/Yes1Mfe6bK+uWqq8tpWgBCQDraBg+z81eaw7l5+EmAlQNKDIKBuekIZHAW/ S/+C7SromxjU8aV9SBuXhdoGqS2d5BsP3Twx2PE68M/TuRO4XUOfrhawFoaBBCHyNrMd 5Ung== X-Gm-Message-State: ALoCoQmQPDbR/BYnMyNLS0jP6FNyKDOqZE59xlbBj/2aJs3PhxNk6NgdbPwiRDcKXCu+kO/EyHeY X-Received: by 10.152.234.76 with SMTP id uc12mr4567756lac.50.1411542228281; Wed, 24 Sep 2014 00:03:48 -0700 (PDT) Received: from t400.localnet ([91.234.176.246]) by mx.google.com with ESMTPSA id ug7sm5450280lac.48.2014.09.24.00.03.47 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 24 Sep 2014 00:03:47 -0700 (PDT) From: Arkadiusz =?utf-8?q?Mi=C5=9Bkiewicz?= To: xfs@oss.sgi.com Subject: "No space left on device" from hell Date: Wed, 24 Sep 2014 09:03:46 +0200 X-ASG-Orig-Subj: "No space left on device" from hell User-Agent: KMail/1.13.7 (Linux/3.17.0-rc6; KDE/4.14.0; x86_64; ; ) MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <201409240903.46899.arekm@maven.pl> X-Barracuda-Connect: mail-lb0-f170.google.com[209.85.217.170] X-Barracuda-Start-Time: 1411542229 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9816 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature Hello. 3.10.40 kernel and creating files causes "No space left on device". After=20 deleting some files I can create new files again until the problem happens= =20 again. Any ideas what is going on and, what is more important, how to fix the=20 problem? # df -h /dev/mapper/vgsys-home 600G 368G 232G 62% /home # df -i /dev/mapper/vgsys-home 629145600 7982895 621162705 2% /home # xfs_info /home meta-data=3D/dev/mapper/vgsys-home isize=3D256 agcount=3D8, agsize=3D196= 60800 blks =3D sectsz=3D512 attr=3D2, projid32bit=3D1 =3D crc=3D0 finobt=3D0 data =3D bsize=3D4096 blocks=3D157286400, imaxp= ct=3D25 =3D sunit=3D0 swidth=3D0 blks naming =3Dversion 2 bsize=3D4096 ascii-ci=3D0 ftype=3D0 log =3Dinternal bsize=3D4096 blocks=3D38400, version= =3D2 =3D sectsz=3D512 sunit=3D0 blks, lazy-coun= t=3D1 realtime =3Dnone extsz=3D4096 blocks=3D0, rtextents=3D imaxpct=3D25% but current inodes take only about 2GB, much less that 25% of= =20 600G, so that shouldn't be problem /dev/mapper/vgsys-home /home xfs=20 rw,nosuid,nodev,relatime,attr2,inode64,usrquota,prjquota 0 0 so inode64 is not a problem # xfs_quota -c "quota -p 0" /home Disk quotas for Project #0 (0) =46ilesystem Blocks Quota Limit Warn/Time Moun= ted=20 on /dev/mapper/vgsys-home 27848804 0 0 00 [--------] /home # xfs_quota -c "quota -u 0" /home Disk quotas for User root (0) =46ilesystem Blocks Quota Limit Warn/Time Moun= ted=20 on /dev/mapper/vgsys-home 103484 0 0 00 [--------] /home # xfs_quota -c "quota -i 0" /home Disk quotas for User root (0) =46ilesystem Files Quota Limit Warn/Time Moun= ted=20 on /dev/mapper/vgsys-home 8336 0 0 00 [--------] /home so quota is not a problem, too. # xfs_db -r "-c freesp -s" /dev/mapper/vgsys-home from to extents blocks pct 1 1 3426 3426 0.01 2 3 3319 8026 0.01 4 7 3694 19027 0.03 8 15 23225 330378 0.54 16 31 396 8180 0.01 32 63 75 3256 0.01 64 127 44 3443 0.01 128 255 26 4892 0.01 256 511 32 10737 0.02 512 1023 5 3867 0.01 1024 2047 8 13576 0.02 2048 4095 5 13893 0.02 4096 8191 3 16896 0.03 8192 16383 1 15532 0.03 16384 32767 1 17731 0.03 1048576 2097151 1 1414952 2.33 16777216 19660800 3 58913965 96.90 total free extents 34264 total free blocks 60801777 average free extent size 1774.51 unfortunately no idea how to interpret this. Man page isn't helpful. http://sprunge.us/IVjE (trace-cmd of touch /home/x ... but looks to be partial only) =2D-=20 Arkadiusz Mi=C5=9Bkiewicz, arekm / maven.pl From namjae.jeon@samsung.com Wed Sep 24 02:53:54 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.1 required=5.0 tests=HDRS_LCASE,T_MANY_HDRS_LCASE autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 60D807F3F for ; Wed, 24 Sep 2014 02:53:54 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id F1246AC004 for ; Wed, 24 Sep 2014 00:53:53 -0700 (PDT) X-ASG-Debug-ID: 1411545230-04bdf0039f122940001-NocioJ Received: from mailout3.samsung.com (mailout3.samsung.com [203.254.224.33]) by cuda.sgi.com with ESMTP id 4Ik1NLSzO8W8Ar6T (version=TLSv1 cipher=RC4-MD5 bits=128 verify=NO) for ; Wed, 24 Sep 2014 00:53:51 -0700 (PDT) X-Barracuda-Envelope-From: namjae.jeon@samsung.com X-Barracuda-Apparent-Source-IP: 203.254.224.33 Received: from epcpsbgr2.samsung.com (u142.gpu120.samsung.co.kr [203.254.230.142]) by mailout3.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NCE00483B9QDNA0@mailout3.samsung.com> for xfs@oss.sgi.com; Wed, 24 Sep 2014 16:53:50 +0900 (KST) Received: from epcpsbgm1.samsung.com ( [172.20.52.115]) by epcpsbgr2.samsung.com (EPCPMTA) with SMTP id D5.C6.11124.D8872245; Wed, 24 Sep 2014 16:53:50 +0900 (KST) X-AuditID: cbfee68e-f79b46d000002b74-e1-5422788d0294 Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 33.7D.20081.D8872245; Wed, 24 Sep 2014 16:53:49 +0900 (KST) Received: from DONAMJAEJEO06 ([10.88.104.63]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0NCE008H3B9PXUF0@mmp2.samsung.com>; Wed, 24 Sep 2014 16:53:49 +0900 (KST) From: Namjae Jeon To: 'Dave Chinner' , 'Theodore Ts'o' , 'Dmitry Monakhov' , 'Christoph Hellwig' , 'linux-ext4' , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, 'Luk?? Czerner' , 'Brian Foster' , 'Ashish Sangwan' , xfs@oss.sgi.com Subject: Unifying XFS_IOC_SWAPEXT and EXT4_IOC_MOV_EXT (was Re: [PATCH 2/3] xfs: Add support IOC_MOV_DATA ioctl) Date: Wed, 24 Sep 2014 16:53:49 +0900 X-ASG-Orig-Subj: Unifying XFS_IOC_SWAPEXT and EXT4_IOC_MOV_EXT (was Re: [PATCH 2/3] xfs: Add support IOC_MOV_DATA ioctl) Message-id: <000001cfd7cc$ad447a00$07cd6e00$@samsung.com> MIME-version: 1.0 Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7bit X-Mailer: Microsoft Outlook 14.0 Thread-index: Ac/Xy52Ab6BrJjpeQYusNfdax1wxOA== Content-language: ko X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrIIsWRmVeSWpSXmKPExsWyRsSkWLevQinE4OF1VoulEy8xW7z7XGWx 5dg9RosTMz0tTk9YxGSx7MFmFouZ8+6wWezZe5LF4vKuOWwWrT0/2S0W9d1idOD2OLVIwmPz Ci2PpjNHmT0mHf7M5LH6wlZGj/f7rrJ59G1ZxejxeZNcAEcUl01Kak5mWWqRvl0CV8bqHwuY C2bxVNxentrA+ICzi5GTQ0LAROLKo4lsELaYxIV764FsLg4hgaWMEvPWfGODKZo3dx8TiC0k MJ1RYmsfI0TRX0aJ5Vu3M3cxcnCwCWhL/NkiChIXEZjOLLHgyDFmkAZhgSKJc/9WMILYLAKq Es8PrwMbyitgKbGqcy0jhC0o8WPyPRYQm1lAS2L9zuNMELa8xOY1b5khjlCQ2HH2NVi9iICe RP+v7VD1IhL7XrwDO0hC4CO7xNm9n6CWCUh8m3yIBeQ4CQFZiU0HoOZIShxccYNlAqPoLCSr ZyFZPQvJ6llIVixgZFnFKJpakFxQnJReZKRXnJhbXJqXrpecn7uJERizp/8969vBePOA9SFG AQ5GJR7eCeJKIUKsiWXFlbmHGE2BLprILCWanA9MDHkl8YbGZkYWpiamxkbmlmZK4rwJUj+D hQTSE0tSs1NTC1KL4otKc1KLDzEycXBKNTDW+LnkBf/Yrn9P+YeDbqBNVvK5h64/q+5Xtwc4 r52zfOljyWshLzR+CEieE7OqU227qnvEd9n7F3avuVlVmx9PFOs+O/PmZfX7ywrelRvO777L +1ls1t8paTOWdQZKpv3415J5/rrkhpNPmCJ/Zwv0aC7UnD/18mn5wqSIr1n/Lzz35M1VZ4hS YinOSDTUYi4qTgQA2y5nVtQCAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFupmleLIzCtJLcpLzFFi42I5/e+xoG5vhVKIwclDVhZLJ15itnj3ucpi y7F7jBYnZnpanJ6wiMli2YPNLBYz591hs9iz9ySLxeVdc9gsWnt+slss6rvF6MDtcWqRhMfm FVoeTWeOMntMOvyZyWP1ha2MHu/3XWXz6NuyitHj8ya5AI6oBkabjNTElNQihdS85PyUzLx0 WyXv4HjneFMzA0NdQ0sLcyWFvMTcVFslF58AXbfMHKAzlRTKEnNKgUIBicXFSvp2mCaEhrjp WsA0Ruj6hgTB9RgZoIGENYwZq38sYC6YxVNxe3lqA+MDzi5GTg4JAROJeXP3MUHYYhIX7q1n A7GFBKYzSmztY+xi5AKy/zJKLN+6nbmLkYODTUBb4s8WUZC4iMB0ZokFR44xgzQICxRJnPu3 ghHEZhFQlXh+eB3YIF4BS4lVnWsZIWxBiR+T77GA2MwCWhLrdx5ngrDlJTavecsMcYSCxI6z r8HqRQT0JPp/bYeqF5HY9+Id4wRG/llIRs1CMmoWklGzkLQsYGRZxSiaWpBcUJyUnmuoV5yY W1yal66XnJ+7iRGcEJ5J7WBc2WBxiFGAg1GJh3eCuFKIEGtiWXFl7iFGCQ5mJRHeE6VAId6U xMqq1KL8+KLSnNTiQ4ymQJ9OZJYSTc4HJqu8knhDYxMzI0sjc0MLI2NzJXHeA63WgUIC6Ykl qdmpqQWpRTB9TBycUg2M8do+Mzs3ZFznzr8VJ14wwbjkUp+j3TY/zVwP45QX848rsegvmJeY eCUu9seOuF1neC+6ywca21Tum1RrGVczU4Wnt8zcfO+fHedFtp1W6dZeNMGqyGIb/7VH3bqT 1n+b9fLzvdbaT2byW62eC1znWtneMWUrf7xrtUhzUcRdwVdMN56//PhbiaU4I9FQi7moOBEA 2zUEWh4DAAA= DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected X-Barracuda-Connect: mailout3.samsung.com[203.254.224.33] X-Barracuda-Start-Time: 1411545231 X-Barracuda-Encrypted: RC4-MD5 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.01 X-Barracuda-Spam-Status: No, SCORE=0.01 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=THREAD_INDEX X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9817 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== > > FWIW, what we ideally need for these sorts of defrag programs is > per-file freezing. i.e. we freeze the file to be defragged, then do > the copy in userspace, swap/move the copied range and then unfreeze > it once complete. That guarantees that the file is not modified in > any way while userspace is doing the defrag... I am trying to unify xfs_swap extent and ext4 move extent so that both of these could be called via new ioctl mov_data. Both ioctl have different interface because both xfs and ext4 have different way of avoiding change in source file while defrag is running. XFS uses xfs_bstat_t while ext4 performs copying of data within kernel space after taking mutex lock. To make them use same approach, we should use something like file sealing as suggessted by you. First of all, I am trying to find proper way of sealing file as suggested by you. I am considering to use S_IMMUTABLE flag set to avoid file modification during defrag. I am thinking of first syncing dirty pages, then truncating page cache pages of inode and lastly setting immutable flag of inode. This will block further attempts of modifying the file by opening new file pointer but already open file pointer can still change it. Although immutable file mean file can not be modified, there is no immutable check condition in write path and mmap path. I am wondering it is just missing to add immutable check condition or there is other reason I am not aware. Thanks! > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com From fran.tsao@gmail.com Wed Sep 24 03:42:21 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE, T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 929807F3F for ; Wed, 24 Sep 2014 03:42:21 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 80BDB8F8035 for ; Wed, 24 Sep 2014 01:42:18 -0700 (PDT) X-ASG-Debug-ID: 1411548136-04cb6c50e61127a0001-NocioJ Received: from mail-wi0-f177.google.com (mail-wi0-f177.google.com [209.85.212.177]) by cuda.sgi.com with ESMTP id Y7atORvWRxpTbzoq (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Wed, 24 Sep 2014 01:42:16 -0700 (PDT) X-Barracuda-Envelope-From: fran.tsao@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.212.177 X-Barracuda-IPDD: Level1 [gmail.com/209.85.212.177] Received: by mail-wi0-f177.google.com with SMTP id q5so6733003wiv.4 for ; Wed, 24 Sep 2014 01:42:15 -0700 (PDT) X-Barracuda-IPDD: Level1 [gmail.com/209.85.212.177] X-Barracuda-IPDD: Level1 [gmail.com/209.85.212.177] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; bh=b8b0oJ/WsOKGnY7MoRCIItqu92R1OEDj2FR7RwLTHG4=; b=fmuVoVTLlnxGzMeIIioyj81JHPiO84APrgHxn5QQVDG8YeRVt/hhYRLqDTKvObYs+w MXG25RwohQvxbSUhLp23CRp5KOAoPzZVx66BH8w4Cr33JuSW6DZrd5VTuiqvssbiXrQe 1Vu5cdZvAXiY6g/jzDPFDFLLlPJIn7U6RKN+Uaf7VPnCFY0gJgWhtPP0Dj3FqcvWLasP nsZAjctHo04fr7rEd92OkHHQGzdoo8BzZIpIjKppshm09Daoa+WKdW4LMw4HV8Hbd7SN 8B9qJ62TMpw+6QTTB9PGz+RJJOurvSpG600+2xmMWMWQjxe0B6khDFy6gyHnnzE9Lg23 0jvA== MIME-Version: 1.0 X-Received: by 10.180.20.20 with SMTP id j20mr4660339wie.18.1411548135731; Wed, 24 Sep 2014 01:42:15 -0700 (PDT) Sender: fran.tsao@gmail.com Received: by 10.216.17.138 with HTTP; Wed, 24 Sep 2014 01:42:15 -0700 (PDT) In-Reply-To: <201409240903.46899.arekm@maven.pl> References: <201409240903.46899.arekm@maven.pl> Date: Wed, 24 Sep 2014 10:42:15 +0200 X-Google-Sender-Auth: zUh6SfoWEutOgMrX1obgNjqSigU Message-ID: Subject: Re: "No space left on device" from hell From: =?UTF-8?Q?Fran_Tsao_Sant=C3=ADn?= X-ASG-Orig-Subj: Re: "No space left on device" from hell To: =?UTF-8?Q?Arkadiusz_Mi=C5=9Bkiewicz?= Cc: xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=bcaec53f398136b64d0503cba94d X-Barracuda-Connect: mail-wi0-f177.google.com[209.85.212.177] X-Barracuda-Start-Time: 1411548136 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9817 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message --bcaec53f398136b64d0503cba94d Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable 2014-09-24 9:03 GMT+02:00 Arkadiusz Mi=C5=9Bkiewicz : > > Hello. > > 3.10.40 kernel and creating files causes "No space left on device". After > deleting some files I can create new files again until the problem happen= s > again. Are you sure the problem is the filesystem device? Maybe you are running a process that fills up another device i.e. shm. --bcaec53f398136b64d0503cba94d Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable

= 2014-09-24 9:03 GMT+02:00 Arkadiusz Mi=C5=9Bkiewicz <<= a href=3D"mailto:arekm@maven.pl" target=3D"_blank">arekm@maven.pl>:

Hello.

3.10.40 kernel and creating files causes "No space left on device"= ;. After
deleting some files I can create new files again until the problem happens<= br> again.

Are you sure the problem is the filesystem devi= ce? Maybe you are running a process that fills up another device i.e. shm.

=C2=A0
=
--bcaec53f398136b64d0503cba94d-- From jack@suse.cz Wed Sep 24 03:45:26 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id A1C1C7F3F for ; Wed, 24 Sep 2014 03:45:26 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8DD6E8F8033 for ; Wed, 24 Sep 2014 01:45:26 -0700 (PDT) X-ASG-Debug-ID: 1411548322-04cbb0730111f7c0001-NocioJ Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id JyeX9wA9xSuVWHUz (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 24 Sep 2014 01:45:23 -0700 (PDT) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 92B91ABE3; Wed, 24 Sep 2014 08:45:21 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 8769A81F97; Wed, 24 Sep 2014 10:45:19 +0200 (CEST) Date: Wed, 24 Sep 2014 10:45:19 +0200 From: Jan Kara To: linux-fsdevel@vger.kernel.org Cc: linux-mm@kvack.org, Dave Chinner , linux-ext4@vger.kernel.org, Ted Tso , Jan Kara , xfs@oss.sgi.com Subject: Re: [PATCH 2/2] ext4: Fix mmap data corruption when blocksize < pagesize Message-ID: <20140924084519.GA21987@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH 2/2] ext4: Fix mmap data corruption when blocksize < pagesize References: <1411484603-17756-1-git-send-email-jack@suse.cz> <1411484603-17756-3-git-send-email-jack@suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411484603-17756-3-git-send-email-jack@suse.cz> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: cantor2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1411548322 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9818 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header On Tue 23-09-14 17:03:23, Jan Kara wrote: > Use block_create_hole() when hole is being created in a file so that > ->page_mkwrite() will get called for the partial tail page if it is > mmaped (see the first patch in the series for details). Just out of curiosity I did a change similar to this one for ext4 to XFS and indeed it fixed generic/030 test failures for XFS with blocksize 1k. Honza PS: I forgot to CC xfs list in the original posting. You can find the VFS patch e.g. at http://www.spinics.net/lists/linux-mm/msg78976.html > Signed-off-by: Jan Kara > --- > fs/ext4/inode.c | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c > index 3aa26e9117c4..fdcb007c2c9e 100644 > --- a/fs/ext4/inode.c > +++ b/fs/ext4/inode.c > @@ -4536,8 +4536,12 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) > ext4_orphan_del(NULL, inode); > goto err_out; > } > - } else > + } else { > + loff_t old_size = inode->i_size; > + > i_size_write(inode, attr->ia_size); > + block_create_hole(inode, old_size, inode->i_size); > + } > > /* > * Blocks are going to be removed from the inode. Wait > -- > 1.8.1.4 > -- Jan Kara SUSE Labs, CR From arekm@maven.pl Wed Sep 24 03:54:15 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C0BB27F3F for ; Wed, 24 Sep 2014 03:54:15 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 41D98AC006 for ; Wed, 24 Sep 2014 01:54:11 -0700 (PDT) X-ASG-Debug-ID: 1411548849-04cb6c50e6112bf0001-NocioJ Received: from mail-la0-f41.google.com (mail-la0-f41.google.com [209.85.215.41]) by cuda.sgi.com with ESMTP id nNz5jH65uILZCDsx (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Wed, 24 Sep 2014 01:54:10 -0700 (PDT) X-Barracuda-Envelope-From: arekm@maven.pl X-Barracuda-Apparent-Source-IP: 209.85.215.41 Received: by mail-la0-f41.google.com with SMTP id s18so10277163lam.14 for ; Wed, 24 Sep 2014 01:54:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=maven.pl; s=maven; h=from:to:subject:date:user-agent:cc:references:in-reply-to :mime-version:content-type:content-transfer-encoding:message-id; bh=LxPvQ6LrmdUQwomvSDIvIWYKK8Rc+6OTcA0RxqI0Bqs=; b=mev7HS+fT1m9efnUqtdMc/2KNN8URVJv3HjkOYiU7Wl/zV4oqeH02kgx6bh9cAbr+T x4elMMVh0Lqu3ky7gFvBNpJUpV1IrOY/aN3Yxd9+1OaI6F0kjg3JoPUXPEfz/o5hADmf Mojj0b6YxSTo3MaUVB+UVbjStxvdQPE43w/jo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:user-agent:cc:references :in-reply-to:mime-version:content-type:content-transfer-encoding :message-id; bh=LxPvQ6LrmdUQwomvSDIvIWYKK8Rc+6OTcA0RxqI0Bqs=; b=KiWo07FbJdrg7MbwVQEEnWYJu/WvwqAcNZY2z4YG5fZ+1SOL3MwnAXz92So4NR+7sq U8nx2Y72R8TqzoXRMpyDM7yG5fLWwyCnmNkyzdvbnaVUCpkwMPVixA44d9IYuvSmmFS6 2rOQlsa2ga2xT3WwInmr7Eth+8/1VwQMpXzJWCRim7Sp3zZYD3ndmRzD4EVi/nRIO2BS FXu5vJ1ap2lduQcZW/KsXJZkbXAOhUqiLbD4waT25HApXtqwFgUV02x0bn19mo+0cJlo H21f7QFJk6mem0fh1Ux7q8r+9GvLM9BU3PGGI4FSMHuqNs7rl9V5G20929YbyGmyonSK irQA== X-Gm-Message-State: ALoCoQlG+stEoHo6y7i3l4OzmKlNZ4aaGpN99TFpSw+IP/onBIEzjUPsEAfShXqnlh+szA2rEtmv X-Received: by 10.112.150.106 with SMTP id uh10mr4683303lbb.11.1411548848480; Wed, 24 Sep 2014 01:54:08 -0700 (PDT) Received: from t400.localnet ([91.234.176.247]) by mx.google.com with ESMTPSA id pw9sm5594758lbb.2.2014.09.24.01.54.07 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 24 Sep 2014 01:54:08 -0700 (PDT) From: Arkadiusz =?utf-8?q?Mi=C5=9Bkiewicz?= To: Fran Tsao =?utf-8?q?Sant=C3=ADn?= Subject: Re: "No space left on device" from hell Date: Wed, 24 Sep 2014 10:54:05 +0200 X-ASG-Orig-Subj: Re: "No space left on device" from hell User-Agent: KMail/1.13.7 (Linux/3.17.0-rc6; KDE/4.14.0; x86_64; ; ) Cc: xfs@oss.sgi.com References: <201409240903.46899.arekm@maven.pl> In-Reply-To: MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <201409241054.06983.arekm@maven.pl> X-Barracuda-Connect: mail-la0-f41.google.com[209.85.215.41] X-Barracuda-Start-Time: 1411548849 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9818 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Wednesday 24 of September 2014, Fran Tsao Sant=C3=ADn wrote: > 2014-09-24 9:03 GMT+02:00 Arkadiusz Mi=C5=9Bkiewicz : > > Hello. > >=20 > > 3.10.40 kernel and creating files causes "No space left on device". Aft= er > > deleting some files I can create new files again until the problem > > happens again. >=20 > Are you sure the problem is the filesystem device? Maybe you are running a > process that fills up another device i.e. shm. Dave Chinner figured out the problem already (on irc). Basically this fs was grown from 300GB to 600GB but due to bug (fixed by=20 commit 9de67c3 ("xfs: allow inode allocations in post-growfs disk space"))= =20 that new space was never used for new inodes. So ended up with full AGs 0-3 (xfs_db -r -c "freesp -s -a XX" /dev/xyz sho= ws=20 that for each AG XX). =46s was never unmounted after grows but fortunately mount -o remount,inode= 32=20 =2E.. followed by mount -o remount,inode64 cured it without a need to reboo= t, so=20 now new inodes are distributed to all AGs. I still need to free some space in AGs 0-3 though (by moving data to new di= rs=20 allocated in new AGs; xfs_db -r -c "convert inode DIR_INODE_NR agno" /dev/x= yz=20 shows in which AG new dir got allocated). There are more bugs hiding (like if ENOSPC on some AG happens it should try= =20 next AG instead of failing). Dave knows all that magic. Big thanks to Dave! =2D-=20 Arkadiusz Mi=C5=9Bkiewicz, arekm / maven.pl From jack@suse.cz Wed Sep 24 03:57:37 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 814757F4E for ; Wed, 24 Sep 2014 03:57:37 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 60D62304039 for ; Wed, 24 Sep 2014 01:57:34 -0700 (PDT) X-ASG-Debug-ID: 1411549046-04cb6c50e5112e00001-NocioJ Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id IkcHB3CGRDXlohY4 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 24 Sep 2014 01:57:27 -0700 (PDT) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 1D8C0ACCD; Wed, 24 Sep 2014 08:57:26 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 241B381F97; Wed, 24 Sep 2014 10:57:24 +0200 (CEST) Date: Wed, 24 Sep 2014 10:57:24 +0200 From: Jan Kara To: linux-fsdevel@vger.kernel.org Cc: linux-mm@kvack.org, Dave Chinner , linux-ext4@vger.kernel.org, Ted Tso , Jan Kara , xfs@oss.sgi.com Subject: Re: [PATCH 2/2] ext4: Fix mmap data corruption when blocksize < pagesize Message-ID: <20140924085724.GA21864@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH 2/2] ext4: Fix mmap data corruption when blocksize < pagesize References: <1411484603-17756-1-git-send-email-jack@suse.cz> <1411484603-17756-3-git-send-email-jack@suse.cz> <20140924084519.GA21987@quack.suse.cz> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="MGYHOYXEY6WxJCY8" Content-Disposition: inline In-Reply-To: <20140924084519.GA21987@quack.suse.cz> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: cantor2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1411549046 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9818 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header --MGYHOYXEY6WxJCY8 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed 24-09-14 10:45:19, Jan Kara wrote: > On Tue 23-09-14 17:03:23, Jan Kara wrote: > > Use block_create_hole() when hole is being created in a file so that > > ->page_mkwrite() will get called for the partial tail page if it is > > mmaped (see the first patch in the series for details). > Just out of curiosity I did a change similar to this one for ext4 to XFS > and indeed it fixed generic/030 test failures for XFS with blocksize 1k. Just for reference attached the patch I was testing - I can resend with proper changelog etc. if people are fine with this approach. Honza > > Signed-off-by: Jan Kara > > --- > > fs/ext4/inode.c | 6 +++++- > > 1 file changed, 5 insertions(+), 1 deletion(-) > > > > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c > > index 3aa26e9117c4..fdcb007c2c9e 100644 > > --- a/fs/ext4/inode.c > > +++ b/fs/ext4/inode.c > > @@ -4536,8 +4536,12 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) > > ext4_orphan_del(NULL, inode); > > goto err_out; > > } > > - } else > > + } else { > > + loff_t old_size = inode->i_size; > > + > > i_size_write(inode, attr->ia_size); > > + block_create_hole(inode, old_size, inode->i_size); > > + } > > > > /* > > * Blocks are going to be removed from the inode. Wait > > -- > > 1.8.1.4 > > > -- > Jan Kara > SUSE Labs, CR > -- > To unsubscribe from this list: send the line "unsubscribe linux-ext4" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Jan Kara SUSE Labs, CR --MGYHOYXEY6WxJCY8 Content-Type: text/x-patch; charset=us-ascii Content-Disposition: attachment; filename="0001-xfs-Fix-mmap-data-corruption.patch" >From ceedc36b1c99c25ebb55c88f6ab059347b52f4ec Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Wed, 24 Sep 2014 10:18:25 +0200 Subject: [PATCH] xfs: Fix mmap data corruption Signed-off-by: Jan Kara --- fs/xfs/xfs_iops.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 72129493e9d3..19ce64bfb4f7 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -848,6 +848,8 @@ xfs_setattr_size( if (error) return error; truncate_setsize(inode, newsize); + if (oldsize < newsize) + block_create_hole(inode, oldsize, newsize); tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE); error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0); -- 1.8.1.4 --MGYHOYXEY6WxJCY8-- From eflorac@intellique.com Wed Sep 24 05:06:09 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id C012A7F3F for ; Wed, 24 Sep 2014 05:06:09 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id AD335304032 for ; Wed, 24 Sep 2014 03:06:06 -0700 (PDT) X-ASG-Debug-ID: 1411553164-04cb6c50e7114910001-NocioJ Received: from mail1.g1.pair.com (mail1.g1.pair.com [66.39.3.162]) by cuda.sgi.com with ESMTP id FBMua7kqZaszWOhn (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 24 Sep 2014 03:06:05 -0700 (PDT) X-Barracuda-Envelope-From: eflorac@intellique.com X-Barracuda-Apparent-Source-IP: 66.39.3.162 Received: from localhost (localhost [127.0.0.1]) by mail1.g1.pair.com (Postfix) with SMTP id 669CB2C14F; Wed, 24 Sep 2014 06:06:04 -0400 (EDT) Received: from harpe.intellique.com (labo.djinux.com [82.225.196.72]) by mail1.g1.pair.com (Postfix) with ESMTPSA id 5422C2BF2E; Wed, 24 Sep 2014 06:06:03 -0400 (EDT) Date: Wed, 24 Sep 2014 12:08:40 +0200 From: Emmanuel Florac To: Diane Trout Cc: xfs@oss.sgi.com Subject: Re: Corrupted file system Message-ID: <20140924120840.1be78240@harpe.intellique.com> X-ASG-Orig-Subj: Re: Corrupted file system In-Reply-To: <5839367.DyqsVHbRuQ@myrada> References: <5839367.DyqsVHbRuQ@myrada> Organization: Intellique X-Mailer: Claws Mail 3.10.0 (GTK+ 2.24.20; i486-slackware-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail1.g1.pair.com[66.39.3.162] X-Barracuda-Start-Time: 1411553165 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9819 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Le Tue, 23 Sep 2014 15:02:57 -0700 Diane Trout =C3=A9crivait: > I had a raid failure at work that ended up corrupting an xfs > filesystem the tail of the xfs_repair command looks like the below. I > was able to generate a metadata dump but is there a point to making > it available?=20 >=20 > It does crash repeatedly at the same place Did you try the very latest xfs_repair? --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From olaf@sgi.com Wed Sep 24 06:07:43 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id E2B227F3F for ; Wed, 24 Sep 2014 06:07:43 -0500 (CDT) Received: from xmail.sgi.com (pv-excas1-dc21.corp.sgi.com [137.38.106.7]) by relay2.corp.sgi.com (Postfix) with ESMTP id C0A26304039; Wed, 24 Sep 2014 04:07:40 -0700 (PDT) Received: from [144.253.208.77] (144.253.208.77) by xmail.sgi.com (137.38.106.6) with Microsoft SMTP Server (TLS) id 14.3.195.1; Wed, 24 Sep 2014 06:07:40 -0500 Message-ID: <5422A5F8.5040703@sgi.com> Date: Wed, 24 Sep 2014 13:07:36 +0200 From: Olaf Weber Organization: SGI User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.1 MIME-Version: 1.0 To: Andi Kleen CC: Ben Myers , , , Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <87lhpbhfgg.fsf@tassilo.jf.intel.com> <20140922184145.GH4482@sgi.com> <20140922192958.GJ4120@two.firstfloor.org> <54219C17.3090104@sgi.com> <20140923201540.GB15923@two.firstfloor.org> In-Reply-To: <20140923201540.GB15923@two.firstfloor.org> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [144.253.208.77] On 23-09-14 22:15, Andi Kleen wrote: >> A big part of the table does decompositions for Korean: eliminating >> the Hangul decompositions removes 156320 bytes, leaving 89936 bytes. > > Are there regular ranges or other redundancies in the Korean encoding > that could be used to compress paths? Yes, though at the expense of more complicated code and interfaces. in particular, lookups that want a normalized string would need to provide a 10-byte buffer to store it in. > Doing some basic research other people already answered this: > > Please use the ICU or google tables referenced below. Apparently > smaller is possible too, but 40-50k seems more reasonable. Riffing off the http://macchiato.com/unicode/normalization_footprint.htm link you provided, looking at the NFKD case. For Unicode 3.0.0 that link gives 3483 NFKD normalizations (exlcuding Hangul), and gives 26,918 bytes as the size of a simple lookup table (key/offset pairs, with the offset pointing into a string table). In Unicode 7.0.0 I count 5721 NFKD normalizations (again excluding Hangul). As NUL-terminated UTF-8 strings these take 23390 bytes. Using a key-offset table I need 3 bytes for the key (code points are 21 bits) and 2 bytes for an offset. Total is 5721 * (3 + 2) + 23390 = 51995 bytes. Stealing 4 bits from the key field and 1 from the offset to store the size of the normalized string I can remove the NUL bytes from the string table and reduce total size to 46274 bytes. The trie implementation used here would use 66283 bytes to store the same information, but it also provides unicode version and canonical combining class for all codepoints. There are 10268 leaves in this case, with the size of each leaf being 1 byte for version, one for ccc, plus the size of the decomposition, if any. So a quick estimate on the space used just for the NFKD data is some 45747 bytes. I'm pretty certain that a trie that only stores the NFKD would be smaller than 45747 bytes as it would need fewer internal nodes, but didn't do the experiment. But as you can see, for just the NFKD part and excluding Hangul, the size of the trie is within the ballpark of the numbers you gave. Case folding adds a partial trie that forwards to the "main" trie for parts that are identical. This adds 2672 extra leaves and 20171 extra bytes. The data for the normalization corrections adds another 3328 bytes. With a bit of rounding, total size comes to 89840 bytes. > I'm just gonna make the claim that whatever performance you > get from a larger table is dwarfed by the cache miss overhead. That's possible, though it seems plausible you'd only suffer from this doing actual Hangul decomposition: all the data related to this (trie nodes, trie leaves, and strings) sits in one contiguous block in memory. Olaf -- Olaf Weber SGI Phone: +31(0)30-6696796 Veldzigt 2b Fax: +31(0)30-6696799 Technical Lead 3454 PW de Meern Vnet: 955-6796 Storage Software The Netherlands Email: olaf@sgi.com From bfoster@redhat.com Wed Sep 24 07:28:00 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D58C97F3F for ; Wed, 24 Sep 2014 07:28:00 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id A75888F8037 for ; Wed, 24 Sep 2014 05:27:57 -0700 (PDT) X-ASG-Debug-ID: 1411561676-04bdf003a212b790001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id jZPObEl3kQy7BydJ (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 24 Sep 2014 05:27:56 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8OCRmjS003430 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 24 Sep 2014 08:27:48 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8OCRl7c019592; Wed, 24 Sep 2014 08:27:48 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id D95D1120064; Wed, 24 Sep 2014 08:27:46 -0400 (EDT) Date: Wed, 24 Sep 2014 08:27:46 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [RFC PATCH] xfs: borrow indirect blocks from freed extent when available Message-ID: <20140924122746.GA53094@bfoster.bfoster> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: borrow indirect blocks from freed extent when available References: <1411500538-6831-1-git-send-email-bfoster@redhat.com> <20140923215816.GC4322@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140923215816.GC4322@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411561676 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Sep 24, 2014 at 07:58:16AM +1000, Dave Chinner wrote: > On Tue, Sep 23, 2014 at 03:28:58PM -0400, Brian Foster wrote: > > xfs_bmap_del_extent() handles extent removal from the in-core and > > on-disk extent lists. When removing a delalloc range, it updates the > > indirect block reservation appropriately based on the removal. It > > currently enforces that the new indirect block reservation is less than > > or equal to the original. This is normally the case in all situations > > except for when the removed range creates a hole in a single delalloc > > extent, thus splitting a single delalloc extent in two. > > > > The indirect block reservation is divided evenly between the two new > > extents in this scenario. However, it is possible with small enough > > extents to split an indlen==1 extent into two such slightly smaller > > extents. This leaves one extent with 0 indirect blocks and leads to > > assert failures in other areas (e.g., xfs_bunmapi() if the extent > > happens to be removed). > > I had long suspected we had an issue in this code, but was never > able to nail down a reproducer that triggered it. Do you have a > reproducer, or did you find this by reading/tracing the code? > I have a setup on which fsx reproduces an instance of this within a few minutes consistently. It looks like the same sequence of events each occurrence so I can try to derive a more specific test case for it. I suspect the right sequence of delayed allocation followed by hole punching or zeroing should be able to trigger it. > > Refactor xfs_bunmapi() to make the updates that must be consistent > > against the inode (e.g., delalloc block counter, quota reservation) > > right before the extent is deleted. Move the sb block counter update > > after the extent is deleted and update xfs_bmap_del_extent() to steal > > some blocks from the freed extent if a larger overall indirect > > reservation is required by the extent removal. > > > > Signed-off-by: Brian Foster > > --- > > > > Hi all, > > > > I'm seeing the following assert more frequently with fsx and the recent > > xfs_free_file_space() changes (at least on 1k fsb fs'): > > > > XFS: Assertion failed: startblockval(del.br_startblock) > 0, file: fs/xfs/libxfs/xfs_bmap.c, line: 5281 > > > > This occurs for the reason described in the commit log description. This > > is a quick experiment I wanted to test to verify the problem goes away > > (so far, so good). Very lightly tested so far. > > I suspect it's also the cause of these occasional assert failures > that I see: > > XFS: Assertion failed: tp->t_blk_res_used <= tp->t_blk_res, file: fs/xfs/xfs_trans.c, line: 327 > > during delalloc conversion because there wasn't a space reservation > for the blocks allocated (i.e. indlen was zero) and so we overrun > the transaction block reservation. > Interesting, I've seen this as well though I'll have to go back and see where I was getting it from. I did run fsx overnight without any assert failures at all, which seems rare lately. ;) I wasn't running my usual parallel fsstress however. I've started that and I reproduce an instance of that assert failure within a few minutes, so if related it appears this might not be the only contributer. I'll look more into that one next. > > I'm not too fond of changing br_blockcount like this. It seems like a > > potential landmine. Alternative approaches could be to kill the assert > > if we think indlen==0 extents is not a huge problem in this scenario, > > A delalloc extent always needs a reservation.... > Ok. > > update the counters independently in xfs_bmap_del_extent() to get the > > needed blocks or pass a separate output parameter rather than messing > > with br_blockcount (e.g., '*ofreedblks'). The latter might mean we could > > just move the entire hunk that updates the inode/quota and whatnot > > rather than splitting it up. > > > > I wanted to put this on the list for comments. Thoughts? Other ideas? > > Thanks. > > > > Brian > > > > fs/xfs/libxfs/xfs_bmap.c | 64 ++++++++++++++++++++++++++++++------------------ > > 1 file changed, 40 insertions(+), 24 deletions(-) > > > > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > > index 86df952..1858e6b 100644 > > --- a/fs/xfs/libxfs/xfs_bmap.c > > +++ b/fs/xfs/libxfs/xfs_bmap.c > > @@ -4969,6 +4969,11 @@ xfs_bmap_del_extent( > > temp2 = xfs_bmap_worst_indlen(ip, temp2); > > new.br_startblock = nullstartblock((int)temp2); > > da_new = temp + temp2; > > + /* pull blocks from extent to make up the difference */ > > + while (da_new > da_old && del->br_blockcount) { > > + del->br_blockcount--; > > + da_new--; > > + } > > while (da_new > da_old) { > > if (temp) { > > temp--; > > So this is the crux of the fix, right? The block stealing from the > deleted extent? I have no objections to doing this given that we > already munge the indirect reservations inteh loop below, but > I think we should make this cleaner and more understandable. i.e. > refactor the indlen adjustment code into a helper, and integrate the > block stealing into the existing adjustment loop? > Yes, the problem is that we basically split the existing reservation amongst the new extents. The 'punch a hole in a small delalloc extent' scenario can mean we have to split 1 indlen block across two extents, thus creating the indlen==0 condition for one of the two. IOW, the existing reservation doesn't always cover the requirements of the new extent(s). If the fundamental fix is sane I'll look into the associated cleanups. Thanks for the feedback. > > @@ -5277,9 +5282,37 @@ xfs_bunmapi( > > goto nodelete; > > } > > } > > + > > + /* > > + * If it's the case where the directory code is running > > + * with no block reservation, and the deleted block is in > > + * the middle of its extent, and the resulting insert > > + * of an extent would cause transformation to btree format, > > + * then reject it. The calling code will then swap > > + * blocks around instead. > > + * We have to do this now, rather than waiting for the > > + * conversion to btree format, since the transaction > > + * will be dirty. > > + */ > > + if (!wasdel && xfs_trans_get_block_res(tp) == 0 && > > + XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_EXTENTS && > > + XFS_IFORK_NEXTENTS(ip, whichfork) >= /* Note the >= */ > > + XFS_IFORK_MAXEXT(ip, whichfork) && > > + del.br_startoff > got.br_startoff && > > + del.br_startoff + del.br_blockcount < > > + got.br_startoff + got.br_blockcount) { > > + error = -ENOSPC; > > + goto error0; > > + } > > + > > + /* > > + * Unreserve quota and update realtime free space, if > > + * appropriate. If delayed allocation, update the inode delalloc > > + * counter now and wait to update the sb counters as > > + * xfs_bmap_del_extent() might need to borrow some blocks. > > + */ > > if (wasdel) { > > ASSERT(startblockval(del.br_startblock) > 0); > > - /* Update realtime/data freespace, unreserve quota */ > > if (isrt) { > > xfs_filblks_t rtexts; > > > > Perhaps this should be separated into it's own patch that is applied > first? It doesn't seem to be directly related to the accounting fix... > Yeah, I actually have this as an independent patch and initial cleanup in my dev. branch and I just squashed everything to send off here. This was probably unnecessary to propose the fundamental fix. Sorry for the added noise. Brian > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From olaf@sgi.com Wed Sep 24 08:21:10 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id D89BD7F3F for ; Wed, 24 Sep 2014 08:21:10 -0500 (CDT) Received: from xmail.sgi.com (pv-excas1-dc21.corp.sgi.com [137.38.106.7]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6D65C304032; Wed, 24 Sep 2014 06:21:07 -0700 (PDT) Received: from [144.253.208.77] (144.253.208.77) by xmail.sgi.com (137.38.106.6) with Microsoft SMTP Server (TLS) id 14.3.195.1; Wed, 24 Sep 2014 08:21:06 -0500 Message-ID: <5422C540.1060007@sgi.com> Date: Wed, 24 Sep 2014 15:21:04 +0200 From: Olaf Weber Organization: SGI User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.1 MIME-Version: 1.0 To: Dave Chinner , Ben Myers CC: , , Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <20140922222611.GZ4322@dastard> In-Reply-To: <20140922222611.GZ4322@dastard> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [144.253.208.77] On 23-09-14 00:26, Dave Chinner wrote: > On Thu, Sep 18, 2014 at 02:56:50PM -0500, Ben Myers wrote: [...] >> TODO: Store the unicode version number of the filesystem on disk in the >> super block. > > So, if the filesystem has to store the specific unicode version it > was created with so that we know what version to put in trie > lookups, again I'll ask: why are we loading the trie as a generic > kernel module and not as metadata in the filesystem that is demand > paged and cached? This way the trie can be shared, and the code using it is not entangled with the XFS code. > i.e. put the entire trie on disk, look up the specific conversion > required for the name being compared, and then cache that conversion > in memory. This makes repeated lookups much faster because the trie > only contains conversions that are in use, the memory footprint is > way lower and the conversions are guaranteed to be consistent for > the life of the filesystem.... Above you mention demand paging parts of the trie, but here you seem to suggest creating an in-core conversion table on the fly from data read from disk. The former seems a lot easier to do than the latter. >> Here are Olaf's design notes: >> >> ----------------------------------------------------------------------------- >> Unicode/UTF-8 support for XFS >> >> So we had a customer request proper unicode support... >> >> >> * What does "supporting unicode" actually mean? >> >> From a text processing point of view, what a filesystem does with >> filenames is simple: it stores and retrieves them, and compares them >> for equality. It may reject certain byte sequences as invalid >> filenames (for example, no filename can contain an ASCII NUL). >> >> I've been taking it as a given that when a file is created with a >> certain byte sequence as its name, then a subsequent directory listing >> will contain that same byte sequence among the names listed. >> >> This leaves comparing names for equality, and in my view this is what >> "supporting unicode" revolves about. >> >> The present state of affairs is that different byte sequences are >> different filenames. This amounts to tolerating unicode without >> actually supporting it. > > That's somewhat circular - using your own definition of "supported" > to argue that your own definition is the right one.... > >> To support unicode we have to interpret filenames. What happens when >> (part of) a filename cannot be interpreted? We can reject the >> filename, interpret the parts we can, or punt and accept it as an >> uninterpreted blob. >> >> Rejecting ill-formed filenames was my first choice, but I came around >> on the issue: there are too many ways in which you can end up with >> having to deal with ill-formed filenames that would leave a user with >> no recourse but to move whatever they're doing to a different >> filesystem. Unpacking a tarball with filenames in a different encoding >> is an example. > > You still haven't addressed this: > > | So we accept invalid unicode in filenames, but only after failing to > | parse them? Isn't this a potential vector for exploiting weaknesses > | in application filename handling? i.e. unprivileged user writes > | specially crafted invalid unicode filename to disk, setuid program > | tries to parse it, invalid sequence triggers a buffer overflow bug > | in setuid parser? > > apart from handwaving that userspace has to be able to handle > invalid utf-8 already. Why should we let filesystems say "we fully > understand and support utf8" and then allow them to accept and > propagate invalid utf8 sequences and leave everyone else to have to > clean up the mess? Because the alternative amounts in my opinion to a demand that every bit of userspace that may be involved in generating filenames generate only clean UTF-8. I do not believe that this is a realistic demand at this point in time. >> Partial interpretation of an ill-formed filename just strikes me as >> the kind of bad idea that most half-houses are. I admit that I have no >> stronger objection to this than the fact that it makes the code even >> more complicated and fragile. >> >> Which leaves "blob" as the preferred option by default for coping with >> ill-formed filenames. > > And so can't be case-folded, leading to inconsistent behaviour of > case-insensitive filename comparisons. > > I don't blindly subscribe to the robustness principle of "be liberal > with what you accept". Being liberal means accepting malformed junk > and then trying to make good. It's a fool's game - we've learnt time > and time again that if we don't fully validate string inputs that we > have to interpret then someone will find an exploit that utilises > malformed strings. I don't think we should expose core kernel code > to such structural weaknesses... This is why I prefer not to interpret strings that are not UTF-8. I just don't think we can afford to outright reject them. >> When comparing well-formed filenames, the question now becomes which >> byte sequences are considered to be alternative spellings of the same >> filename. This is where normalization forms come into play, and the >> unicode standard has quite a bit to say about the subject. >> >> If all you're doing is comparison, then choosing NFD over NFC is easy, >> because the former is easier to calculate than the latter. >> >> If you want various spellings of "office" to compare equal, then >> picking NFKD over NFD for comparison is also an obvious >> choice. (Hand-picking individual compatibility forms is truly a bad >> idea.) Ways to spell "office": "o_f_f_i_c_e", "o_f_fi_c_e", and >> "o_ffi_c_e", using no ligatures, the fi ligature, or the ffi >> ligature. (Some fool thought it a good idea to add these ligatures to >> unicode, all we get to decide is how to cope.) > > Yet normalised strings are only stable and hence comparable > if there are no unassigned code points in them. What happens when > userspace is not using the same version of unicode as the > filesystem and is using newer code points in it's strings? > Normalisation fails, right? For the newer code points, yes. This is not treated as a failure to normalize the string as a whole, as there are clear guidelines in unicode on how unassigned code points interact with normalization: they have canonical combining class 0 and no decomposition. > And as an extension of using normalisation for case-folded > comparisons, how do we make case folding work with blobs that can't > be normalised? It seems to me that this just leads to the nasty > situation where some filenames are case sensitive and some aren't > based on what the filesystem thinks is valid utf-8. The worst part > is that userspace has no idea that the filesystem is making such > distinctions and so behaviour is not at all predictable or expected. Making case-folding work on a blob that cannot be normalized is (in my opinion) akin to doing an ASCII-based casefold on a Shift-JIS string: the result is neither pretty nor useful. > This is another point in favour of rejecting invalid utf-8 strings > and for keeping the translation tables stable within the > filesystem... Bear in mind that this means not just rejecting invalid UTF-8 strings, but also rejecting valid UTF-8 strings that encode unassigned code points. This should be easy to implement if it is decided that we want to do this. >> The most contentious part is (should be) ignoring the codepoints with >> the Default_Ignorable_Code_Point property. I've included the list >> below. My argument, such as it is, is that these code points either >> have no visible rendering, or in cases like the soft hyphen, are only >> conditionally visible. The problem with these (as I see it) is that on >> seeing a filename that might contain them you cannot tell whether they >> are present. So I propose to ignore them for the purpose of comparing >> filenames for equality. > > Which introduces a non-standard "visibility criterial" for > determining what should be or shouldn't be part of the normalised > string for comparison. I don't see any real justification for > stepping outside the standard unicode normalisation here - just > because the user cannot see a character in a specific context does > not mean that it is not significant to the application that created > it. I agree these characters may be significant to the application. I'm just not convinced that they should be significant in a file name. >> Finally, case folding. First of all, it is optional. Then the issue is >> that you either go the language-specific route, or simplify the task >> by "just" doing a full casefold (C+F, in unicode parlance). Looking >> around the net I tend to find that if you're going to do casefolding >> at all, then a language-independent full casefold is preferred because >> it is the most predictable option. See >> http://www.w3.org/TR/charmod-norm/ for an example of that kind of >> reasoning. > > Which says in section 2.4: "Some languages need case-folding to be > tailored to meet specific linguistic needs". That implies that the > case folding needs to be language aware and hence needs to be tied > into the NLS subsystem for handling specific quirks like Turkic. It also recommends just doing a full case fold for cases where you are ignorant of the language actually in use. In section 3.1 they say: "However, language-sensitive case-sensitive matching in document formats and protocols is NOT RECOMMENDED because language information can be hard to obtain, verify, or manage and the resulting operations can produce results that frustrate users." This doesn't exactly address the case of filesystems, but as far as I know there is no defined interface that allows kernel code to query the locale settings that currently apply to a userspace process. > I also note that it says in several places that C+F can result in a > folded string of a different length. What happens when that folded > string is longer than 255 bytes and hence longer than NAME_MAX? > That's a bit of a nasty landmine for pathname string handling > functions - developers are going to assume that pathname components > are not longer than NAME_MAX, and if we are passing normalised > strings around that is not a valid assumption.... This is not just true for case folding: normalization may also change string length, and NFD or NFKD will typically increase the length. That is among the reasons why normalized and case folded strings are not stored on disk, and are not passed up to other parts of the kernel. The code posted will generate a normalized version of the user-provided string used to look up data as a way to cache that normalization and to reduce stack pressure a bit, but this string is ephemeral and discarded once lookup is complete. >> * XFS-specific design notes. > ... >> If the borgbit (the bit enabling legacy ASCII-based CI in XFS) is set >> in the superblock, then case folding is added into the mix. This is >> the nfkdicf normalization form mentioned above. It allows for the >> creation of case-insensitive filesystems with UTF-8 support. > > Please don't overload existing superblock feature bits with multiple > meanings. ASCII-CI is a stand-alone feature and is not in any way > compatible with Unicode: Unicode-CI is a superset of Unicode > support. So it really needs two new feature bits for Unicode and > Unicode-CI, not just one for unicode. It seemed an obvious extension of the meaning of that bit. Olaf -- Olaf Weber SGI Phone: +31(0)30-6696796 Veldzigt 2b Fax: +31(0)30-6696799 Technical Lead 3454 PW de Meern Vnet: 955-6796 Storage Software The Netherlands Email: olaf@sgi.com From tessarek@evermeet.cx Wed Sep 24 10:54:11 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 021D57F3F for ; Wed, 24 Sep 2014 10:54:11 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id C223E8F8035 for ; Wed, 24 Sep 2014 08:54:07 -0700 (PDT) X-ASG-Debug-ID: 1411574039-04bdf003a1134590001-NocioJ Received: from atvie01s.evermeet.cx (evermeet.cx [77.244.245.66]) by cuda.sgi.com with ESMTP id FMs6nCbGC64UDayt (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 24 Sep 2014 08:54:00 -0700 (PDT) X-Barracuda-Envelope-From: tessarek@evermeet.cx X-Barracuda-Apparent-Source-IP: 77.244.245.66 Received: from [192.168.9.65] (mail.quickplay.com [66.207.196.66]) (authenticated bits=0) by atvie01s.evermeet.cx (8.14.9/8.14.9) with ESMTP id s8OFrsa3015252 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Wed, 24 Sep 2014 17:53:55 +0200 Message-ID: <5422E912.1000708@evermeet.cx> Date: Wed, 24 Sep 2014 11:53:54 -0400 From: Helmut Tessarek User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:31.0) Gecko/20100101 Thunderbird/31.1.1 MIME-Version: 1.0 To: Stan Hoeppner , Eric Sandeen , xfs@oss.sgi.com Subject: Re: How to format RAID1 correctly References: <5422146A.90206@evermeet.cx> <54222763.40107@sandeen.net> <5422285B.6010306@evermeet.cx> <542234F6.4080000@hardwarefreak.com> <5422376D.3000204@evermeet.cx> <542243E6.1040302@hardwarefreak.com> X-ASG-Orig-Subj: Re: How to format RAID1 correctly In-Reply-To: <542243E6.1040302@hardwarefreak.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: evermeet.cx[77.244.245.66] X-Barracuda-Start-Time: 1411574040 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9828 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 2014-09-24 0:09, Stan Hoeppner wrote: > If you create any striped arrays, especially parity arrays, with md make > sure to manually specify chunk size and match it to your workload. The > current default is 512KB. This is too large for a great many workloads, > specifically those that are metadata heavy or manipulate many small > files. 512KB wastes space and with parity arrays causes RMW, hammering > throughput and increasing latency. Thanks again for the valueable information. I used to work with databases on storage subsystems, so placing GBs of database containers for tableapaces on arrays with a larger stripe size was actually beneficial. For log files and other data I usually used different cache settings and strip sizes. So how does this work with SW RAID? Does the XFS chunk size equal the amount of data touched by a single r/w operation? I'm asking because data is usually written in page/extent sizes for databases. Even if I have a container with 50GB, I might only have to read/write a 4k page. Cheers, K. C. -- regards Helmut K. C. Tessarek lookup http://sks.pkqs.net for KeyID 0xC11F128D /* Thou shalt not follow the NULL pointer for chaos and madness await thee at its end. */ From sandeen@sandeen.net Wed Sep 24 11:18:22 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E7CB97F47 for ; Wed, 24 Sep 2014 11:18:22 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id C7E6A8F8039 for ; Wed, 24 Sep 2014 09:18:19 -0700 (PDT) X-ASG-Debug-ID: 1411575497-04bdf003a2135940001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id Ldo6vJ5Kmyp0BW7H for ; Wed, 24 Sep 2014 09:18:17 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 6C3B363D22A4; Wed, 24 Sep 2014 11:18:17 -0500 (CDT) Message-ID: <5422EECA.10301@sandeen.net> Date: Wed, 24 Sep 2014 11:18:18 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Helmut Tessarek , Stan Hoeppner , xfs@oss.sgi.com Subject: Re: How to format RAID1 correctly References: <5422146A.90206@evermeet.cx> <54222763.40107@sandeen.net> <5422285B.6010306@evermeet.cx> <542234F6.4080000@hardwarefreak.com> <5422376D.3000204@evermeet.cx> <542243E6.1040302@hardwarefreak.com> <5422E912.1000708@evermeet.cx> X-ASG-Orig-Subj: Re: How to format RAID1 correctly In-Reply-To: <5422E912.1000708@evermeet.cx> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1411575497 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9828 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/24/14 10:53 AM, Helmut Tessarek wrote: > On 2014-09-24 0:09, Stan Hoeppner wrote: >> If you create any striped arrays, especially parity arrays, with md make >> sure to manually specify chunk size and match it to your workload. The >> current default is 512KB. This is too large for a great many workloads, >> specifically those that are metadata heavy or manipulate many small >> files. 512KB wastes space and with parity arrays causes RMW, hammering >> throughput and increasing latency. > > Thanks again for the valueable information. > > I used to work with databases on storage subsystems, so placing GBs of > database containers for tableapaces on arrays with a larger stripe size > was actually beneficial. > For log files and other data I usually used different cache settings and > strip sizes. > > So how does this work with SW RAID? > > Does the XFS chunk size equal the amount of data touched by a single r/w > operation? It has more to do with where allocations start, so that allocations don't cross stripe boundaries if possible. -Eric From jack@suse.cz Wed Sep 24 11:25:12 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 0E58A7F4E for ; Wed, 24 Sep 2014 11:25:12 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id EEF618F8037 for ; Wed, 24 Sep 2014 09:25:11 -0700 (PDT) X-ASG-Debug-ID: 1411575909-04cb6c50e5122320001-NocioJ Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id eTDAwEUgKsy73nIP (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 24 Sep 2014 09:25:10 -0700 (PDT) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 0725AAAF3; Wed, 24 Sep 2014 16:25:09 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 22D9181F97; Wed, 24 Sep 2014 18:25:07 +0200 (CEST) Date: Wed, 24 Sep 2014 18:25:07 +0200 From: Jan Kara To: Li Xi Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-api@vger.kernel.org, tytso@mit.edu, adilger@dilger.ca, jack@suse.cz, viro@zeniv.linux.org.uk, hch@infradead.org, dmonakhov@openvz.org, xfs@oss.sgi.com Subject: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project Message-ID: <20140924162507.GC27000@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project References: <1411567470-31799-1-git-send-email-lixi@ddn.com> <1411567470-31799-5-git-send-email-lixi@ddn.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411567470-31799-5-git-send-email-lixi@ddn.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: cantor2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1411575909 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9828 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed 24-09-14 22:04:30, Li Xi wrote: > This patch adds ioctl interface for setting/getting project of ext4. The patch looks good to me. I was just wondering whether it won't be useful to add an ioctl() which isn't ext4 specific. We could just extend ->setattr() to allow setting of project ID (most filesystems would just return -EOPNOTSUPP but ext4 and xfs could do the right thing) and then call ->setattr from the generic ioctl. That way userspace won't have to care about filesystem type when setting project ID... What do others think? Honza > Signed-off-by: Li Xi > --- > Documentation/filesystems/ext4.txt | 4 ++ > fs/ext4/ext4.h | 2 + > fs/ext4/ioctl.c | 85 ++++++++++++++++++++++++++++++++++++ > 3 files changed, 91 insertions(+), 0 deletions(-) > > diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt > index 919a329..9c98e62 100644 > --- a/Documentation/filesystems/ext4.txt > +++ b/Documentation/filesystems/ext4.txt > @@ -609,6 +609,10 @@ EXT4_IOC_SWAP_BOOT Swap i_blocks and associated attributes > The data blocks of the previous boot loader > will be associated with the given inode. > > + EXT4_IOC_GETPROJECT Get project ID associated with inode. > + > + EXT4_IOC_SETPROJECT Set Project ID associated with inode. > + > .............................................................................. > > References > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h > index f8be9bf..51946fd 100644 > --- a/fs/ext4/ext4.h > +++ b/fs/ext4/ext4.h > @@ -617,6 +617,8 @@ enum { > #define EXT4_IOC_RESIZE_FS _IOW('f', 16, __u64) > #define EXT4_IOC_SWAP_BOOT _IO('f', 17) > #define EXT4_IOC_PRECACHE_EXTENTS _IO('f', 18) > +#define EXT4_IOC_GETPROJECT _IOR('f', 19, long) > +#define EXT4_IOC_SETPROJECT _IOW('f', 20, long) > > #if defined(__KERNEL__) && defined(CONFIG_COMPAT) > /* > diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c > index 0f2252e..93b7ff4 100644 > --- a/fs/ext4/ioctl.c > +++ b/fs/ext4/ioctl.c > @@ -14,6 +14,8 @@ > #include > #include > #include > +#include > +#include > #include > #include "ext4_jbd2.h" > #include "ext4.h" > @@ -611,6 +613,89 @@ resizefs_out: > case EXT4_IOC_PRECACHE_EXTENTS: > return ext4_ext_precache(inode); > > + case EXT4_IOC_GETPROJECT: > + { > + __u32 projid; > + > + projid = (__u32)from_kprojid(&init_user_ns, > + EXT4_I(inode)->i_projid); > + return put_user(projid, (__u32 __user *) arg); > + } > + case EXT4_IOC_SETPROJECT: > + { > + __u32 projid; > + int err; > + handle_t *handle; > + kprojid_t kprojid; > + struct ext4_iloc iloc; > + struct ext4_inode *raw_inode; > + > + struct dquot *transfer_to[EXT4_MAXQUOTAS] = { }; > + > + /* Make sure caller can change project. */ > + if (!capable(CAP_SYS_ADMIN)) > + return -EACCES; > + > + if (get_user(projid, (__u32 __user *) arg)) > + return -EFAULT; > + > + kprojid = make_kprojid(&init_user_ns, (projid_t)projid); > + > + if (projid_eq(kprojid, EXT4_I(inode)->i_projid)) > + return 0; > + > + err = mnt_want_write_file(filp); > + if (err) > + return err; > + > + err = -EPERM; > + mutex_lock(&inode->i_mutex); > + /* Is it quota file? Do not allow user to mess with it */ > + if (IS_NOQUOTA(inode)) > + goto project_out; > + > + dquot_initialize(inode); > + > + handle = ext4_journal_start(inode, EXT4_HT_QUOTA, > + EXT4_QUOTA_INIT_BLOCKS(sb) + > + EXT4_QUOTA_DEL_BLOCKS(sb) + 3); > + if (IS_ERR(handle)) { > + err = PTR_ERR(handle); > + goto project_out; > + } > + > + err = ext4_reserve_inode_write(handle, inode, &iloc); > + if (err) > + goto project_stop; > + > + raw_inode = ext4_raw_inode(&iloc); > + if ((EXT4_INODE_SIZE(inode->i_sb) <= > + EXT4_GOOD_OLD_INODE_SIZE) || > + (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid))) { > + err = -EFBIG; > + goto project_stop; > + } > + > + transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid)); > + if (!transfer_to[PRJQUOTA]) > + goto project_set; > + > + err = __dquot_transfer(inode, transfer_to); > + dqput(transfer_to[PRJQUOTA]); > + if (err) > + goto project_stop; > + > +project_set: > + EXT4_I(inode)->i_projid = kprojid; > + inode->i_ctime = ext4_current_time(inode); > + err = ext4_mark_iloc_dirty(handle, inode, &iloc); > +project_stop: > + ext4_journal_stop(handle); > +project_out: > + mutex_unlock(&inode->i_mutex); > + mnt_drop_write_file(filp); > + return err; > + } > default: > return -ENOTTY; > } > -- > 1.7.1 > -- Jan Kara SUSE Labs, CR From BATV+22d22156cf6d8c505944+4049+infradead.org+hch@bombadil.srs.infradead.org Wed Sep 24 11:26:41 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 345CB7F51 for ; Wed, 24 Sep 2014 11:26:41 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0478C8F8035 for ; Wed, 24 Sep 2014 09:26:40 -0700 (PDT) X-ASG-Debug-ID: 1411575998-04bdf0039f136050001-NocioJ Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) by cuda.sgi.com with ESMTP id fBOcYX8odNweNGIt (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 24 Sep 2014 09:26:38 -0700 (PDT) X-Barracuda-Envelope-From: BATV+22d22156cf6d8c505944+4049+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XWpOk-000541-TX; Wed, 24 Sep 2014 16:26:34 +0000 Date: Wed, 24 Sep 2014 09:26:34 -0700 From: Christoph Hellwig To: Jan Kara Cc: Li Xi , linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-api@vger.kernel.org, tytso@mit.edu, adilger@dilger.ca, viro@zeniv.linux.org.uk, hch@infradead.org, dmonakhov@openvz.org, xfs@oss.sgi.com Subject: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project Message-ID: <20140924162634.GA16886@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project References: <1411567470-31799-1-git-send-email-lixi@ddn.com> <1411567470-31799-5-git-send-email-lixi@ddn.com> <20140924162507.GC27000@quack.suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140924162507.GC27000@quack.suse.cz> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: bombadil.infradead.org[198.137.202.9] X-Barracuda-Start-Time: 1411575998 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9828 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Sep 24, 2014 at 06:25:07PM +0200, Jan Kara wrote: > On Wed 24-09-14 22:04:30, Li Xi wrote: > > This patch adds ioctl interface for setting/getting project of ext4. > The patch looks good to me. I was just wondering whether it won't be > useful to add an ioctl() which isn't ext4 specific. We could just extend > ->setattr() to allow setting of project ID (most filesystems would just > return -EOPNOTSUPP but ext4 and xfs could do the right thing) and then call > ->setattr from the generic ioctl. That way userspace won't have to care > about filesystem type when setting project ID... What do others think? Absolutely. In general I also wonder why this patch doesn't implement the full XFS API. Maybe there is a reason it was considered and rejected, but it would be helpful to document why. From jack@suse.cz Wed Sep 24 12:01:13 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 3E4D27F53 for ; Wed, 24 Sep 2014 12:01:13 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1CB788F804C for ; Wed, 24 Sep 2014 10:01:09 -0700 (PDT) X-ASG-Debug-ID: 1411578067-04bdf003a2137a60001-NocioJ Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id vrXixPsI33tdgqzc (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 24 Sep 2014 10:01:08 -0700 (PDT) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id CBDAEAB43; Wed, 24 Sep 2014 17:01:06 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 0E86D81F97; Wed, 24 Sep 2014 19:01:05 +0200 (CEST) Date: Wed, 24 Sep 2014 19:01:05 +0200 From: Jan Kara To: Christoph Hellwig Cc: Jan Kara , Li Xi , linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-api@vger.kernel.org, tytso@mit.edu, adilger@dilger.ca, viro@zeniv.linux.org.uk, dmonakhov@openvz.org, xfs@oss.sgi.com Subject: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project Message-ID: <20140924170105.GE27000@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project References: <1411567470-31799-1-git-send-email-lixi@ddn.com> <1411567470-31799-5-git-send-email-lixi@ddn.com> <20140924162507.GC27000@quack.suse.cz> <20140924162634.GA16886@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140924162634.GA16886@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: cantor2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1411578067 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9829 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed 24-09-14 09:26:34, Christoph Hellwig wrote: > On Wed, Sep 24, 2014 at 06:25:07PM +0200, Jan Kara wrote: > > On Wed 24-09-14 22:04:30, Li Xi wrote: > > > This patch adds ioctl interface for setting/getting project of ext4. > > The patch looks good to me. I was just wondering whether it won't be > > useful to add an ioctl() which isn't ext4 specific. We could just extend > > ->setattr() to allow setting of project ID (most filesystems would just > > return -EOPNOTSUPP but ext4 and xfs could do the right thing) and then call > > ->setattr from the generic ioctl. That way userspace won't have to care > > about filesystem type when setting project ID... What do others think? > > Absolutely. In general I also wonder why this patch doesn't implement > the full XFS API. Maybe there is a reason it was considered and > rejected, but it would be helpful to document why. Do you mean full get/setfsxattr API? That basically contains project ID, flags (those that are currently get/set with FS_IOC_GETFLAGS/SETFLAGS), and extent size hint right? That seems workable and it would also make setting of PROJINHERIT flag fs agnostic. Only we would have to create some generic flags namespace and merge into that ext4 flags and have a translation function for the old ext4 flags. Also I'm afraid we may quickly run out of 32 available flags in xflags so we'd need to extend that. But all this seems to be doable. Honza -- Jan Kara SUSE Labs, CR From chad.kee@udc.edu Wed Sep 24 12:03:12 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6644B7F53 for ; Wed, 24 Sep 2014 12:03:12 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 04771AC00C for ; Wed, 24 Sep 2014 10:03:08 -0700 (PDT) X-ASG-Debug-ID: 1411578187-04bdf003a2137c20001-NocioJ Received: from na01-by2-obe.outbound.protection.outlook.com (mail-by2hn0254.outbound.protection.outlook.com [207.46.100.254]) by cuda.sgi.com with ESMTP id 5Dxt2PH7MH3i2FHU (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 24 Sep 2014 10:03:07 -0700 (PDT) X-Barracuda-Envelope-From: chad.kee@udc.edu X-Barracuda-Apparent-Source-IP: 207.46.100.254 Received: from BY2PR01CA001.prod.exchangelabs.com (10.255.247.31) by CY1PR0101MB1051.prod.exchangelabs.com (25.160.225.143) with Microsoft SMTP Server (TLS) id 15.0.1034.13; Wed, 24 Sep 2014 17:03:05 +0000 Received: from BN1AFFO11FD032.protection.gbl (2a01:111:f400:7c10::131) by BY2PR01CA001.outlook.office365.com (2a01:111:e400:2c16::31) with Microsoft SMTP Server (TLS) id 15.0.1039.15 via Frontend Transport; Wed, 24 Sep 2014 17:03:04 +0000 Received: from mail.udc.edu (38.105.72.86) by BN1AFFO11FD032.mail.protection.outlook.com (10.58.52.186) with Microsoft SMTP Server (TLS) id 15.0.1029.15 via Frontend Transport; Wed, 24 Sep 2014 17:03:04 +0000 Received: from UDCMSGSTAFF-M.firebirds.udc.edu ([fe80::6050:5d2:44a7:687b]) by UDCMSG008.firebirds.udc.edu ([fe80::b8e9:ca18:5333:1fc0%10]) with mapi; Wed, 24 Sep 2014 13:02:07 -0400 From: "Kee, Chad E." Date: Wed, 24 Sep 2014 13:02:06 -0400 Subject: Thread-Index: AQHP2BlE5jso6NsekEmgDV4zbyjIUg== X-ASG-Orig-Subj: Message-ID: <7D9600C7E626D243869355C8D9BE880A0140FE9B22D1@UDCMSGSTAFF-M.firebirds.udc.edu> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US Content-Type: multipart/alternative; boundary="_000_7D9600C7E626D243869355C8D9BE880A0140FE9B22D1UDCMSGSTAFF_" MIME-Version: 1.0 To: Undisclosed recipients:; X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:38.105.72.86;CTRY:US;IPV:NLI;EFV:NLI;SFV:SPM;SFS:(10019020)(6009001)(448002)(199003)(189002)(88552001)(81542003)(21056001)(1671002)(20776003)(64706001)(75432002)(85326001)(120916001)(76482002)(106116001)(10300001)(881003)(71186001)(44976005)(5406001)(325944007)(83322001)(4396001)(95666004)(107046002)(90282001)(86362001)(16236675004)(55846006)(109096001)(6806004)(85852003)(46102003)(83072002)(31966008)(90102001)(81342003)(79102003)(54356999)(87936001)(77982003)(50986999)(106466001)(109986003)(33656002)(19580395003)(107886001)(512934002)(19580405001)(84326002)(2656002)(80022003)(89122001)(92726001)(25636003)(77096002)(92566001)(104016003)(85306004)(110136001)(74662003)(74502003)(99396003)(75786005);DIR:OUT;SFP:1501;SCL:5;SRVR:CY1PR0101MB1051;H:mail.udc.edu;FPR:;MLV:spm;PTR:owa.udc.edu,www.owa.udc.edu,email.udc.edu,www.email.udc.edu,email8.udc.edu,udcmsg008.firebirds.udc.edu,pop.udc.edu,pop3.udc.edu,www.webmail.udc.edu;A:1;MX:1;LANG:en; X-Microsoft-Antispam: UriScan:; X-Microsoft-Antispam: BCL:0;PCL:0;RULEID:;SRVR:CY1PR0101MB1051; X-Forefront-PRVS: 03449D5DD1 Received-SPF: PermError (protection.outlook.com: domain of udc.edu used an invalid SPF mechanism) Authentication-Results: spf=permerror (sender IP is 38.105.72.86) smtp.mailfrom=chad.kee@udc.edu; X-OriginatorOrg: udc.edu X-Barracuda-Connect: mail-by2hn0254.outbound.protection.outlook.com[207.46.100.254] X-Barracuda-Start-Time: 1411578187 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.31 X-Barracuda-Spam-Status: No, SCORE=1.31 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE, MAILTO_TO_SPAM_ADDR, MISSING_SUBJECT, MISSING_SUBJECT_2, THREAD_INDEX X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9829 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.00 MAILTO_TO_SPAM_ADDR URI: Includes a link to a likely spammer email 0.00 HTML_MESSAGE BODY: HTML included in message 0.01 MISSING_SUBJECT Missing Subject: header 1.28 MISSING_SUBJECT_2 Missing Subject: header --_000_7D9600C7E626D243869355C8D9BE880A0140FE9B22D1UDCMSGSTAFF_ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Need a loan for financial assistance? We Loans Guarantee Loan Fund Company to interest rates casualties. CONTACT U.S. VIA E-MAIL paulhiggins018@hotmail.co.uk CONTACT Mr.Paul Higgins --_000_7D9600C7E626D243869355C8D9BE880A0140FE9B22D1UDCMSGSTAFF_ Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable
=  

Need a loan for financial assistance? We Loans
Gu= arantee Loan Fund Company to interest rates
ca= sualties.
CO= NTACT U.S. VIA E-MAIL <= /font>
paulhiggins018@hotmail.co.uk
CONTACT Mr.Paul Higgins

--_000_7D9600C7E626D243869355C8D9BE880A0140FE9B22D1UDCMSGSTAFF_-- From bfoster@redhat.com Wed Sep 24 13:47:12 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=LOTS_OF_MONEY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id D26067F47 for ; Wed, 24 Sep 2014 13:47:12 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id AF36B304059 for ; Wed, 24 Sep 2014 11:47:09 -0700 (PDT) X-ASG-Debug-ID: 1411584428-04cbb07301137070001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id r05N3sGmH1QNpc0N (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 24 Sep 2014 11:47:08 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8OIl7KU012680 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 24 Sep 2014 14:47:07 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8OIl7NJ007445; Wed, 24 Sep 2014 14:47:07 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id C2206120064; Wed, 24 Sep 2014 14:47:05 -0400 (EDT) From: Brian Foster To: fstests@vger.kernel.org Cc: xfs@oss.sgi.com Subject: [PATCH] generic/033: add xfs delalloc indirect block depletion reproducer Date: Wed, 24 Sep 2014 14:47:05 -0400 X-ASG-Orig-Subj: [PATCH] generic/033: add xfs delalloc indirect block depletion reproducer Message-Id: <1411584425-52709-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411584428 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 XFS allocates extra indirect blocks for delayed allocation extents at write time. When delalloc extents are split, the existing indirect block reservation was historically divided up evenly among the new extents even though the overall requirement for two extents could exceed the requirement for the original. Repeated delalloc extent splits ultimately leads to extents with 0 indirect blocks and in turn leads to assert failures in XFS. Add a test to stress indirect block reservation for delayed allocation extents. The test converts a single delalloc extent to many and operates on the remaining extents to detect or trigger potential problems. Signed-off-by: Brian Foster --- Here's a simple reproducer for the indirect block reservation problem called out here: http://oss.sgi.com/archives/xfs/2014-09/msg00337.html It reproduces the assert failures described therein: XFS: Assertion failed: startblockval(del.br_startblock) > 0, file: fs/xfs/libxfs/xfs_bmap.c, line: 5281 Note that this test also unintentionally fails on XFS. The test file ends up zero-sized after the remount and thus hexdump doesn't produce any output. This doesn't occur on ext4, I suspect due to the fact that the range being zeroed is flushed beforehand, though I could be wrong about that. In any event, this calls out a separate bug in XFS where if appending data is chucked from cache by zero range before written back (eof is page aligned), we lose the on-disk inode size update and the inode size changes unexpectedly across the remount (assuming nothing else changes the size, of course). Brian tests/generic/033 | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/033.out | 4 +++ tests/generic/group | 1 + 3 files changed, 93 insertions(+) create mode 100755 tests/generic/033 create mode 100644 tests/generic/033.out diff --git a/tests/generic/033 b/tests/generic/033 new file mode 100755 index 0000000..41198b7 --- /dev/null +++ b/tests/generic/033 @@ -0,0 +1,88 @@ +#! /bin/bash +# FS QA Test No. 033 +# +# This test stresses indirect block reservation for delayed allocation extents. +# XFS reserves extra blocks for deferred allocation of delalloc extents. These +# reserved blocks can be divided among more extents than anticipated if the +# original extent for which the blocks were reserved is split into multiple +# delalloc extents. If this scenario repeats, eventually some extents are left +# without any indirect block reservation whatsoever. This leads to assert +# failures and possibly other problems in XFS. +# +#----------------------------------------------------------------------- +# Copyright (c) 2014 Red Hat, Inc. All Rights Reserved. +# +# This program 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. +# +# This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -f $tmp.* +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +rm -f $seqres.full + +# Modify as appropriate. +_supported_fs generic +_supported_os Linux +_require_scratch +_require_xfs_io_command "fzero" + +_scratch_mkfs >/dev/null 2>&1 +_scratch_mount + +file=$SCRATCH_MNT/file.$seq +bytes=$((64 * 1024)) + +# create sequential delayed allocation +$XFS_IO_PROG -f -c "pwrite 0 $bytes" $file | _filter_xfs_io \ + >> $seqres.full 2>&1 + +# Zero every other 4k range to split the larger delalloc extent into many more +# smaller extents. Use zero instead of hole punch because the former does not +# force writeback (and hence delalloc conversion). It can simply discard +# delalloc blocks and convert the ranges to unwritten. +endoff=$((bytes - 4096)) +for i in $(seq 0 8192 $endoff); do + $XFS_IO_PROG -c "fzero -k $i 4k" $file | _filter_xfs_io \ + >> $seqres.full 2>&1 +done + +# now zero the opposite set to remove remaining delalloc extents +for i in $(seq 4096 8192 $endoff); do + $XFS_IO_PROG -c "fzero -k $i 4k" $file | _filter_xfs_io \ + >> $seqres.full 2>&1 +done + +_scratch_remount +hexdump $file + +status=0 +exit diff --git a/tests/generic/033.out b/tests/generic/033.out new file mode 100644 index 0000000..419d831 --- /dev/null +++ b/tests/generic/033.out @@ -0,0 +1,4 @@ +QA output created by 033 +0000000 0000 0000 0000 0000 0000 0000 0000 0000 +* +0010000 diff --git a/tests/generic/group b/tests/generic/group index 8e0c22a..1227408 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -32,6 +32,7 @@ 027 auto enospc 028 auto quick 032 auto quick rw +033 auto quick rw 053 acl repair auto quick 062 attr udf auto quick 068 other auto freeze dangerous stress -- 1.8.3.1 From bfoster@redhat.com Wed Sep 24 14:06:38 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 8E8CB7F5A for ; Wed, 24 Sep 2014 14:06:38 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7D5E88F8033 for ; Wed, 24 Sep 2014 12:06:35 -0700 (PDT) X-ASG-Debug-ID: 1411585593-04cb6c50e512a7d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id oFBMffDsKFMCPnmV (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 24 Sep 2014 12:06:34 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8OJ6XT6020806 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Wed, 24 Sep 2014 15:06:33 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8OJ6XAd016743 for ; Wed, 24 Sep 2014 15:06:33 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 0C7EE120064; Wed, 24 Sep 2014 15:06:31 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH] xfs: flush the range before zero range conversion Date: Wed, 24 Sep 2014 15:06:31 -0400 X-ASG-Orig-Subj: [PATCH] xfs: flush the range before zero range conversion Message-Id: <1411585591-55975-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411585594 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 XFS currently discards delalloc blocks within the target range of a zero range request. Unaligned start and end offsets are zeroed through the page cache and the internal, aligned blocks are converted to unwritten extents. If EOF is page aligned and covered by a delayed allocation extent. The inode size is not updated until I/O completion. If a zero range request discards a delalloc range that covers page aligned EOF as such, the inode size update never occurs. For example: $ rm -f /mnt/file $ xfs_io -fc "pwrite 0 64k" -c "zero 60k 4k" /mnt/file $ stat -c "%s" /mnt/file 65536 $ umount /mnt $ mount /mnt $ stat -c "%s" /mnt/file 61440 Update xfs_zero_file_space() to flush the range rather than discard delalloc blocks to ensure that inode size updates occur appropriately. Signed-off-by: Brian Foster --- I suppose we could be more clever here and only flush the range in this particular scenario, but I'm not sure if there's a major benefit there. FWIW, this implicitly addresses the indlen==0 assert failures described in the xfs_bmap_del_extent() rfc, but doesn't necessarily mean we shouldn't fix that code IMO. Brian fs/xfs/xfs_bmap_util.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index d8b77b5..24d634d 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1394,14 +1394,14 @@ xfs_zero_file_space( if (start_boundary < end_boundary - 1) { /* - * punch out delayed allocation blocks and the page cache over - * the conversion range + * Writeback the range to ensure any inode size updates due to + * appending writes make it to disk (otherwise we could just + * punch out the delalloc blocks). */ - xfs_ilock(ip, XFS_ILOCK_EXCL); - error = xfs_bmap_punch_delalloc_range(ip, - XFS_B_TO_FSBT(mp, start_boundary), - XFS_B_TO_FSB(mp, end_boundary - start_boundary)); - xfs_iunlock(ip, XFS_ILOCK_EXCL); + error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, + start_boundary, end_boundary - 1); + if (error) + goto out; truncate_pagecache_range(VFS_I(ip), start_boundary, end_boundary - 1); -- 1.8.3.1 From stan@hardwarefreak.com Wed Sep 24 14:06:50 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C7C3E7F5A for ; Wed, 24 Sep 2014 14:06:50 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 56026AC008 for ; Wed, 24 Sep 2014 12:06:47 -0700 (PDT) X-ASG-Debug-ID: 1411585605-04cbb07304138010001-NocioJ Received: from greer.hardwarefreak.com (mo-65-41-216-221.sta.embarqhsd.net [65.41.216.221]) by cuda.sgi.com with ESMTP id SpUhdk0qfeuYybix for ; Wed, 24 Sep 2014 12:06:46 -0700 (PDT) X-Barracuda-Envelope-From: stan@hardwarefreak.com X-Barracuda-Apparent-Source-IP: 65.41.216.221 X-Barracuda-User-Whitelist: xfs@oss.sgi.com Received: from [192.168.100.53] (mo-65-41-216-221.sta.embarqhsd.net [65.41.216.221]) by greer.hardwarefreak.com (Postfix) with ESMTPA id AE1956C052; Wed, 24 Sep 2014 14:06:45 -0500 (CDT) Message-ID: <54231653.7050600@hardwarefreak.com> Date: Wed, 24 Sep 2014 14:06:59 -0500 From: Stan Hoeppner User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Icedove/24.7.0 MIME-Version: 1.0 To: Helmut Tessarek , Eric Sandeen , xfs@oss.sgi.com Subject: Re: How to format RAID1 correctly References: <5422146A.90206@evermeet.cx> <54222763.40107@sandeen.net> <5422285B.6010306@evermeet.cx> <542234F6.4080000@hardwarefreak.com> <5422376D.3000204@evermeet.cx> <542243E6.1040302@hardwarefreak.com> <5422E912.1000708@evermeet.cx> X-ASG-Orig-Subj: Re: How to format RAID1 correctly In-Reply-To: <5422E912.1000708@evermeet.cx> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mo-65-41-216-221.sta.embarqhsd.net[65.41.216.221] X-Barracuda-Start-Time: 1411585606 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On 09/24/2014 10:53 AM, Helmut Tessarek wrote: > On 2014-09-24 0:09, Stan Hoeppner wrote: >> If you create any striped arrays, especially parity arrays, with md make >> sure to manually specify chunk size and match it to your workload. The >> current default is 512KB. This is too large for a great many workloads, >> specifically those that are metadata heavy or manipulate many small >> files. 512KB wastes space and with parity arrays causes RMW, hammering >> throughput and increasing latency. > > Thanks again for the valueable information. > > I used to work with databases on storage subsystems, so placing GBs of > database containers for tableapaces on arrays with a larger stripe size > was actually beneficial. > For log files and other data I usually used different cache settings and > strip sizes. > > So how does this work with SW RAID? > > Does the XFS chunk size equal the amount of data touched by a single r/w > operation? No. The XFS stripe unit size (chunk size) must/should equal the underlying RAID stripe unit size (chunk). As Eric said, all this does is help XFS align allocations to the underlying RAID geometry in an attempt to get more full chunk/stripe writes on the disks. Note we both said allocation. The XFS sunit/swidth settings have no affect with file appends or writing into preallocated files. > I'm asking because data is usually written in page/extent sizes for > databases. Even if I have a container with 50GB, I might only have to > read/write a 4k page. db operations are going to be append or modify-in-place. Neither will benefit from aligning XFS to the RAID geometry. Appending the db logs is also not allocation. So in practical terms, you simply would not use the "-d" striping options during mkfs.xfs. Use the defaults. Cheers, Stan From lists@nerdbynature.de Wed Sep 24 14:15:09 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 664587F63 for ; Wed, 24 Sep 2014 14:15:09 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 3757F304062 for ; Wed, 24 Sep 2014 12:15:09 -0700 (PDT) X-ASG-Debug-ID: 1411586102-04bdf003a113f630001-NocioJ Received: from trent.utfs.org (trent.utfs.org [94.185.90.103]) by cuda.sgi.com with ESMTP id cw4hpCsEBB1KMHdq (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 24 Sep 2014 12:15:04 -0700 (PDT) X-Barracuda-Envelope-From: lists@nerdbynature.de X-Barracuda-Apparent-Source-IP: 94.185.90.103 Received: by trent.utfs.org (Postfix, from userid 8) id EEDFF3DABF; Wed, 24 Sep 2014 21:15:00 +0200 (CEST) Received: from trent.utfs.org (localhost [127.0.0.1]) by trent.utfs.org (Postfix) with ESMTP id BC02D3DAE7; Wed, 24 Sep 2014 21:14:59 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by trent.utfs.org (Postfix) with ESMTP id 99D9F3DABF; Wed, 24 Sep 2014 21:14:59 +0200 (CEST) Date: Wed, 24 Sep 2014 12:14:59 -0700 (PDT) From: Christian Kujau To: Dave Chinner cc: xfs@oss.sgi.com Subject: Re: log record CRC mismatch: found 0x10a71f1d, expected 0xe012d25f In-Reply-To: X-ASG-Orig-Subj: Re: log record CRC mismatch: found 0x10a71f1d, expected 0xe012d25f Message-ID: References: <20140618120124.GR9508@dastard> <20140618230721.GD4453@dastard> User-Agent: Alpine 2.19.4 (DEB 40 2013-11-18) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-AV-Checked: ClamAV using ClamSMTP (127.0.0.1 at Wed Sep 24 21:14:59 2014 +0200 (CEST)) X-Barracuda-Connect: trent.utfs.org[94.185.90.103] X-Barracuda-Start-Time: 1411586103 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.20 X-Barracuda-Spam-Status: No, SCORE=0.20 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=PR0N_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9833 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.20 PR0N_SUBJECT Subject has letters around special characters (pr0n) On Wed, 18 Jun 2014 at 17:22, Christian Kujau wrote: > On Thu, 19 Jun 2014 at 09:07, Dave Chinner wrote: > > > When the PowerPC box crashed there should not have been any i/o on > > > the file system - so, if there was nothing to commit, clearing the > > > log with "xfs_repair -L" should not lose any data, right? > > > > In theory. use xfs_logprint to check the log is empty... > > Ah - next time I'll use that. I was too impatient and went with > "-L" and now the filesystem could be mounted. All is good. My PowerBook G4 is offline again (rats!) and again I connected this disk to an i686 laptop. Trying to mount fails again, because the XFS file system was not unmounted properly and the i686 laptop cannot read the big-endian XFS log. OK, no biggie, this had been explained earlier. I just wanted to share the xfs_logprint(8) output of this filesystem and I haven't cleared the log yet - just in case anyone wants to play around with that some more: # xfs_logprint /dev/mapper/wdc1 xfs_logprint: data device: 0xfd03 log device: 0xfd03 daddr: 976762064 length: 262144 cycle: 1 version: 2 lsn: 1,0 tail_lsn: 1,0 length of Log Record: 20 prev offset: -1 num ops: 1 uuid: 3f121b9a-19e9-4cc8-97ba-86ec62240026 format: little endian linux h_size: 32768 ---------------------------------------------------------------------------- Oper (0): tid: b0c0d0d0 len: 8 clientid: LOG flags: UNMOUNT Unmount filesystem ============================================================================ cycle: 1 version: 2 lsn: 1,2 tail_lsn: 1,2 length of Log Record: 512 prev offset: 0 num ops: 5 uuid: 3f121b9a-19e9-4cc8-97ba-86ec62240026 format: big endian linux h_size: 32768 ---------------------------------------------------------------------------- Oper (0): tid: 4029c0bb len: 0 clientid: TRANS flags: START ---------------------------------------------------------------------------- Oper (1): tid: 4029c0bb len: 16 clientid: TRANS flags: none xfs_logprint: unknown log operation type (5254) ********************************************************************** * ERROR: data block=2 * ********************************************************************** Bad data in log When the PowerPC crashed, the XFS file system was mounte read-write but no writes should have been active, only read operations at best. I'll probably clear the log tomorrow. And yes, this might be a more exotic scenario so don't bother with code fixes, I just wanted this to be somewhat documented in the archives. Cheers, Christian. # mount -t xfs -o ro /dev/mapper/wdc1 /mnt # dmesg [...] XFS (dm-3): Mounting V4 Filesystem XFS (dm-3): Starting recovery (logdev: internal) XFS (dm-3): log record CRC mismatch: found 0xbb3995f5, expected 0x6e17c591. fa400000: 00 00 00 01 00 00 00 00 69 01 00 00 8e 6c 64 e0 ........i....ld. fa400010: 00 00 00 10 69 00 00 00 54 52 41 4e 00 00 00 2a ....i...TRAN...* XFS (dm-3): dirty log written in incompatible format - can't recover XFS (dm-3): log mount/recovery failed: error 5 XFS (dm-3): log mount failed > Now I only have to make sure to cleanly unmount from the i686 box > once my PowerPC system is back online :-) > > Thanks you! > Christian. > -- > BOFH excuse #25: > > Decreasing electron flux -- BOFH excuse #334: 50% of the manual is in .pdf readme files From diane@caltech.edu Wed Sep 24 15:38:54 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 3CE7A7F55 for ; Wed, 24 Sep 2014 15:38:54 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1CD988F8033 for ; Wed, 24 Sep 2014 13:38:50 -0700 (PDT) X-ASG-Debug-ID: 1411591129-04bdf0039f144040001-NocioJ Received: from chaos.caltech.edu (chaos.caltech.edu [131.215.34.119]) by cuda.sgi.com with ESMTP id Agh7fqjjhQpllpv1 (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO) for ; Wed, 24 Sep 2014 13:38:49 -0700 (PDT) X-Barracuda-Envelope-From: diane@caltech.edu X-Barracuda-Apparent-Source-IP: 131.215.34.119 Received: from dhcp-54-193.caltech.edu ([131.215.54.193] helo=myrada.localnet) by chaos.caltech.edu with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.80) (envelope-from ) id 1XWtKq-0002CX-BS; Wed, 24 Sep 2014 13:38:48 -0700 From: Diane Trout To: Emmanuel Florac Cc: xfs@oss.sgi.com Subject: Re: Corrupted file system Date: Wed, 24 Sep 2014 13:38:27 -0700 X-ASG-Orig-Subj: Re: Corrupted file system Message-ID: <705802842.F0QjhfVGQR@myrada> User-Agent: KMail/4.14 (Linux/3.14-2-amd64; KDE/4.14.1; x86_64; ; ) In-Reply-To: <20140924120840.1be78240@harpe.intellique.com> References: <5839367.DyqsVHbRuQ@myrada> <20140924120840.1be78240@harpe.intellique.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="iso-8859-1" X-Barracuda-Connect: chaos.caltech.edu[131.215.34.119] X-Barracuda-Start-Time: 1411591129 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9835 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wednesday, September 24, 2014 12:08:40 Emmanuel Florac wrote: > Le Tue, 23 Sep 2014 15:02:57 -0700 >=20 > Diane Trout =E9crivait: > > I had a raid failure at work that ended up corrupting an xfs > > filesystem the tail of the xfs_repair command looks like the below.= I > > was able to generate a metadata dump but is there a point to making= > > it available? > >=20 > > It does crash repeatedly at the same place >=20 > Did you try the very latest xfs_repair? I grabbed the one out of debian unstable (3.2.1), verified that it was = your=20 latest release and used that. I didn't try building the version in git.= It did get much further than version 3.1.7+b1 (debian stable) Diane Phase 6 - check inode connectivity... - resetting contents of realtime bitmap and summary inodes - traversing filesystem ... entry "lymphoblastoid" in dir ino 256 doesn't have a .. entry, will set= it in=20 ino 2051. bad hash table for directory inode 256 (no data entry): rebuilding rebuilding directory inode 256 7f70c79c8700: Badness in key lookup (length) bp=3D(bno 0x3480, len 4096 bytes) key=3D(bno 0x3480, len 8192 bytes) Metadata corruption detected at block 0x4000070/0x1000 xfs_da_do_buf(2): XFS_CORRUPTION_ERROR fatal error -- can't read block 8388608 for directory inode 259, error = 117 From sandeen@sandeen.net Wed Sep 24 15:57:54 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2CB2E7F61 for ; Wed, 24 Sep 2014 15:57:54 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 077988F804C for ; Wed, 24 Sep 2014 13:57:53 -0700 (PDT) X-ASG-Debug-ID: 1411592272-04bdf003a11451a0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id ctY68HqWcpNmXHh5 for ; Wed, 24 Sep 2014 13:57:52 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 2B0F160F9684; Wed, 24 Sep 2014 15:57:52 -0500 (CDT) Message-ID: <54233051.4070709@sandeen.net> Date: Wed, 24 Sep 2014 15:57:53 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Diane Trout CC: xfs-oss Subject: Re: Corrupted file system References: <5839367.DyqsVHbRuQ@myrada> <20140924120840.1be78240@harpe.intellique.com> <705802842.F0QjhfVGQR@myrada> X-ASG-Orig-Subj: Re: Corrupted file system In-Reply-To: <705802842.F0QjhfVGQR@myrada> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1411592272 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9836 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- If you want to make a metadata image, compress it, and send it my way I'd be glad to look at it - I've been doing some repair work lately. -Eric On 9/24/14 3:38 PM, Diane Trout wrote: > On Wednesday, September 24, 2014 12:08:40 Emmanuel Florac wrote: >> Le Tue, 23 Sep 2014 15:02:57 -0700 >> >> Diane Trout écrivait: >>> I had a raid failure at work that ended up corrupting an xfs >>> filesystem the tail of the xfs_repair command looks like the below. I >>> was able to generate a metadata dump but is there a point to making >>> it available? >>> >>> It does crash repeatedly at the same place >> >> Did you try the very latest xfs_repair? > > > I grabbed the one out of debian unstable (3.2.1), verified that it was your > latest release and used that. I didn't try building the version in git. > > It did get much further than version 3.1.7+b1 (debian stable) > > Diane > > Phase 6 - check inode connectivity... > - resetting contents of realtime bitmap and summary inodes > - traversing filesystem ... > entry "lymphoblastoid" in dir ino 256 doesn't have a .. entry, will set it in > ino 2051. > bad hash table for directory inode 256 (no data entry): rebuilding > rebuilding directory inode 256 > 7f70c79c8700: Badness in key lookup (length) > bp=(bno 0x3480, len 4096 bytes) key=(bno 0x3480, len 8192 bytes) > Metadata corruption detected at block 0x4000070/0x1000 > xfs_da_do_buf(2): XFS_CORRUPTION_ERROR > > fatal error -- can't read block 8388608 for directory inode 259, error 117 > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs > From david@fromorbit.com Wed Sep 24 18:10:38 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B8DD67F60 for ; Wed, 24 Sep 2014 18:10:38 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id A7371304053 for ; Wed, 24 Sep 2014 16:10:35 -0700 (PDT) X-ASG-Debug-ID: 1411600228-04cb6c50e4136090001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id e4JlouqcE72UD8Wy for ; Wed, 24 Sep 2014 16:10:29 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AukdACROI1R5LHimPGdsb2JhbABggw5TtmMGlDKBYYVqBAIBgQwXAQYBAQEBODiEAwEBAQMBOg0PIwULCAMYCSUPBSUDBxoTGYgdBw6zNpB8ARcYhXqKDAeDLoEdBZ0gjDaLCh6BaysvgkoBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail06.adl2.internode.on.net with ESMTP; 25 Sep 2014 08:40:27 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XWvhY-0004up-LD; Thu, 25 Sep 2014 09:10:24 +1000 Date: Thu, 25 Sep 2014 09:10:24 +1000 From: Dave Chinner To: Olaf Weber Cc: Ben Myers , linux-fsdevel@vger.kernel.org, tinguely@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140924231024.GA4758@dastard> X-ASG-Orig-Subj: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <20140922222611.GZ4322@dastard> <5422C540.1060007@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5422C540.1060007@sgi.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1411600228 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9839 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Sep 24, 2014 at 03:21:04PM +0200, Olaf Weber wrote: > On 23-09-14 00:26, Dave Chinner wrote: > >On Thu, Sep 18, 2014 at 02:56:50PM -0500, Ben Myers wrote: > > [...] > > >>TODO: Store the unicode version number of the filesystem on disk in the > >>super block. > > > >So, if the filesystem has to store the specific unicode version it > >was created with so that we know what version to put in trie > >lookups, again I'll ask: why are we loading the trie as a generic > >kernel module and not as metadata in the filesystem that is demand > >paged and cached? > > This way the trie can be shared, and the code using it is not > entangled with the XFS code. The trie parsing code can still be common - just the location and contents of the data is determined by the end-user. > > >i.e. put the entire trie on disk, look up the specific conversion > >required for the name being compared, and then cache that conversion > >in memory. This makes repeated lookups much faster because the trie > >only contains conversions that are in use, the memory footprint is > >way lower and the conversions are guaranteed to be consistent for > >the life of the filesystem.... > > Above you mention demand paging parts of the trie, but here you seem > to suggest creating an in-core conversion table on the fly from data > read from disk. The former seems a lot easier to do than the latter. Right - it's a question of what needs optimising. If people are only concerned about memory footprint, then demand paging solves that problem. If people are concerned about performance and memory footprint, then demand paging plus a lookaside cache will address both of those aspects. We can't do demand paging if the trie data is built into the kernel. We can still do a lookaside cache to avoid performane issues with repeated trie lookups... [...] > >>To support unicode we have to interpret filenames. What happens when > >>(part of) a filename cannot be interpreted? We can reject the > >>filename, interpret the parts we can, or punt and accept it as an > >>uninterpreted blob. > >> > >>Rejecting ill-formed filenames was my first choice, but I came around > >>on the issue: there are too many ways in which you can end up with > >>having to deal with ill-formed filenames that would leave a user with > >>no recourse but to move whatever they're doing to a different > >>filesystem. Unpacking a tarball with filenames in a different encoding > >>is an example. > > > >You still haven't addressed this: > > > >| So we accept invalid unicode in filenames, but only after failing to > >| parse them? Isn't this a potential vector for exploiting weaknesses > >| in application filename handling? i.e. unprivileged user writes > >| specially crafted invalid unicode filename to disk, setuid program > >| tries to parse it, invalid sequence triggers a buffer overflow bug > >| in setuid parser? > > > >apart from handwaving that userspace has to be able to handle > >invalid utf-8 already. Why should we let filesystems say "we fully > >understand and support utf8" and then allow them to accept and > >propagate invalid utf8 sequences and leave everyone else to have to > >clean up the mess? > > Because the alternative amounts in my opinion to a demand that every > bit of userspace that may be involved in generating filenames > generate only clean UTF-8. I do not believe that this is a realistic > demand at this point in time. It's a chicken and egg situation. I'd much prefer we enforce clean utf8 from the start, because if we don't we'll never be able to do that. And other filesystems (e.g. ZFS) allow you to do reject anything that is not clean utf8.... [...] > >>When comparing well-formed filenames, the question now becomes which > >>byte sequences are considered to be alternative spellings of the same > >>filename. This is where normalization forms come into play, and the > >>unicode standard has quite a bit to say about the subject. > >> > >>If all you're doing is comparison, then choosing NFD over NFC is easy, > >>because the former is easier to calculate than the latter. > >> > >>If you want various spellings of "office" to compare equal, then > >>picking NFKD over NFD for comparison is also an obvious > >>choice. (Hand-picking individual compatibility forms is truly a bad > >>idea.) Ways to spell "office": "o_f_f_i_c_e", "o_f_fi_c_e", and > >>"o_ffi_c_e", using no ligatures, the fi ligature, or the ffi > >>ligature. (Some fool thought it a good idea to add these ligatures to > >>unicode, all we get to decide is how to cope.) > > > >Yet normalised strings are only stable and hence comparable > >if there are no unassigned code points in them. What happens when > >userspace is not using the same version of unicode as the > >filesystem and is using newer code points in it's strings? > >Normalisation fails, right? > > For the newer code points, yes. This is not treated as a failure to > normalize the string as a whole, as there are clear guidelines in > unicode on how unassigned code points interact with normalization: > they have canonical combining class 0 and no decomposition. And so effectively are not stable. Which is something we absolutely have to avoid for information stored on disk. i.e. you're using the normalised form to build the hash values in the lookup index in the directory structure, and so having unstable normalisation forms is just wrong. Hence we'd need to reject anything with unassigned code points.... > >And as an extension of using normalisation for case-folded > >comparisons, how do we make case folding work with blobs that can't > >be normalised? It seems to me that this just leads to the nasty > >situation where some filenames are case sensitive and some aren't > >based on what the filesystem thinks is valid utf-8. The worst part > >is that userspace has no idea that the filesystem is making such > >distinctions and so behaviour is not at all predictable or expected. > > Making case-folding work on a blob that cannot be normalized is (in > my opinion) akin to doing an ASCII-based casefold on a Shift-JIS > string: the result is neither pretty nor useful. Yes, that's exactly my point. > >This is another point in favour of rejecting invalid utf-8 strings > >and for keeping the translation tables stable within the > >filesystem... > > Bear in mind that this means not just rejecting invalid UTF-8 > strings, but also rejecting valid UTF-8 strings that encode > unassigned code points. And that's precisely what I'm suggesting: If we can't normalise the filename to a stable form then it cannot be used for hashing or case folding. That means it needs to be rejected, not treated as an opaque blob. The moment we start parsing filenames they are no longer opaque blobs and so all existing "filename are opaque blobs" handling rules go out the window. They are now either valid so we can use them, or they are invalid and need to be rejected to avoid unpredictable and/or undesirable behaviour. > This should be easy to implement if it is decided that we want to do this. > > >>The most contentious part is (should be) ignoring the codepoints with > >>the Default_Ignorable_Code_Point property. I've included the list > >>below. My argument, such as it is, is that these code points either > >>have no visible rendering, or in cases like the soft hyphen, are only > >>conditionally visible. The problem with these (as I see it) is that on > >>seeing a filename that might contain them you cannot tell whether they > >>are present. So I propose to ignore them for the purpose of comparing > >>filenames for equality. > > > >Which introduces a non-standard "visibility criterial" for > >determining what should be or shouldn't be part of the normalised > >string for comparison. I don't see any real justification for > >stepping outside the standard unicode normalisation here - just > >because the user cannot see a character in a specific context does > >not mean that it is not significant to the application that created > >it. > > I agree these characters may be significant to the application. I'm > just not convinced that they should be significant in a file name. They are significant to the case folding result, right? And therefore would be significant in a filename... > > >>Finally, case folding. First of all, it is optional. Then the issue is > >>that you either go the language-specific route, or simplify the task > >>by "just" doing a full casefold (C+F, in unicode parlance). Looking > >>around the net I tend to find that if you're going to do casefolding > >>at all, then a language-independent full casefold is preferred because > >>it is the most predictable option. See > >>http://www.w3.org/TR/charmod-norm/ for an example of that kind of > >>reasoning. > > > >Which says in section 2.4: "Some languages need case-folding to be > >tailored to meet specific linguistic needs". That implies that the > >case folding needs to be language aware and hence needs to be tied > >into the NLS subsystem for handling specific quirks like Turkic. > > It also recommends just doing a full case fold for cases where you > are ignorant of the language actually in use. In section 3.1 they > say: "However, language-sensitive case-sensitive matching in > document formats and protocols is NOT RECOMMENDED because language > information can be hard to obtain, verify, or manage and the > resulting operations can produce results that frustrate users." This > doesn't exactly address the case of filesystems, but as far as I > know there is no defined interface that allows kernel code to query > the locale settings that currently apply to a userspace process. Hence my comments about NLS integration. The NLS subsystem already has utf8 support with language dependent case folding tables. All the current filesystems that deal with unicode (including case folding) use the NLS subsystem for conversions. Hmmm - looking at all the NLS code that does different utf format conversions first: what happens if an application is using UTF16 or UTF32 for it's filename encoding rather than utf8? > >>* XFS-specific design notes. > >... > >>If the borgbit (the bit enabling legacy ASCII-based CI in XFS) is set > >>in the superblock, then case folding is added into the mix. This is > >>the nfkdicf normalization form mentioned above. It allows for the > >>creation of case-insensitive filesystems with UTF-8 support. > > > >Please don't overload existing superblock feature bits with multiple > >meanings. ASCII-CI is a stand-alone feature and is not in any way > >compatible with Unicode: Unicode-CI is a superset of Unicode > >support. So it really needs two new feature bits for Unicode and > >Unicode-CI, not just one for unicode. > > It seemed an obvious extension of the meaning of that bit. Feature bits refer to a specific on disk format feature. If that bit is set, then that feature is present. In this case, it means the filesystem is using ascii-ci. If that bit is passed out to userspace via the geometry ioctl, then *existing applications* expect it to mean ascii-ci behaviour from the filesystem. If an existing utility reads the flag field from disk (e.g. repair, metadump, db, etc) they all expect it to mean ascii-ci, and will do stuff based on that specific meaning. We cannot redefine the meaning of a feature bit after the fact - we have lots of feature bits so there's no need to overload an existing one for this. Hmmm - another interesting question just popped into my head about metadump: file name obfuscation. What does unicode and utf8 mean for the hash collision calculation algorithm? Cheers, Dave. -- Dave Chinner david@fromorbit.com From bpm@sgi.com Wed Sep 24 18:11:46 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 146E67F61 for ; Wed, 24 Sep 2014 18:11:46 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id DD3C98F8035; Wed, 24 Sep 2014 16:11:45 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 9F6964266DC; Wed, 24 Sep 2014 18:11:45 -0500 (CDT) Date: Wed, 24 Sep 2014 18:11:45 -0500 From: Ben Myers To: Roger Willcocks Cc: linux-fsdevel@vger.kernel.org, tinguely@sgi.com, olaf@sgi.com, xfs@oss.sgi.com Subject: Re: [PATCH 07a/13] xfsprogs: add trie generator for UTF-8. Message-ID: <20140924231145.GK4482@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140918203114.GN4482@sgi.com> <20140919160612.GF4482@sgi.com> <1411497259.4842.163.camel@localhost.localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411497259.4842.163.camel@localhost.localdomain> User-Agent: Mutt/1.5.20 (2009-06-14) Hi Roger, On Tue, Sep 23, 2014 at 07:34:19PM +0100, Roger Willcocks wrote: > On Fri, 2014-09-19 at 11:06 -0500, Ben Myers wrote: > > +#define AGE_NAME "DerivedAge.txt" > > +#define CCC_NAME "DerivedCombiningClass.txt" > > +#define PROP_NAME "DerivedCoreProperties.txt" > > +#define DATA_NAME "UnicodeData.txt" > > +#define FOLD_NAME "CaseFolding.txt" > > +#define NORM_NAME "NormalizationCorrections.txt" > > +#define TEST_NAME "NormalizationTest.txt" > > Is there a reason why you're using multiple text-based data files (and > hand-parsing them) when there's an xml formatted flat file available ? > > http://www.unicode.org/Public/UCD/latest/ucdxml/ The UCD files being parsed are the authoritative source. Check out ucdxml.readme.txt. > And a 2nd question - why does the trie need to encode "the the unicode > version in which the codepoint was assigned an interpretation" ? You need to know whether a given code point is assigned in the version of Unicode you're normalizing for. Unicode 8 is supposed to release June/July 2015 (see http://www.unicode.org/versions/), but filesystems you created this year will still need the version 7 normalization. There is still some plumbing to do to pass the version along with the string for normalization. I think you bring up a good point, but we'll need to support multiple versions in the long run. Regards, Ben From david@fromorbit.com Wed Sep 24 18:30:23 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 7C92F7F63 for ; Wed, 24 Sep 2014 18:30:23 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6A2718F8033 for ; Wed, 24 Sep 2014 16:30:22 -0700 (PDT) X-ASG-Debug-ID: 1411601416-04cbb07301143b80001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id p3JSW5bH22nXxv9X for ; Wed, 24 Sep 2014 16:30:17 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ag1ZANpSI1R5LHimPGdsb2JhbABggw5Tjj6oJQaUNoFdhWoCAgEBAYEMFwEGAQEBATg4hAMBAQEDAScTHCMQCAMOCgklDwUlAwcaE4g2Bw7EMRgYhXqHeYFGTQeDLoEdBZYYhwiZSSsvAYEGgUMBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail06.adl2.internode.on.net with ESMTP; 25 Sep 2014 09:00:15 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XWw0k-0004x5-F8; Thu, 25 Sep 2014 09:30:14 +1000 Date: Thu, 25 Sep 2014 09:30:14 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [RFC PATCH] xfs: borrow indirect blocks from freed extent when available Message-ID: <20140924233014.GB4758@dastard> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: borrow indirect blocks from freed extent when available References: <1411500538-6831-1-git-send-email-bfoster@redhat.com> <20140923215816.GC4322@dastard> <20140924122746.GA53094@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140924122746.GA53094@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1411601416 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9840 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Sep 24, 2014 at 08:27:46AM -0400, Brian Foster wrote: > On Wed, Sep 24, 2014 at 07:58:16AM +1000, Dave Chinner wrote: > > On Tue, Sep 23, 2014 at 03:28:58PM -0400, Brian Foster wrote: > > > xfs_bmap_del_extent() handles extent removal from the in-core and > > > on-disk extent lists. When removing a delalloc range, it updates the > > > indirect block reservation appropriately based on the removal. It > > > currently enforces that the new indirect block reservation is less than > > > or equal to the original. This is normally the case in all situations > > > except for when the removed range creates a hole in a single delalloc > > > extent, thus splitting a single delalloc extent in two. > > > > > > The indirect block reservation is divided evenly between the two new > > > extents in this scenario. However, it is possible with small enough > > > extents to split an indlen==1 extent into two such slightly smaller > > > extents. This leaves one extent with 0 indirect blocks and leads to > > > assert failures in other areas (e.g., xfs_bunmapi() if the extent > > > happens to be removed). > > > > I had long suspected we had an issue in this code, but was never > > able to nail down a reproducer that triggered it. Do you have a > > reproducer, or did you find this by reading/tracing the code? > > > > I have a setup on which fsx reproduces an instance of this within a few > minutes consistently. It looks like the same sequence of events each > occurrence so I can try to derive a more specific test case for it. I > suspect the right sequence of delayed allocation followed by hole > punching or zeroing should be able to trigger it. *nod* > > > Refactor xfs_bunmapi() to make the updates that must be consistent > > > against the inode (e.g., delalloc block counter, quota reservation) > > > right before the extent is deleted. Move the sb block counter update > > > after the extent is deleted and update xfs_bmap_del_extent() to steal > > > some blocks from the freed extent if a larger overall indirect > > > reservation is required by the extent removal. > > > > > > Signed-off-by: Brian Foster > > > --- > > > > > > Hi all, > > > > > > I'm seeing the following assert more frequently with fsx and the recent > > > xfs_free_file_space() changes (at least on 1k fsb fs'): > > > > > > XFS: Assertion failed: startblockval(del.br_startblock) > 0, file: fs/xfs/libxfs/xfs_bmap.c, line: 5281 > > > > > > This occurs for the reason described in the commit log description. This > > > is a quick experiment I wanted to test to verify the problem goes away > > > (so far, so good). Very lightly tested so far. > > > > I suspect it's also the cause of these occasional assert failures > > that I see: > > > > XFS: Assertion failed: tp->t_blk_res_used <= tp->t_blk_res, file: fs/xfs/xfs_trans.c, line: 327 > > > > during delalloc conversion because there wasn't a space reservation > > for the blocks allocated (i.e. indlen was zero) and so we overrun > > the transaction block reservation. > > > > Interesting, I've seen this as well though I'll have to go back and see > where I was getting it from. I did run fsx overnight without any assert > failures at all, which seems rare lately. ;) I wasn't running my usual > parallel fsstress however. I've started that and I reproduce an instance > of that assert failure within a few minutes, so if related it appears > this might not be the only contributer. I'll look more into that one > next. I knew I'd looked at this before: http://oss.sgi.com/archives/xfs/2014-03/msg00314.html That got lost because I wrote it in a topic branch and not my usual working branch, so when I dropped the topic branch. Guilt, however, keeps all the patches from topic branches around, and so when I just did a grep for da_new across .git/patch, this showed up. It's basically the same "steal blocks from the deleted extent reservation fix, and it was trying to address the above failure. However, there are some other details in it (like changing the location of delalloc accounting updates) that might be relevant. I'm pretty sure the test case was simply something like: xfs_io -f -c "pwrite 0 1m" \ -c "fzero 4k 8k" \ -c "fzero 16k 8k" \ -c "fzero 32k 8k" \ -c "fzero 64k 8k" \ ..... To basically split the delalloc extent repeatedly and hence drain the reservation. Cheers, Dave. -- Dave Chinner david@fromorbit.com From dave@fromorbit.com Wed Sep 24 18:37:49 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id CCBCA7F6B for ; Wed, 24 Sep 2014 18:37:49 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id AA0E08F8033 for ; Wed, 24 Sep 2014 16:37:49 -0700 (PDT) X-ASG-Debug-ID: 1411601867-04cb6c50e6137040001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id i7hiyylQx1ASrz7Z for ; Wed, 24 Sep 2014 16:37:47 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ArIVADdVI1R5LHimPGdsb2JhbABggw6IYq5UBp0QFwEGAQEBATg4hGA7gQIDB4hqnlemAIYSiimENQW0OwGCLSuCeQEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail06.adl2.internode.on.net with ESMTP; 25 Sep 2014 09:07:46 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XWw81-0004yD-JJ for xfs@oss.sgi.com; Thu, 25 Sep 2014 09:37:45 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XWw81-00056g-ID for xfs@oss.sgi.com; Thu, 25 Sep 2014 09:37:45 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 0/4] xfs: sparse fixes Date: Thu, 25 Sep 2014 09:37:39 +1000 X-ASG-Orig-Subj: [PATCH 0/4] xfs: sparse fixes Message-Id: <1411601863-19594-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1411601867 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9840 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi folks, In gathering up the outstanding sparse warning fixes, these are the ones that went unnoticed or didn't have patches for them. The first patch fixes an actual bug, though one with almost no impact on performance and no impact on correctness. The others are just cleanups to remove warnings from correctly functioning code. Cheers, Dave. From dave@fromorbit.com Wed Sep 24 18:37:51 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 357797F6B for ; Wed, 24 Sep 2014 18:37:51 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id C6E91AC004 for ; Wed, 24 Sep 2014 16:37:50 -0700 (PDT) X-ASG-Debug-ID: 1411601867-04cb6c50e6137040002-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id Bi6chVioV6tXUK63 for ; Wed, 24 Sep 2014 16:37:49 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ArUVADdVI1R5LHimPGdsb2JhbABggw6IYq5UBp0QFwEGAQEBATg4hAQBBVYzCBgxOQMHFBmIPcRXhhKKKYQ1BY9GmhSNDysvgkoBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail06.adl2.internode.on.net with ESMTP; 25 Sep 2014 09:07:46 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XWw81-0004yF-KO for xfs@oss.sgi.com; Thu, 25 Sep 2014 09:37:45 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XWw81-00056o-JR for xfs@oss.sgi.com; Thu, 25 Sep 2014 09:37:45 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 2/4] xfs: xfs_qm_dquot_isolate needs locking annotations for sparse Date: Thu, 25 Sep 2014 09:37:41 +1000 X-ASG-Orig-Subj: [PATCH 2/4] xfs: xfs_qm_dquot_isolate needs locking annotations for sparse Message-Id: <1411601863-19594-3-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411601863-19594-1-git-send-email-david@fromorbit.com> References: <1411601863-19594-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1411601868 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9840 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner To remove noise from the build. Signed-off-by: Dave Chinner --- fs/xfs/xfs_qm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 1023210..d68f230 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -434,6 +434,7 @@ xfs_qm_dquot_isolate( struct list_head *item, spinlock_t *lru_lock, void *arg) + __releases(lru_lock) __acquires(lru_lock) { struct xfs_dquot *dqp = container_of(item, struct xfs_dquot, q_lru); -- 2.0.0 From dave@fromorbit.com Wed Sep 24 18:37:51 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id F0A197F74 for ; Wed, 24 Sep 2014 18:37:51 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id DE75F8F8033 for ; Wed, 24 Sep 2014 16:37:51 -0700 (PDT) X-ASG-Debug-ID: 1411601867-04cb6c50e6137040003-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id gQaPxXnmPyy7BE1n for ; Wed, 24 Sep 2014 16:37:50 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ArUVADdVI1R5LHimPGdsb2JhbABggw6IYq5UBp0QFwEGAQEBATg4hAQBBVYzCBgxOQMHFBmIPcRXhhKKKYQ1BbZpKy+CSgEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail06.adl2.internode.on.net with ESMTP; 25 Sep 2014 09:07:46 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XWw81-0004yH-Lp for xfs@oss.sgi.com; Thu, 25 Sep 2014 09:37:45 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XWw81-00056y-Kl for xfs@oss.sgi.com; Thu, 25 Sep 2014 09:37:45 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 4/4] xfs: annotate user variables passed as void Date: Thu, 25 Sep 2014 09:37:43 +1000 X-ASG-Orig-Subj: [PATCH 4/4] xfs: annotate user variables passed as void Message-Id: <1411601863-19594-5-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411601863-19594-1-git-send-email-david@fromorbit.com> References: <1411601863-19594-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1411601870 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9840 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner Some argument callbacks can contain user buffers, and sparse warns about passing them as void pointers. Cast appropriately to remove the sparse warnings. Signed-off-by: Dave Chinner --- fs/xfs/xfs_ioctl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 3799695..7a6b406 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -1349,7 +1349,7 @@ xfs_ioc_setxflags( STATIC int xfs_getbmap_format(void **ap, struct getbmapx *bmv, int *full) { - struct getbmap __user *base = *ap; + struct getbmap __user *base = (struct getbmap __user *)*ap; /* copy only getbmap portion (not getbmapx) */ if (copy_to_user(base, bmv, sizeof(struct getbmap))) @@ -1380,7 +1380,7 @@ xfs_ioc_getbmap( bmx.bmv_iflags |= BMV_IF_NO_DMAPI_READ; error = xfs_getbmap(ip, &bmx, xfs_getbmap_format, - (struct getbmap *)arg+1); + (__force struct getbmap *)arg+1); if (error) return error; @@ -1393,7 +1393,7 @@ xfs_ioc_getbmap( STATIC int xfs_getbmapx_format(void **ap, struct getbmapx *bmv, int *full) { - struct getbmapx __user *base = *ap; + struct getbmapx __user *base = (struct getbmapx __user *)*ap; if (copy_to_user(base, bmv, sizeof(struct getbmapx))) return -EFAULT; @@ -1420,7 +1420,7 @@ xfs_ioc_getbmapx( return -EINVAL; error = xfs_getbmap(ip, &bmx, xfs_getbmapx_format, - (struct getbmapx *)arg+1); + (__force struct getbmapx *)arg+1); if (error) return error; -- 2.0.0 From dave@fromorbit.com Wed Sep 24 18:37:52 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 7050D7F74 for ; Wed, 24 Sep 2014 18:37:52 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id F2FE0AC004 for ; Wed, 24 Sep 2014 16:37:51 -0700 (PDT) X-ASG-Debug-ID: 1411601869-04cb6c50e4137040001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id 1DpYRzeD386ctHM3 for ; Wed, 24 Sep 2014 16:37:49 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ArUVADdVI1R5LHimPGdsb2JhbABggw6IYq5UBp0QFwEGAQEBATg4hAQBBScvMwhJOQMHFBmIPcRXhhKKKYQ1BZhWkQSNDysvgkoBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail06.adl2.internode.on.net with ESMTP; 25 Sep 2014 09:07:46 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XWw81-0004yE-Ju for xfs@oss.sgi.com; Thu, 25 Sep 2014 09:37:45 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XWw81-00056j-Iq for xfs@oss.sgi.com; Thu, 25 Sep 2014 09:37:45 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 1/4] xfs: fix use of agi_newino in finobt lookup Date: Thu, 25 Sep 2014 09:37:40 +1000 X-ASG-Orig-Subj: [PATCH 1/4] xfs: fix use of agi_newino in finobt lookup Message-Id: <1411601863-19594-2-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411601863-19594-1-git-send-email-david@fromorbit.com> References: <1411601863-19594-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1411601869 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9840 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Sparse warns that we are passing the big-endian valueo f agi_newino to the initial btree lookup function when trying to find a new inode. This is wrong - we need to pass the host order value, not the disk order value. This will adversely affect the next inode allocated, but given that the free inode btree is usually much smaller than the allocated inode btree it is much less likely to be a performance issue if we start the search in the wrong place. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_ialloc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index d213a2e..23dcb72 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -1076,8 +1076,8 @@ xfs_dialloc_ag_finobt_newino( int i; if (agi->agi_newino != cpu_to_be32(NULLAGINO)) { - error = xfs_inobt_lookup(cur, agi->agi_newino, XFS_LOOKUP_EQ, - &i); + error = xfs_inobt_lookup(cur, be32_to_cpu(agi->agi_newino), + XFS_LOOKUP_EQ, &i); if (error) return error; if (i == 1) { @@ -1085,7 +1085,6 @@ xfs_dialloc_ag_finobt_newino( if (error) return error; XFS_WANT_CORRUPTED_RETURN(i == 1); - return 0; } } -- 2.0.0 From dave@fromorbit.com Wed Sep 24 18:37:53 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 03ACE7F82 for ; Wed, 24 Sep 2014 18:37:53 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id C88A6304039 for ; Wed, 24 Sep 2014 16:37:52 -0700 (PDT) X-ASG-Debug-ID: 1411601870-04bdf003a014c3b0001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id KHbiuVYRaSyhVOw4 for ; Wed, 24 Sep 2014 16:37:51 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ArUVADdVI1R5LHimPGdsb2JhbABggw6IYq5UBp0QFwEGAQEBATg4hAQBBScvMwgYMTkDBxQZiD3EV4YSiimENQWpWo0PKy+CSgEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail06.adl2.internode.on.net with ESMTP; 25 Sep 2014 09:07:46 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XWw81-0004yG-LJ for xfs@oss.sgi.com; Thu, 25 Sep 2014 09:37:45 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XWw81-00056t-Ju for xfs@oss.sgi.com; Thu, 25 Sep 2014 09:37:45 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 3/4] xfs: xfs_kset should be static Date: Thu, 25 Sep 2014 09:37:42 +1000 X-ASG-Orig-Subj: [PATCH 3/4] xfs: xfs_kset should be static Message-Id: <1411601863-19594-4-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411601863-19594-1-git-send-email-david@fromorbit.com> References: <1411601863-19594-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1411601870 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9840 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner As it is accessed through the struct xfs_mount and can be set up entirely from fs/xfs/xfs_super.c Signed-off-by: Dave Chinner --- fs/xfs/xfs_mount.c | 3 --- fs/xfs/xfs_super.c | 3 ++- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index fbf0384..d36bdbc 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -61,8 +61,6 @@ static DEFINE_MUTEX(xfs_uuid_table_mutex); static int xfs_uuid_table_size; static uuid_t *xfs_uuid_table; -extern struct kset *xfs_kset; - /* * See if the UUID is unique among mounted XFS filesystems. * Mount fails if UUID is nil or a FS with the same UUID is already mounted. @@ -729,7 +727,6 @@ xfs_mountfs( xfs_set_maxicount(mp); - mp->m_kobj.kobject.kset = xfs_kset; error = xfs_sysfs_init(&mp->m_kobj, &xfs_mp_ktype, NULL, mp->m_fsname); if (error) goto out; diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index dcd4b93..9f622fe 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -63,7 +63,7 @@ static const struct super_operations xfs_super_operations; static kmem_zone_t *xfs_ioend_zone; mempool_t *xfs_ioend_pool; -struct kset *xfs_kset; /* top-level xfs sysfs dir */ +static struct kset *xfs_kset; /* top-level xfs sysfs dir */ #ifdef DEBUG static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */ #endif @@ -1411,6 +1411,7 @@ xfs_fs_fill_super( atomic_set(&mp->m_active_trans, 0); INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker); INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker); + mp->m_kobj.kobject.kset = xfs_kset; mp->m_super = sb; sb->s_fs_info = mp; -- 2.0.0 From diane@caltech.edu Wed Sep 24 19:25:32 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 832F77F76 for ; Wed, 24 Sep 2014 19:25:32 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2FC67AC002 for ; Wed, 24 Sep 2014 17:25:29 -0700 (PDT) X-ASG-Debug-ID: 1411604727-04bdf003a114e8d0001-NocioJ Received: from chaos.caltech.edu (chaos.caltech.edu [131.215.34.119]) by cuda.sgi.com with ESMTP id Ef7HBpce5xxBaFdS (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO) for ; Wed, 24 Sep 2014 17:25:28 -0700 (PDT) X-Barracuda-Envelope-From: diane@caltech.edu X-Barracuda-Apparent-Source-IP: 131.215.34.119 Received: from dhcp-54-193.caltech.edu ([131.215.54.193] helo=myrada.localnet) by chaos.caltech.edu with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.80) (envelope-from ) id 1XWwsB-00030d-8a; Wed, 24 Sep 2014 17:25:27 -0700 From: Diane Trout To: Eric Sandeen Cc: xfs-oss Subject: Re: Corrupted file system Date: Wed, 24 Sep 2014 17:25:12 -0700 X-ASG-Orig-Subj: Re: Corrupted file system Message-ID: <2047180.98c6Ryq0NE@myrada> User-Agent: KMail/4.14 (Linux/3.14-2-amd64; KDE/4.14.1; x86_64; ; ) In-Reply-To: <54233051.4070709@sandeen.net> References: <5839367.DyqsVHbRuQ@myrada> <705802842.F0QjhfVGQR@myrada> <54233051.4070709@sandeen.net> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="iso-8859-1" X-Barracuda-Connect: chaos.caltech.edu[131.215.34.119] X-Barracuda-Start-Time: 1411604728 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9842 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Huh. I'd managed to make a metadump using the 3.1.7 version of the tools. Th= en I=20 tried to run xfs_repair on the partition, and now xfs_metadump is segfa= ulting=20 on the partition. Would the older metadata dump be useful? I'd need to rebuild xfsprogs before the stack trace would be useful... = debian=20 likes to strip the symbols and they didn't make a -dbg package. Diane On Wednesday, September 24, 2014 15:57:53 Eric Sandeen wrote: > If you want to make a metadata image, compress it, and send it my way= I'd be > glad to look at it - I've been doing some repair work lately. >=20 > -Eric >=20 > On 9/24/14 3:38 PM, Diane Trout wrote: > > On Wednesday, September 24, 2014 12:08:40 Emmanuel Florac wrote: > >> Le Tue, 23 Sep 2014 15:02:57 -0700 > >>=20 > >> Diane Trout =E9crivait: > >>> I had a raid failure at work that ended up corrupting an xfs > >>> filesystem the tail of the xfs_repair command looks like the belo= w. I > >>> was able to generate a metadata dump but is there a point to maki= ng > >>> it available? > >>>=20 > >>> It does crash repeatedly at the same place > >>=20 > >> Did you try the very latest xfs_repair? > >=20 > > I grabbed the one out of debian unstable (3.2.1), verified that it = was > > your > > latest release and used that. I didn't try building the version in = git. > >=20 > > It did get much further than version 3.1.7+b1 (debian stable) > >=20 > > Diane > >=20 > > Phase 6 - check inode connectivity... > >=20 > > - resetting contents of realtime bitmap and summary inodes > > - traversing filesystem ... > >=20 > > entry "lymphoblastoid" in dir ino 256 doesn't have a .. entry, will= set it > > in ino 2051. > > bad hash table for directory inode 256 (no data entry): rebuilding > > rebuilding directory inode 256 > > 7f70c79c8700: Badness in key lookup (length) > > bp=3D(bno 0x3480, len 4096 bytes) key=3D(bno 0x3480, len 8192 bytes= ) > > Metadata corruption detected at block 0x4000070/0x1000 > > xfs_da_do_buf(2): XFS_CORRUPTION_ERROR > >=20 > > fatal error -- can't read block 8388608 for directory inode 259, er= ror 117 > >=20 > >=20 > > _______________________________________________ > > xfs mailing list > > xfs@oss.sgi.com > > http://oss.sgi.com/mailman/listinfo/xfs From sandeen@sandeen.net Wed Sep 24 19:50:26 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E76607F78 for ; Wed, 24 Sep 2014 19:50:25 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 656E1AC004 for ; Wed, 24 Sep 2014 17:50:25 -0700 (PDT) X-ASG-Debug-ID: 1411606223-04cb6c50e413a0b0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id m0GbEEXuYcQfboHY for ; Wed, 24 Sep 2014 17:50:23 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 9A1DD608F745; Wed, 24 Sep 2014 19:50:23 -0500 (CDT) Message-ID: <542366CF.3040905@sandeen.net> Date: Wed, 24 Sep 2014 19:50:23 -0500 From: Eric Sandeen MIME-Version: 1.0 To: Diane Trout CC: xfs-oss Subject: Re: Corrupted file system References: <5839367.DyqsVHbRuQ@myrada> <705802842.F0QjhfVGQR@myrada> <54233051.4070709@sandeen.net> <2047180.98c6Ryq0NE@myrada> X-ASG-Orig-Subj: Re: Corrupted file system In-Reply-To: <2047180.98c6Ryq0NE@myrada> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1411606223 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9843 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/24/14 7:25 PM, Diane Trout wrote: > Huh. > > I'd managed to make a metadump using the 3.1.7 version of the tools. Then I > tried to run xfs_repair on the partition, and now xfs_metadump is segfaulting > on the partition. > > Would the older metadata dump be useful? sure. Compress it & send me a private note with it attached (or with a location if it's too big to email) -Eric > I'd need to rebuild xfsprogs before the stack trace would be useful... debian > likes to strip the symbols and they didn't make a -dbg package. > > Diane > > On Wednesday, September 24, 2014 15:57:53 Eric Sandeen wrote: >> If you want to make a metadata image, compress it, and send it my way I'd be >> glad to look at it - I've been doing some repair work lately. >> >> -Eric >> >> On 9/24/14 3:38 PM, Diane Trout wrote: >>> On Wednesday, September 24, 2014 12:08:40 Emmanuel Florac wrote: >>>> Le Tue, 23 Sep 2014 15:02:57 -0700 >>>> >>>> Diane Trout écrivait: >>>>> I had a raid failure at work that ended up corrupting an xfs >>>>> filesystem the tail of the xfs_repair command looks like the below. I >>>>> was able to generate a metadata dump but is there a point to making >>>>> it available? >>>>> >>>>> It does crash repeatedly at the same place >>>> >>>> Did you try the very latest xfs_repair? >>> >>> I grabbed the one out of debian unstable (3.2.1), verified that it was >>> your >>> latest release and used that. I didn't try building the version in git. >>> >>> It did get much further than version 3.1.7+b1 (debian stable) >>> >>> Diane >>> >>> Phase 6 - check inode connectivity... >>> >>> - resetting contents of realtime bitmap and summary inodes >>> - traversing filesystem ... >>> >>> entry "lymphoblastoid" in dir ino 256 doesn't have a .. entry, will set it >>> in ino 2051. >>> bad hash table for directory inode 256 (no data entry): rebuilding >>> rebuilding directory inode 256 >>> 7f70c79c8700: Badness in key lookup (length) >>> bp=(bno 0x3480, len 4096 bytes) key=(bno 0x3480, len 8192 bytes) >>> Metadata corruption detected at block 0x4000070/0x1000 >>> xfs_da_do_buf(2): XFS_CORRUPTION_ERROR >>> >>> fatal error -- can't read block 8388608 for directory inode 259, error 117 >>> >>> >>> _______________________________________________ >>> xfs mailing list >>> xfs@oss.sgi.com >>> http://oss.sgi.com/mailman/listinfo/xfs > From guaneryu@gmail.com Wed Sep 24 22:54:25 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,LOTS_OF_MONEY, T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 462737F7B for ; Wed, 24 Sep 2014 22:54:25 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 253F18F8035 for ; Wed, 24 Sep 2014 20:54:22 -0700 (PDT) X-ASG-Debug-ID: 1411617260-04cbb0730117e070001-NocioJ Received: from mail-pd0-f173.google.com (mail-pd0-f173.google.com [209.85.192.173]) by cuda.sgi.com with ESMTP id xbWfEcCOVFPhIB4s (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Wed, 24 Sep 2014 20:54:20 -0700 (PDT) X-Barracuda-Envelope-From: guaneryu@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.192.173 Received: by mail-pd0-f173.google.com with SMTP id w10so234596pde.18 for ; Wed, 24 Sep 2014 20:54:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=UWSfu8VyJxk5gN2IGTYYDqs6jJ/fA5cdxS8ubTaU5G4=; b=aJiylaNZsI/AYro3NlzTTYbX7VlXeyl4R7+BFOEDKqaqUD97lAHEjrBLgJOS3kLSgC aV5nJs2KYeGKYaFPpSdyNz3OJDkLEU9ERpELk8q5wQA5HG5wr7nZg1nseZnNRQv9U4SP tHjJxlX09KNq/6EFO1Aa93CjCwLmdzfwqo9CcmhQGO7gRe8RUTWBbGox8RxLTF/Az9s3 XWZ/NfUO73XtjlQHA4gptBtbqRTrbg5o9p2u7QVeuWRbUsWaMkJRRYAsnUX9cp2mPF2l I8kTOvKPc78BoIdKQWtilOwEd0aQhFICKKH1qzWTUM4yv6m4lQLY8Pp3w8304q9HpWtT e95A== X-Barracuda-BBL-IP: nil X-Received: by 10.68.114.129 with SMTP id jg1mr15063700pbb.38.1411617259821; Wed, 24 Sep 2014 20:54:19 -0700 (PDT) Received: from localhost ([203.114.244.88]) by mx.google.com with ESMTPSA id fo4sm717078pbb.12.2014.09.24.20.54.18 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 24 Sep 2014 20:54:19 -0700 (PDT) Date: Thu, 25 Sep 2014 11:54:16 +0800 X-Barracuda-Apparent-Source-IP: 203.114.244.88 From: Eryu Guan To: Brian Foster Cc: fstests@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH] generic/033: add xfs delalloc indirect block depletion reproducer Message-ID: <20140925035416.GC13950@dhcp-13-216.nay.redhat.com> X-ASG-Orig-Subj: Re: [PATCH] generic/033: add xfs delalloc indirect block depletion reproducer References: <1411584425-52709-1-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411584425-52709-1-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: mail-pd0-f173.google.com[209.85.192.173] X-Barracuda-Start-Time: 1411617260 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, MARKETING_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9848 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Wed, Sep 24, 2014 at 02:47:05PM -0400, Brian Foster wrote: > XFS allocates extra indirect blocks for delayed allocation extents at > write time. When delalloc extents are split, the existing indirect block > reservation was historically divided up evenly among the new extents > even though the overall requirement for two extents could exceed the > requirement for the original. Repeated delalloc extent splits ultimately > leads to extents with 0 indirect blocks and in turn leads to assert > failures in XFS. > > Add a test to stress indirect block reservation for delayed allocation > extents. The test converts a single delalloc extent to many and operates > on the remaining extents to detect or trigger potential problems. > > Signed-off-by: Brian Foster > --- > > Here's a simple reproducer for the indirect block reservation problem > called out here: > > http://oss.sgi.com/archives/xfs/2014-09/msg00337.html > > It reproduces the assert failures described therein: > > XFS: Assertion failed: startblockval(del.br_startblock) > 0, file: fs/xfs/libxfs/xfs_bmap.c, line: 5281 > > Note that this test also unintentionally fails on XFS. The test file > ends up zero-sized after the remount and thus hexdump doesn't produce > any output. This doesn't occur on ext4, I suspect due to the fact that > the range being zeroed is flushed beforehand, though I could be wrong > about that. Tested with ext4 and xfs, and ext4 passes/xfs fails the test as described here. Reviewed-by: Eryu Guan With one nitpick below.. > > In any event, this calls out a separate bug in XFS where if appending > data is chucked from cache by zero range before written back (eof is > page aligned), we lose the on-disk inode size update and the inode size > changes unexpectedly across the remount (assuming nothing else changes > the size, of course). > > Brian > > tests/generic/033 | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++ > tests/generic/033.out | 4 +++ > tests/generic/group | 1 + > 3 files changed, 93 insertions(+) > create mode 100755 tests/generic/033 > create mode 100644 tests/generic/033.out > > diff --git a/tests/generic/033 b/tests/generic/033 > new file mode 100755 > index 0000000..41198b7 > --- /dev/null > +++ b/tests/generic/033 > @@ -0,0 +1,88 @@ > +#! /bin/bash > +# FS QA Test No. 033 > +# > +# This test stresses indirect block reservation for delayed allocation extents. > +# XFS reserves extra blocks for deferred allocation of delalloc extents. These > +# reserved blocks can be divided among more extents than anticipated if the > +# original extent for which the blocks were reserved is split into multiple > +# delalloc extents. If this scenario repeats, eventually some extents are left > +# without any indirect block reservation whatsoever. This leads to assert > +# failures and possibly other problems in XFS. > +# > +#----------------------------------------------------------------------- > +# Copyright (c) 2014 Red Hat, Inc. All Rights Reserved. > +# > +# This program 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. > +# > +# This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, > +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > +#----------------------------------------------------------------------- > +# > + > +seq=`basename $0` > +seqres=$RESULT_DIR/$seq > +echo "QA output created by $seq" > + > +here=`pwd` > +tmp=/tmp/$$ > +status=1 # failure is the default! > +trap "_cleanup; exit \$status" 0 1 2 3 15 > + > +_cleanup() > +{ > + cd / > + rm -f $tmp.* > +} > + > +# get standard environment, filters and checks > +. ./common/rc > +. ./common/filter > + > +# real QA test starts here > +rm -f $seqres.full > + > +# Modify as appropriate. > +_supported_fs generic > +_supported_os Linux > +_require_scratch > +_require_xfs_io_command "fzero" > + > +_scratch_mkfs >/dev/null 2>&1 > +_scratch_mount > + > +file=$SCRATCH_MNT/file.$seq > +bytes=$((64 * 1024)) > + > +# create sequential delayed allocation > +$XFS_IO_PROG -f -c "pwrite 0 $bytes" $file | _filter_xfs_io \ > + >> $seqres.full 2>&1 The output of xfs_io is redirected to $seqres.full, so it's not necessary to be filtered, for debug purpose. And the following two xfs_io calls. Thanks, Eryu > + > +# Zero every other 4k range to split the larger delalloc extent into many more > +# smaller extents. Use zero instead of hole punch because the former does not > +# force writeback (and hence delalloc conversion). It can simply discard > +# delalloc blocks and convert the ranges to unwritten. > +endoff=$((bytes - 4096)) > +for i in $(seq 0 8192 $endoff); do > + $XFS_IO_PROG -c "fzero -k $i 4k" $file | _filter_xfs_io \ > + >> $seqres.full 2>&1 > +done > + > +# now zero the opposite set to remove remaining delalloc extents > +for i in $(seq 4096 8192 $endoff); do > + $XFS_IO_PROG -c "fzero -k $i 4k" $file | _filter_xfs_io \ > + >> $seqres.full 2>&1 > +done > + > +_scratch_remount > +hexdump $file > + > +status=0 > +exit > diff --git a/tests/generic/033.out b/tests/generic/033.out > new file mode 100644 > index 0000000..419d831 > --- /dev/null > +++ b/tests/generic/033.out > @@ -0,0 +1,4 @@ > +QA output created by 033 > +0000000 0000 0000 0000 0000 0000 0000 0000 0000 > +* > +0010000 > diff --git a/tests/generic/group b/tests/generic/group > index 8e0c22a..1227408 100644 > --- a/tests/generic/group > +++ b/tests/generic/group > @@ -32,6 +32,7 @@ > 027 auto enospc > 028 auto quick > 032 auto quick rw > +033 auto quick rw > 053 acl repair auto quick > 062 attr udf auto quick > 068 other auto freeze dangerous stress > -- > 1.8.3.1 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From talonx@gmail.com Thu Sep 25 01:08:33 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE, T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 4FC9D7F7E for ; Thu, 25 Sep 2014 01:08:33 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 122848F8035 for ; Wed, 24 Sep 2014 23:08:30 -0700 (PDT) X-ASG-Debug-ID: 1411625307-04bdf003a119b360001-NocioJ Received: from mail-ie0-f179.google.com (mail-ie0-f179.google.com [209.85.223.179]) by cuda.sgi.com with ESMTP id 6qRMN30kgVAoBb0v (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Wed, 24 Sep 2014 23:08:27 -0700 (PDT) X-Barracuda-Envelope-From: talonx@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.223.179 X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.179] Received: by mail-ie0-f179.google.com with SMTP id tp5so8310372ieb.10 for ; Wed, 24 Sep 2014 23:08:27 -0700 (PDT) X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.179] X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.179] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type; bh=p6gxQtswQzpDbCg9WmF5q2yakxJBda3AX14zVDGXIQI=; b=YrlOxgrA7fhoHX0EPV27W+a8LZae8KvhrYoPHEofdpzyQBz3WlUS33VT/ENmvMtdxj zy+2fnU0eZqsfHqc4YcR4hOh8p9vwyEL95/5GwXrTQcGw+gMdDWtbezwR+1bnO7sBbm/ d2aF9VByomhPH3DQTnHJS+emAkljzg4LowtXX3W+gCCRJsp8RxrYDjWnh9VkwYoNBBsR r2Dn6s0cseXesUHtJrImeXPXvvccKsfFDDtMswuxFAKcz9uiibobHZM5DSCkjiybXMTU ySLeAhrLbty4S+wYz4mNreGUgLFuIjhbOATPVUz06My4i7fD0mLWYWqoJSsJyGG5Pvlb XC/A== X-Received: by 10.43.128.7 with SMTP id hc7mr16129122icc.63.1411625307369; Wed, 24 Sep 2014 23:08:27 -0700 (PDT) MIME-Version: 1.0 Received: by 10.64.0.37 with HTTP; Wed, 24 Sep 2014 23:07:47 -0700 (PDT) In-Reply-To: References: <20140716124757.GC36312@bfoster.bfoster> From: Hrishikesh Barua Date: Thu, 25 Sep 2014 11:37:47 +0530 Message-ID: Subject: Re: Occassional problems with unfreeze To: Brian Foster , xfs@oss.sgi.com X-ASG-Orig-Subj: Re: Occassional problems with unfreeze Content-Type: multipart/alternative; boundary=001a11c219e4007a950503dda13a X-Barracuda-Connect: mail-ie0-f179.google.com[209.85.223.179] X-Barracuda-Start-Time: 1411625307 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-BRTS-Evidence: deepinspace.net X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9851 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message --001a11c219e4007a950503dda13a Content-Type: text/plain; charset=UTF-8 This happened again yesterday and I took the "echo w > /proc/sysrq-trigger". Output - http://pastebin.com/rpKNSYY7 - Hrish On 16 July 2014 18:53, Hrishikesh Barua wrote: > > On 16 July 2014 18:17, Brian Foster wrote: > >> >> That one looks like a freeze hang whereas you see an unfreeze hang. >> > You are right. My bad. > > >> Perhaps similar to this: >> >> https://bugzilla.redhat.com/show_bug.cgi?id=1052004 >> > Looks like I can't access that bug report, even after logging in. The > error message says "Most likely the bug has been restricted for internal > development processes and we cannot grant access." > >> >> > >> > No resolution seems to have happened there. Is this a known bug, or has >> it >> > been fixed since (I'm running xfsprogs 3.1.7) ? >> > >> >> Do you have the hung task output for when this occurs (echo w > >> /proc/sysrq-trigger)? >> > No, but I'll get it the next time it happens. Thanks for the tip. > >> >> Brian >> >> > Regards >> > Hrish >> >> > _______________________________________________ >> > xfs mailing list >> > xfs@oss.sgi.com >> > http://oss.sgi.com/mailman/listinfo/xfs >> >> > -- You can't be normal and expect abnormal returns - Jeffrey Pfeffer ------------------------------------------ http://code.deepinspace.net ------------------------------------------ --001a11c219e4007a950503dda13a Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
This happened again yesterday and I took the &qu= ot;echo w > /proc/sysrq-trigger".
Output - http://pastebin.com/rpKNSYY7

- = Hrish

On= 16 July 2014 18:53, Hrishikesh Barua <talonx@gmail.com> wrot= e:

On 16 July 2014 18:17= , Brian Foster <bfoster@redhat.com> wrote:

That one looks like a freeze hang whereas you see an unfreeze hang.
You are right. My bad.
=C2=A0
Perhaps similar to this:

https://bugzilla.redhat.com/show_bug.cgi?id=3D1052004
Looks like I can't access that bug report, even aft= er logging in. The error message says=C2=A0 "Most likely the bug has b= een restricted for internal development processes and we cannot grant acces= s."

>
> No resolution seems to have happened there. Is this a known bug, or ha= s it
> been fixed since (I'm running xfsprogs 3.1.7) ?
>

Do you have the hung task output for when this occurs (echo w > /proc/sysrq-trigger)?
No, but I'll get it t= he next time it happens. Thanks for the tip.

Brian

> Regards
> Hrish

> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
>
= http://oss.sgi.com/mailman/listinfo/xfs





--
You can't be normal= and expect abnormal returns - Jeffrey Pfeffer
-------------------------= -----------------
http://code.deepinspace.net
------------------------------------= ------
--001a11c219e4007a950503dda13a-- From david@fromorbit.com Thu Sep 25 02:19:23 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 72AC37F80 for ; Thu, 25 Sep 2014 02:19:23 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 43E088F8035 for ; Thu, 25 Sep 2014 00:19:19 -0700 (PDT) X-ASG-Debug-ID: 1411629546-04bdf003a019d7c0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id VFR3PpyQKDikm9hn for ; Thu, 25 Sep 2014 00:19:07 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AjMmADvBI1R5LHim/2dsb2JhbABggw5TUwSCMbNmBpQygWGFawQCAYEGFwF6hAQBAQQ6HCMQCAMOCgkMGQ8FJQMhE4g9CcMRGBiFeooMBwqDJIEdBZYYhwiBYo0whkOBaSCBaysvgkoBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail07.adl2.internode.on.net with ESMTP; 25 Sep 2014 16:49:05 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XX3KG-00061Q-Rr; Thu, 25 Sep 2014 17:18:52 +1000 Date: Thu, 25 Sep 2014 17:18:52 +1000 From: Dave Chinner To: Hrishikesh Barua Cc: Brian Foster , xfs@oss.sgi.com Subject: Re: Occassional problems with unfreeze Message-ID: <20140925071852.GE4758@dastard> X-ASG-Orig-Subj: Re: Occassional problems with unfreeze References: <20140716124757.GC36312@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1411629546 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9853 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 25, 2014 at 11:37:47AM +0530, Hrishikesh Barua wrote: > This happened again yesterday and I took the "echo w > > /proc/sysrq-trigger". > Output - http://pastebin.com/rpKNSYY7 How long have you been ignoring these messages for? [30278027.798067] XFS (xvdj): xlog_space_left: head behind tail [30278027.798069] tail_cycle = 1085, tail_bytes = 1041920 [30278027.798070] GH cycle = 1085, GH bytes = 1039296 XFS is emitting that warning several times a second. Isn't that a pretty good sign that there's something not quite right and is worth reporting? Indeed, you are running an old kern (3.2.0-54) which means it won't have this fix: 3948659 xfs: Account log unmount transaction correctly And that's likely to be the source of all your freeze/unfreeze problems because it will eventually hang the log when it's leaked all it's space in the ether.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Thu Sep 25 02:26:57 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 771907F78 for ; Thu, 25 Sep 2014 02:26:57 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 62655304051 for ; Thu, 25 Sep 2014 00:26:57 -0700 (PDT) X-ASG-Debug-ID: 1411630014-04cbb073021f1940001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id RDQnsJfFZKfpE8a2 for ; Thu, 25 Sep 2014 00:26:54 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvElAGfCI1R5LHim/2dsb2JhbABggw6BKoIxs2kGiyuKaIVrBAIBgQYXAXqEBAEBBCcTHCMQCAMOCgklDwUlAyETiD3DGAEXGIV6igwHgy6BHQEEnSCMQQSJEIN0Ky+CSgEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail07.adl2.internode.on.net with ESMTP; 25 Sep 2014 16:56:53 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XX3Ro-00062T-Vs; Thu, 25 Sep 2014 17:26:40 +1000 Date: Thu, 25 Sep 2014 17:26:40 +1000 From: Dave Chinner To: Jan Kara Cc: Li Xi , adilger@dilger.ca, linux-api@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, dmonakhov@openvz.org, viro@zeniv.linux.org.uk, linux-fsdevel@vger.kernel.org, tytso@mit.edu, linux-ext4@vger.kernel.org Subject: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project Message-ID: <20140925072640.GF4758@dastard> X-ASG-Orig-Subj: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project References: <1411567470-31799-1-git-send-email-lixi@ddn.com> <1411567470-31799-5-git-send-email-lixi@ddn.com> <20140924162507.GC27000@quack.suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140924162507.GC27000@quack.suse.cz> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1411630014 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9854 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Sep 24, 2014 at 06:25:07PM +0200, Jan Kara wrote: > On Wed 24-09-14 22:04:30, Li Xi wrote: > > This patch adds ioctl interface for setting/getting project of ext4. > The patch looks good to me. I was just wondering whether it won't be > useful to add an ioctl() which isn't ext4 specific. We could just extend > ->setattr() to allow setting of project ID (most filesystems would just > return -EOPNOTSUPP but ext4 and xfs could do the right thing) and then call > ->setattr from the generic ioctl. That way userspace won't have to care > about filesystem type when setting project ID... What do others think? I've repeatedly said that these ext4 project ID patches should implement the same interfaces as XFS rather than creating a new set of incompatible, ext4 specific interfaces to do implement the same functionality. There is no good reason for forcing userspace to re-invent tools that already exist just to manage identical functionality in different filesystems. Cheers, Dave. -- Dave Chinner david@fromorbit.com From sdray@espial.com Thu Sep 25 02:30:28 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.0 required=5.0 tests=DEAR_SOMETHING,HTML_MESSAGE autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 09F327F80 for ; Thu, 25 Sep 2014 02:30:28 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id EAE218F8035 for ; Thu, 25 Sep 2014 00:30:27 -0700 (PDT) X-ASG-Debug-ID: 1411630225-04cb6c50e718e600001-NocioJ Received: from na01-bn1-obe.outbound.protection.outlook.com (mail-bn1on0117.outbound.protection.outlook.com [157.56.110.117]) by cuda.sgi.com with ESMTP id DNmXxuPn36o54qZw (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 25 Sep 2014 00:30:25 -0700 (PDT) X-Barracuda-Envelope-From: sdray@Espial.com X-Barracuda-Apparent-Source-IP: 157.56.110.117 Received: from BN1PR0301MB0625.namprd03.prod.outlook.com (25.160.170.28) by BN1PR0301MB0627.namprd03.prod.outlook.com (25.160.171.12) with Microsoft SMTP Server (TLS) id 15.0.1039.15; Thu, 25 Sep 2014 07:30:23 +0000 Received: from BN1PR0301MB0625.namprd03.prod.outlook.com ([25.160.170.28]) by BN1PR0301MB0625.namprd03.prod.outlook.com ([25.160.170.28]) with mapi id 15.00.1034.003; Thu, 25 Sep 2014 07:30:23 +0000 From: Simon Dray To: "xfs@oss.sgi.com" Subject: XFS issue xfs goes offline with various messages drive not recoverable without reboot Thread-Topic: XFS issue xfs goes offline with various messages drive not recoverable without reboot X-ASG-Orig-Subj: XFS issue xfs goes offline with various messages drive not recoverable without reboot Thread-Index: Ac/YkpDG9jVR1llKTc+P4l4O2U49Aw== Date: Thu, 25 Sep 2014 07:30:23 +0000 Message-ID: Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [212.44.45.165] x-microsoft-antispam: BCL:0;PCL:0;RULEID:;SRVR:BN1PR0301MB0627; x-forefront-prvs: 0345CFD558 x-forefront-antispam-report: SFV:NSPM;SFS:(10019020)(6009001)(189002)(54094003)(199003)(19300405004)(76482002)(83322001)(15202345003)(19580405001)(50986999)(54356999)(2656002)(16236675004)(31966008)(86362001)(92566001)(19580395003)(21056001)(10300001)(101416001)(20776003)(46102003)(19625215002)(15975445006)(4396001)(85306004)(64706001)(120916001)(74502003)(74662003)(77982003)(81342003)(79102003)(81542003)(80022003)(106356001)(2501002)(107046002)(18717965001)(2351001)(90102001)(229853001)(107886001)(76576001)(97736003)(33646002)(105586002)(74316001)(77096002)(83072002)(108616004)(85852003)(87936001)(99286002)(66066001)(95666004)(99396003)(110136001)(24736002);DIR:OUT;SFP:1102;SCL:1;SRVR:BN1PR0301MB0627;H:BN1PR0301MB0625.namprd03.prod.outlook.com;FPR:;MLV:sfv;PTR:InfoNoRecords;MX:1;A:1;LANG:en; Content-Type: multipart/alternative; boundary="_000_dd6d1d6e9fa7469584e72574347bb088BN1PR0301MB0625namprd03_" MIME-Version: 1.0 X-OriginatorOrg: Espial.com X-Barracuda-Connect: mail-bn1on0117.outbound.protection.outlook.com[157.56.110.117] X-Barracuda-Start-Time: 1411630225 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.02 X-Barracuda-Spam-Status: No, SCORE=0.02 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE, THREAD_INDEX, THREAD_TOPIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9853 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.01 THREAD_TOPIC Thread-Topic: ...(Japanese Subject)... 0.00 HTML_MESSAGE BODY: HTML included in message --_000_dd6d1d6e9fa7469584e72574347bb088BN1PR0301MB0625namprd03_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Dear Sirs I wonder if you can help with an issue we see re-occuring on a regular basi= s with one of our HP systems which uses a HP 420 Raid controller Action taken We first saw the following: [root@ content]# ls ls: cannot open directory .: Input/output error [root@ /]# ls -ltr ls: cannot access content total 358 d?????????? ? ? ? ? ? content drwxr-xr-x. 2 root root 4096 Jun 28 2011 srv drwxr-xr-x. 2 root root 4096 Jun 28 2011 media drwxr-xr-x. 2 root root 4096 Feb 22 2012 cgroup drwx------. 2 root root 16384 Jul 21 2012 lost+found drwxr-xr-x. 2 root root 4096 Jul 21 2012 selinux We try to run: [root@ /]# xfs_check /dev/md0 xfs_check: /dev/md0 contains a mounted and writable filesystem fatal error -- couldn't initialize XFS library We also tried to umount the /dev/md0 before runniing xfs_check but no luck.= We received the error: device is in use We use xfs for one of our large raid file systems and we are seeing the xfs= filesystem go offline with the following messages in dmesg messages-20140921:Sep 18 23:01: kernel: XFS (md0): Device md0: metadata wri= te error block 0x5e28623d8 messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): I/O error occurred: me= ta-data dev md0 block 0x445cccc40 ("xlog_iodone") error 5 buf count 32768 messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): xfs_do_force_shutdown(= 0x2) called from line 891 of file fs/xfs/xfs_log.c. Return address =3D 0xff= ffffffa2c428dc messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): Log I/O Error Detected= . Shutting down filesystem messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): Please umount the file= system and rectify the problem(s) messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): xfs_imap_to_bp: xfs_tr= ans_read_buf() returned error 5. messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): xfs_iunlink_remove: xf= s_itobp() returned error 5. messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): I/O error occurred: me= ta-data dev md0 block 0x445cccc80 ("xlog_iodone") error 5 buf count 32768 messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): xfs_do_force_shutdown(= 0x2) called from line 891 of file fs/xfs/xfs_log.c. Return address =3D 0xff= ffffffa2c428dc XFS (md0): xfs_log_force: error 5 returned. XFS (md0): xfs_log_force: error 5 returned. XFS (md0): xfs_log_force: error 5 returned. In all occurrences the only way to recover from this is to reboot the syste= m and allow xfs_repair to run during boot this clears the issue until next = time We have checked the RAID health and nothing seems to be amiss, if you could= help with this it would be much appreciated Best regards Simon Simon Dray * p: +44.1223 716.400 p: +44.1223 716.476 e: sdray@espial.com 1st Floor, 335 Cambridge Science Park, Milton Road, Cambridge, Cambridgeshi= re, CB4 0WN, United Kingdom. Understanding is a three-edged sword --_000_dd6d1d6e9fa7469584e72574347bb088BN1PR0301MB0625namprd03_ Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

Dear Sirs

 

I wonder if you can help with an issue we see re-occ= uring on a regular basis with one of our HP systems which uses a HP 420 Rai= d controller

 

Action taken

 

We first saw the following:
[root@ content]# ls
ls: cannot open directory .: Input/output error


[root@ /]# ls -ltr
ls: cannot access content
total 358
d?????????? ? ? ? ? ? content
drwxr-xr-x. 2 root root 4096 Jun 28 2011 srv
drwxr-xr-x. 2 root root 4096 Jun 28 2011 media
drwxr-xr-x. 2 root root 4096 Feb 22 2012 cgroup
drwx------. 2 root root 16384 Jul 21 2012 lost+found
drwxr-xr-x. 2 root root 4096 Jul 21 2012 selinux

We try to run:
[root@ /]# xfs_check /dev/md0
xfs_check: /dev/md0 contains a mounted and writable filesystem
fatal error -- couldn't initialize XFS library
We also tried to umount the /dev/md0 before runniing xfs_check but no luck.= We received the error: device is in use

 

We use xfs for one of our large raid file systems an= d we are seeing the xfs filesystem go offline with the following messages i= n dmesg

 

messages-20140921:Sep 18 23:01: kernel: XFS (md0): D= evice md0: metadata write error block 0x5e28623d8
messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): I/O error occurred: me= ta-data dev md0 block 0x445cccc40 ("xlog_iodone") error 5 buf cou= nt 32768
messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): xfs_do_force_shutdown(= 0x2) called from line 891 of file fs/xfs/xfs_log.c. Return address =3D 0xff= ffffffa2c428dc
messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): Log I/O Error Detected= . Shutting down filesystem
messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): Please umount the file= system and rectify the problem(s)
messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): xfs_imap_to_bp: xfs_tr= ans_read_buf() returned error 5.
messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): xfs_iunlink_remove: xf= s_itobp() returned error 5.
messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): I/O error occurred: me= ta-data dev md0 block 0x445cccc80 ("xlog_iodone") error 5 buf cou= nt 32768
messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): xfs_do_force_shutdown(= 0x2) called from line 891 of file fs/xfs/xfs_log.c. Return address =3D 0xff= ffffffa2c428dc

 

XFS (md0): xfs_log_force: error 5 returned.
XFS (md0): xfs_log_force: error 5 returned.
XFS (md0): xfs_log_force: error 5 returned.

 

In all occurrences the only way to recover from this= is to reboot the system and allow xfs_repair to run during boot this clear= s the issue until next time

 

We have checked the RAID health and nothing seems to= be amiss, if you could help with this it would be much appreciated

 

 

Best regards Simon

 

 

Simon Dray s

 

p: +44.1223 716.400

p: +44.1223 716.476

e: sdray@espial.com

 = ;

1st Floor, 335 Cambridge Science Park, Mi= lton Road, Cambridge, Cambridgeshire, CB4 0WN, United Kingdom.

 

Understand= ing is a three-edged sword<= /p>

 

--_000_dd6d1d6e9fa7469584e72574347bb088BN1PR0301MB0625namprd03_-- From david@fromorbit.com Thu Sep 25 02:59:30 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 2266A7F8A for ; Thu, 25 Sep 2014 02:59:30 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id AFEFDAC004 for ; Thu, 25 Sep 2014 00:59:29 -0700 (PDT) X-ASG-Debug-ID: 1411631967-04bdf0039f19eca0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id dPTc82bhXgWSzyfE for ; Thu, 25 Sep 2014 00:59:27 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvMlAGPKI1R5LHim/2dsb2JhbABggw6BKoIxs2sGiyuKaIVrBAIBgQYXAXqEAwEBAQMBJxMcIwULCAMOCgklDwUlAyETiDYHwwMYGIV6iT9NB4RLBZ0gjEEEiRCDdCsvgQeBQwEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail07.adl2.internode.on.net with ESMTP; 25 Sep 2014 17:29:26 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XX3xI-00067w-9P; Thu, 25 Sep 2014 17:59:12 +1000 Date: Thu, 25 Sep 2014 17:59:12 +1000 From: Dave Chinner To: Jan Kara Cc: Christoph Hellwig , adilger@dilger.ca, linux-api@vger.kernel.org, xfs@oss.sgi.com, dmonakhov@openvz.org, viro@zeniv.linux.org.uk, Li Xi , linux-fsdevel@vger.kernel.org, tytso@mit.edu, linux-ext4@vger.kernel.org Subject: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project Message-ID: <20140925075912.GG4758@dastard> X-ASG-Orig-Subj: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project References: <1411567470-31799-1-git-send-email-lixi@ddn.com> <1411567470-31799-5-git-send-email-lixi@ddn.com> <20140924162507.GC27000@quack.suse.cz> <20140924162634.GA16886@infradead.org> <20140924170105.GE27000@quack.suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140924170105.GE27000@quack.suse.cz> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1411631967 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9854 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Sep 24, 2014 at 07:01:05PM +0200, Jan Kara wrote: > On Wed 24-09-14 09:26:34, Christoph Hellwig wrote: > > On Wed, Sep 24, 2014 at 06:25:07PM +0200, Jan Kara wrote: > > > On Wed 24-09-14 22:04:30, Li Xi wrote: > > > > This patch adds ioctl interface for setting/getting project of ext4. > > > The patch looks good to me. I was just wondering whether it won't be > > > useful to add an ioctl() which isn't ext4 specific. We could just extend > > > ->setattr() to allow setting of project ID (most filesystems would just > > > return -EOPNOTSUPP but ext4 and xfs could do the right thing) and then call > > > ->setattr from the generic ioctl. That way userspace won't have to care > > > about filesystem type when setting project ID... What do others think? > > > > Absolutely. In general I also wonder why this patch doesn't implement > > the full XFS API. Maybe there is a reason it was considered and > > rejected, but it would be helpful to document why. > Do you mean full get/setfsxattr API? That's a good start. The bigger issue in my mind is that we already have a fully featured quota API that supports project quotas and userspace tools available that manipulate it. xfstests already uses those tools and API for testing project quotas. This whole patchset reinvents all the quota APIs, and will require adding support in userspace, and hence require re-inventing all the test infrastructure we already have because it won't be compatible with the existing project quota test code. > That basically contains project ID, > flags (those that are currently get/set with FS_IOC_GETFLAGS/SETFLAGS), and > extent size hint right? It's a different set of flag definitions. We translate the interface XFS_XFLAG_* values to/from the inode on-disk XFS_DIFLAG_* inode values, just like we translate the VFS FS_*_FL flags that get passed through the FS_IOC_GETFLAGS/SETFLAGS ioctl. > That seems workable and it would also make setting > of PROJINHERIT flag fs agnostic. Only we would have to create some generic > flags namespace and merge into that ext4 flags and have a translation > function for the old ext4 flags. The XFS_XFLAGS_* are already filesystem agnostic - they are flags that are only used for interfacing with userspace and hence only exist at the ioctl copy in/out layer..... > Also I'm afraid we may quickly run out of > 32 available flags in xflags so we'd need to extend that. But all this > seems to be doable. The struct fsxattr was designed to be extensible - it has unused padding and enough space in the flags field to allow us to conditionally use that padding.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Thu Sep 25 03:13:14 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: * X-Spam-Status: No, score=2.0 required=5.0 tests=DEAR_SOMETHING autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 7DE7E7F8B for ; Thu, 25 Sep 2014 03:13:14 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4FCEF8F8087 for ; Thu, 25 Sep 2014 01:13:10 -0700 (PDT) X-ASG-Debug-ID: 1411632788-04bdf003a019f3a0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id N5mxBqR6WoBN4liM for ; Thu, 25 Sep 2014 01:13:08 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AiUzACHOI1R5LHim/2dsb2JhbABGGoMOU1eCMYs4qDMGlDiBW4VrBAIBgQYXAXqEAwEBAQMBOhwjBQsIAw4KCSUPBSUDIROINgcONsI9GBiFeokfJEkHhEsFlhiHCJVVgh+BVSsvAYEGgUMBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail07.adl2.internode.on.net with ESMTP; 25 Sep 2014 17:43:07 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XX4AY-0006Ap-Hr; Thu, 25 Sep 2014 18:12:54 +1000 Date: Thu, 25 Sep 2014 18:12:54 +1000 From: Dave Chinner To: Simon Dray Cc: "xfs@oss.sgi.com" Subject: Re: XFS issue xfs goes offline with various messages drive not recoverable without reboot Message-ID: <20140925081254.GH4758@dastard> X-ASG-Orig-Subj: Re: XFS issue xfs goes offline with various messages drive not recoverable without reboot References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1411632788 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9854 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 BSF_SC0_SA085 Custom Rule SA085 On Thu, Sep 25, 2014 at 07:30:23AM +0000, Simon Dray wrote: > Dear Sirs > > I wonder if you can help with an issue we see re-occuring on a regular basis with one of our HP systems which uses a HP 420 Raid controller tl;dr: more information is needed about your system to make sense of the problem. See here: http://xfs.org/index.php/XFS_FAQ#Q:_What_information_should_I_include_when_reporting_a_problem.3F > Action taken > > We first saw the following: > [root@ content]# ls > ls: cannot open directory .: Input/output error The filesystem has shut down due to a fatal error. > We try to run: > [root@ /]# xfs_check /dev/md0 > xfs_check: /dev/md0 contains a mounted and writable filesystem > fatal error -- couldn't initialize XFS library FYI, xfs_check was deprecated a quite a while ago. It no longer exists in current releases.... > We also tried to umount the /dev/md0 before runniing xfs_check but no luck. We received the error: device is in use That can happen if the storage has gone bad and IOs have been lost. > We use xfs for one of our large raid file systems and we are seeing the xfs filesystem go offline with the following messages in dmesg > > messages-20140921:Sep 18 23:01: kernel: XFS (md0): Device md0: metadata write error block 0x5e28623d8 What messages occurred before this? Something reported an IO error back to XFS, and so that something should have logged an error message... > messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): I/O error occurred: meta-data dev md0 block 0x445cccc40 ("xlog_iodone") error 5 buf count 32768 > messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): xfs_do_force_shutdown(0x2) called from line 891 of file fs/xfs/xfs_log.c. Return address = 0xffffffffa2c428dc > messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): Log I/O Error Detected. Shutting down filesystem > messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): Please umount the filesystem and rectify the problem(s) > messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): xfs_imap_to_bp: xfs_trans_read_buf() returned error 5. > messages-20140921:Sep 18 23:01:04 kernel: XFS (md0): xfs_iunlink_remove: xfs_itobp() returned error 5. Yup, kernel code is at least 2 years old, because we removed xfs_itobp in mid 2012... ;) > In all occurrences the only way to recover from this is to reboot > the system and allow xfs_repair to run during boot this clears the > issue until next time > > We have checked the RAID health and nothing seems to be amiss, if > you could help with this it would be much appreciated That's par for the course when hardware raid goes AWOL - they almost never report that they had a problem when they hang (e.g. firmware crashes so can't log an event to say it crashed). But really, more information about your system and more complete logs are needed to be able to make any progress triaging the problem. Cheers, Dave. -- Dave Chinner david@fromorbit.com From pkuelelixi@gmail.com Thu Sep 25 06:35:28 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 5706A7F8D for ; Thu, 25 Sep 2014 06:35:28 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 375CF8F8035 for ; Thu, 25 Sep 2014 04:35:25 -0700 (PDT) X-ASG-Debug-ID: 1411644923-04cb6c50e41f0770001-NocioJ Received: from mail-pa0-f52.google.com (mail-pa0-f52.google.com [209.85.220.52]) by cuda.sgi.com with ESMTP id 42VXxpa9rdDdU2bB (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Thu, 25 Sep 2014 04:35:24 -0700 (PDT) X-Barracuda-Envelope-From: pkuelelixi@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.52 Received: by mail-pa0-f52.google.com with SMTP id hz1so10687822pad.25 for ; Thu, 25 Sep 2014 04:35:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=content-type:mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=2M4RF1XEwbVv2L0qqUeqz5djhkOaI7RuyocaV3x4ngM=; b=zkwoi3aGJbQGyDKSctwrIq6zdW//PV+PqQp701RrVX00QC5+06O7wlM6QnDBo9W1+s MOWBzIpLeRolIE9INjtdcKgRluCIzrrQjPEJP5FzyLfcLkXPZOSC0dd6RKVfjuUKdtH4 u24G5d8JWpMrELYja8Ooxi6+BCDDZfwax9A/MPvX4nTizBWMpEGyzWiV505URcYr9wIc O7KnamZBrOT3ZieDOwYSSxBia8hobMq+hTDAQYfG8TDC6AX5dO6E4TcJ0D8rrMGpOT7f J+t4Z+sapRyRBcpmvKq60Z5VwYf5g41EbaT+ujZ1lmMKTEDYrVupTdAmOQ5d7LJIx3Xy EuIg== X-Barracuda-BBL-IP: nil X-Received: by 10.68.178.36 with SMTP id cv4mr18105196pbc.136.1411644923464; Thu, 25 Sep 2014 04:35:23 -0700 (PDT) Received: from [192.168.3.109] ([117.45.255.136]) by mx.google.com with ESMTPSA id qo4sm1491487pdb.37.2014.09.25.04.35.15 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 25 Sep 2014 04:35:22 -0700 (PDT) Content-Type: text/plain; charset=GB2312 Mime-Version: 1.0 (Mac OS X Mail 7.3 \(1878.6\)) Subject: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project From: lixi X-ASG-Orig-Subj: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project In-Reply-To: <20140925075912.GG4758@dastard> Date: Thu, 25 Sep 2014 19:34:38 +0800 Cc: Jan Kara , Christoph Hellwig , Andreas Dilger , linux-api@vger.kernel.org, xfs@oss.sgi.com, Dmitry Monakhov , viro@zeniv.linux.org.uk, linux-fsdevel@vger.kernel.org, Theodore Ts'o , Ext4 Developers List Content-Transfer-Encoding: quoted-printable Message-Id: References: <1411567470-31799-1-git-send-email-lixi@ddn.com> <1411567470-31799-5-git-send-email-lixi@ddn.com> <20140924162507.GC27000@quack.suse.cz> <20140924162634.GA16886@infradead.org> <20140924170105.GE27000@quack.suse.cz> <20140925075912.GG4758@dastard> To: Dave Chinner X-Mailer: Apple Mail (2.1878.6) X-Barracuda-Connect: mail-pa0-f52.google.com[209.85.220.52] X-Barracuda-Start-Time: 1411644923 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9860 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature =D4=DA 2014=C4=EA9=D4=C225=C8=D5=A3=AC=CF=C2=CE=E73:59=A3=ACDave Chinner = =D0=B4=B5=C0=A3=BA > On Wed, Sep 24, 2014 at 07:01:05PM +0200, Jan Kara wrote: >> On Wed 24-09-14 09:26:34, Christoph Hellwig wrote: >>> On Wed, Sep 24, 2014 at 06:25:07PM +0200, Jan Kara wrote: >>>> On Wed 24-09-14 22:04:30, Li Xi wrote: >>>>> This patch adds ioctl interface for setting/getting project of = ext4. >>>> The patch looks good to me. I was just wondering whether it won't = be >>>> useful to add an ioctl() which isn't ext4 specific. We could just = extend >>>> ->setattr() to allow setting of project ID (most filesystems would = just >>>> return -EOPNOTSUPP but ext4 and xfs could do the right thing) and = then call >>>> ->setattr from the generic ioctl. That way userspace won't have to = care >>>> about filesystem type when setting project ID... What do others = think? >>>=20 >>> Absolutely. In general I also wonder why this patch doesn't = implement >>> the full XFS API. Maybe there is a reason it was considered and >>> rejected, but it would be helpful to document why. >> Do you mean full get/setfsxattr API? >=20 > That's a good start. >=20 > The bigger issue in my mind is that we already have a fully featured > quota API that supports project quotas and userspace tools available > that manipulate it. xfstests already uses those tools and API > for testing project quotas. >=20 > This whole patchset reinvents all the quota APIs, and will require > adding support in userspace, and hence require re-inventing all the > test infrastructure we already have because it won't be compatible > with the existing project quota test code. >=20 >> That basically contains project ID, >> flags (those that are currently get/set with = FS_IOC_GETFLAGS/SETFLAGS), and >> extent size hint right? >=20 > It's a different set of flag definitions. We translate the interface > XFS_XFLAG_* values to/from the inode on-disk XFS_DIFLAG_* inode = values, just > like we translate the VFS FS_*_FL flags that get passed through the > FS_IOC_GETFLAGS/SETFLAGS ioctl. >=20 >> That seems workable and it would also make setting >> of PROJINHERIT flag fs agnostic. Only we would have to create some = generic >> flags namespace and merge into that ext4 flags and have a translation >> function for the old ext4 flags. >=20 > The XFS_XFLAGS_* are already filesystem agnostic - they are flags > that are only used for interfacing with userspace and hence only > exist at the ioctl copy in/out layer..... >=20 >> Also I'm afraid we may quickly run out of >> 32 available flags in xflags so we'd need to extend that. But all = this >> seems to be doable. >=20 > The struct fsxattr was designed to be extensible - it has unused > padding and enough space in the flags field to allow us to > conditionally use that padding=A1=AD. Hi Dave, I was mostly working on the semantics of inherit flag on these patches. = And I didn=A1=AFt realized that the interface differences would bother you = so much. Sorry for that. I agree that we should choose a good interface. It would be good that it = is general so that it works well for all file systems. I agree that adding = an ext4 specific ioctl() is far from the best choice. I am willing to = change it to any general interface. A general ioctl() sounds good to me. Extend = setattr() and getattr() for project ID sounds even better, since project ID looks = like UID/GID. And general xattr name is another choice. But it is might be a = little bit confusing if we use xattr actually, since we are not saving project = ID as extended attribute on Ext4. Any choice is fine with me, as long as the implementation won't introduce nasty codes or inconsistent design. However, the problem is, I do not quite understand why we should keep the interface exactly the same with XFS. It would be good if we can. But as far as I can see, it seems hard. XFS uses a lot interfaces which are not so standard and used by other file systems. For example, struct fsxattr is not used by other file systems at all except XFS. I am not = sure why we should introduce this into Ext4 if there are a lot of other = better ways. I would be happy to change to XFS interfaces, if it is general. However, I don=A1=AFt think it is general enough. I know xfstest is using the existing project quota interfaces of XFS. = And maybe there are some applications which are using them too. But keeping the interfaces exactly the same with XFS would cost so much effort that I=A1=AFd like to get enough reasons before start working on = it. Is it really necessary? I am not so sure. It is so easy to change user space applications comparing to changing a weird interfaces. For example, I think it won=A1=AFt cost even more than a day to add xfstest support for new Ext4 project quota. And since project quota is far from a widely used feature, I don=A1=AFt think there is much compatibility = problems for existing applications. And If the new project interface are general enough, there won=A1=AFt be any compatibility problems for new = applications at all. I might missed something important. So please let me know if you have any advices. Regards, - Li Xi= From david@fromorbit.com Thu Sep 25 07:02:03 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B592E7F90 for ; Thu, 25 Sep 2014 07:02:03 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 51D49AC003 for ; Thu, 25 Sep 2014 05:01:59 -0700 (PDT) X-ASG-Debug-ID: 1411646517-04bdf003a2221730001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id GpTmTx7JAKNmFV8Z for ; Thu, 25 Sep 2014 05:01:58 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ArZXAFEDJFR5LHimPGdsb2JhbABggw6BKoIxhQeucQEBAQEBAQaWE4VrAgIBAQKBCBcBBgEBAQE4OYQDAQEBAwE6HCMFCwgDDgoJJQ8FJQMHGhOINgfCahgYhXqKDAeDLoEdBZ0imUwrL4JKAQEB Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 21:31:56 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XX7kB-0006iD-6b; Thu, 25 Sep 2014 22:01:55 +1000 Date: Thu, 25 Sep 2014 22:01:55 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: flush the range before zero range conversion Message-ID: <20140925120155.GF4945@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs: flush the range before zero range conversion References: <1411585591-55975-1-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411585591-55975-1-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411646517 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9861 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Sep 24, 2014 at 03:06:31PM -0400, Brian Foster wrote: > XFS currently discards delalloc blocks within the target range of a zero > range request. Unaligned start and end offsets are zeroed through the > page cache and the internal, aligned blocks are converted to unwritten > extents. > > If EOF is page aligned and covered by a delayed allocation extent. The > inode size is not updated until I/O completion. If a zero range request > discards a delalloc range that covers page aligned EOF as such, the > inode size update never occurs. For example: > > $ rm -f /mnt/file > $ xfs_io -fc "pwrite 0 64k" -c "zero 60k 4k" /mnt/file > $ stat -c "%s" /mnt/file > 65536 > $ umount /mnt > $ mount /mnt > $ stat -c "%s" /mnt/file > 61440 > > Update xfs_zero_file_space() to flush the range rather than discard > delalloc blocks to ensure that inode size updates occur appropriately. > > Signed-off-by: Brian Foster > --- > > I suppose we could be more clever here and only flush the range in this > particular scenario, but I'm not sure if there's a major benefit there. Punching the delalloc range rather than flushing the file was done intentionally - this was added primarily for speeding up the zeroing of large VM image files. i.e. it's an extent manipulation operation rather than a data Io operation. Flushing the file defeats the primary reason for the operation existing. We can easily detect this situation and just zero the last block in the file directly after punching out all the delalloc state. This should happen anyway when the region to be zeroed is not page aligned.... > FWIW, this implicitly addresses the indlen==0 assert failures described > in the xfs_bmap_del_extent() rfc, but doesn't necessarily mean we > shouldn't fix that code IMO. We punch delalloc extents elsewhere, so that still needs fixing. Cheers, Dave. -- Dave Chinner david@fromorbit.com From dave@fromorbit.com Thu Sep 25 07:20:45 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id F2B6E7F92 for ; Thu, 25 Sep 2014 07:20:44 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id D29848F8037 for ; Thu, 25 Sep 2014 05:20:44 -0700 (PDT) X-ASG-Debug-ID: 1411647639-04cb6c50e71fae50001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id AHQe1sm7qly439iA for ; Thu, 25 Sep 2014 05:20:39 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoEXAP8HJFR5LHimPGdsb2JhbABggw6BKoc4rnABAQEBAQEGnQ4XAQYBAQEBODmEBAEFJy8zCBgxOQMHFBmIPcMLhhKOXgWpXY0RKy+CSgEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 21:50:38 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XX82H-0006kr-9c for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:20:37 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XX82H-0007Mc-8P for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:20:37 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 1/3] xfs: consider freeze levels in xfs_fs_writable() Date: Thu, 25 Sep 2014 22:20:30 +1000 X-ASG-Orig-Subj: [PATCH 1/3] xfs: consider freeze levels in xfs_fs_writable() Message-Id: <1411647632-28240-2-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411647632-28240-1-git-send-email-david@fromorbit.com> References: <1411647632-28240-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411647639 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9861 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner The filesystem is still writable in certain circumstances while a freeze is in progress but xfs_fs_writable() does not reflect that. In some code we want to check whether the fs is writable, and the context we can be called under varies because the code call be called from under both unmount and freeze contexts. Hence allow the caller to pass in the freeze level it is allowed to write at, thereby ensuring that we can use the general writable function in more places. Note: Brian Foster also wrote an almost identical patch at the same time, so some credit is due to him for the existence of this commit. Signed-off-by: Dave Chinner --- fs/xfs/xfs_log.c | 2 +- fs/xfs/xfs_mount.c | 21 +++++++++++++++------ fs/xfs/xfs_mount.h | 2 +- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index ca4fd5b..7ada70c 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1031,7 +1031,7 @@ xfs_log_need_covered(xfs_mount_t *mp) struct xlog *log = mp->m_log; int needed = 0; - if (!xfs_fs_writable(mp)) + if (!xfs_fs_writable(mp, SB_UNFROZEN)) return 0; if (!xlog_cil_empty(log)) diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index d36bdbc..9073895 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -607,7 +607,7 @@ xfs_mount_reset_sbqflags( * If the fs is readonly, let the incore superblock run * with quotas off but don't flush the update out to disk */ - if (mp->m_flags & XFS_MOUNT_RDONLY) + if (!xfs_fs_writable(mp, SB_UNFROZEN)) return 0; tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE); @@ -1077,11 +1077,16 @@ xfs_unmountfs( xfs_sysfs_del(&mp->m_kobj); } -int -xfs_fs_writable(xfs_mount_t *mp) +bool +xfs_fs_writable(xfs_mount_t *mp, int frozen_state) { - return !(mp->m_super->s_writers.frozen || XFS_FORCED_SHUTDOWN(mp) || - (mp->m_flags & XFS_MOUNT_RDONLY)); + if (mp->m_super->s_writers.frozen > frozen_state) + return false; + if (XFS_FORCED_SHUTDOWN(mp)) + return false; + if (mp->m_flags & XFS_MOUNT_RDONLY) + return false; + return true; } /* @@ -1099,7 +1104,11 @@ xfs_log_sbcount(xfs_mount_t *mp) xfs_trans_t *tp; int error; - if (!xfs_fs_writable(mp)) + /* + * We can be called during the fs freeze process, and we need to be + * able to write the superblock in that case. + */ + if (!xfs_fs_writable(mp, SB_FREEZE_FS)) return 0; xfs_icsb_sync_counters(mp, 0); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index b0447c8..30f85ca 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -384,7 +384,7 @@ extern int xfs_mount_log_sb(xfs_mount_t *, __int64_t); extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); extern int xfs_readsb(xfs_mount_t *, int); extern void xfs_freesb(xfs_mount_t *); -extern int xfs_fs_writable(xfs_mount_t *); +extern bool xfs_fs_writable(struct xfs_mount *, int); extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); extern int xfs_dev_is_read_only(struct xfs_mount *, char *); -- 2.0.0 From dave@fromorbit.com Thu Sep 25 07:20:47 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 618037F9E for ; Thu, 25 Sep 2014 07:20:47 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id E5BE4AC007 for ; Thu, 25 Sep 2014 05:20:46 -0700 (PDT) X-ASG-Debug-ID: 1411647639-04cb6c50e71fae50002-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id aWsZz8tA2rFojMh5 for ; Thu, 25 Sep 2014 05:20:44 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AmSBAP8HJFR5LHimPGdsb2JhbABggw5TV41kqCwCCgwBAQEBAQEGcgGEao5ZiFgXAQYBAQEBODmEYDuBAgMHiGoOnQ+lboYSh3mCMIQ1BZYaniYBgi0rLwGCSQEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 21:50:38 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XX82H-0006kq-8y for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:20:37 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XX82H-0007MZ-7b for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:20:37 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 0/3 v2] xfs: superblock logging rework Date: Thu, 25 Sep 2014 22:20:29 +1000 X-ASG-Orig-Subj: [PATCH 0/3 v2] xfs: superblock logging rework Message-Id: <1411647632-28240-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411647643 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA717 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9861 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_SA717 Custom Rule BSF_SC0_SA717 Hi folks, This is an updated version of the superblock logging simplification patch series I first sent here: http://oss.sgi.com/archives/xfs/2014-07/msg00465.html Version 2: - added initial patch to sanitse xfs_fs_writeable - updated comments to describe caller requirements for xfs_sync_sb() -Dave. From dave@fromorbit.com Thu Sep 25 07:20:48 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 96AA77FA1 for ; Thu, 25 Sep 2014 07:20:48 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8428D8F8035 for ; Thu, 25 Sep 2014 05:20:48 -0700 (PDT) X-ASG-Debug-ID: 1411647644-04cb6c50e61fae60001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id GFPDpVHeIX05eISY for ; Thu, 25 Sep 2014 05:20:45 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoYXAP8HJFR5LHimPGdsb2JhbABggw6BKoc4rnABAQEBAQEGnASBChcBBgEBAQE4OYQEAQUaDS8zCBgxOQMHFBmIPcMLhhKJP0KEXQWGJrBIKy+BB4FDAQEB Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 21:50:38 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XX82H-0006ks-AC for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:20:37 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XX82H-0007Mh-94 for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:20:37 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 2/3] xfs: remove bitfield based superblock updates Date: Thu, 25 Sep 2014 22:20:31 +1000 X-ASG-Orig-Subj: [PATCH 2/3] xfs: remove bitfield based superblock updates Message-Id: <1411647632-28240-3-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411647632-28240-1-git-send-email-david@fromorbit.com> References: <1411647632-28240-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411647644 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9861 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner When we log changes to the superblock, we first have to write them to the on-disk buffer, and then log that. Right now we have a complex bitfield based arrangement to only write the modified field to the buffer before we log it. This used to be necessary as a performance optimisation because we logged the superblock buffer in every extent or inode allocation or freeing, and so performance was extremely important. We haven't done this for years, however, ever since the lazy superblock counters pulled the superblock logging out of the transaction commit fast path. Hence we have a bunch of complexity that is not necessary that makes writing the in-core superblock to disk much more complex than it needs to be. We only need to log the superblock now during management operations (e.g. during mount, unmount or quota control operations) so it is not a performance critical path anymore. As such, remove the complex field based logging mechanism and replace it with a simple conversion function similar to what we use for all other on-disk structures. This means we always log the entirity of the superblock, but again because we rarely modify the superblock this is not an issue for log bandwidth or CPU time. Indeed, if we do log the superblock frequently, delayed logging will minimise the impact of this overhead. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster --- fs/xfs/libxfs/xfs_attr_leaf.c | 2 +- fs/xfs/libxfs/xfs_bmap.c | 14 +-- fs/xfs/libxfs/xfs_sb.c | 287 +++++++++++++++--------------------------- fs/xfs/libxfs/xfs_sb.h | 10 +- fs/xfs/xfs_fsops.c | 6 +- fs/xfs/xfs_mount.c | 18 +-- fs/xfs/xfs_mount.h | 2 +- fs/xfs/xfs_qm.c | 26 +--- fs/xfs/xfs_qm.h | 2 +- fs/xfs/xfs_qm_syscalls.c | 13 +- fs/xfs/xfs_super.c | 2 +- 11 files changed, 130 insertions(+), 252 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index b1f73db..f4a47a7 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -405,7 +405,7 @@ xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp) if (!xfs_sb_version_hasattr2(&mp->m_sb)) { xfs_sb_version_addattr2(&mp->m_sb); spin_unlock(&mp->m_sb_lock); - xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); + xfs_mod_sb(tp); } else spin_unlock(&mp->m_sb_lock); } diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index d85ccc3..e33a780 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1224,22 +1224,20 @@ xfs_bmap_add_attrfork( goto bmap_cancel; if (!xfs_sb_version_hasattr(&mp->m_sb) || (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) { - __int64_t sbfields = 0; + bool mod_sb = false; spin_lock(&mp->m_sb_lock); if (!xfs_sb_version_hasattr(&mp->m_sb)) { xfs_sb_version_addattr(&mp->m_sb); - sbfields |= XFS_SB_VERSIONNUM; + mod_sb = true; } if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) { xfs_sb_version_addattr2(&mp->m_sb); - sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2); + mod_sb = true; } - if (sbfields) { - spin_unlock(&mp->m_sb_lock); - xfs_mod_sb(tp, sbfields); - } else - spin_unlock(&mp->m_sb_lock); + spin_unlock(&mp->m_sb_lock); + if (mod_sb) + xfs_mod_sb(tp); } error = xfs_bmap_finish(&tp, &flist, &committed); diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 8426e5e..2803325 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -42,69 +42,6 @@ * Physical superblock buffer manipulations. Shared with libxfs in userspace. */ -static const struct { - short offset; - short type; /* 0 = integer - * 1 = binary / string (no translation) - */ -} xfs_sb_info[] = { - { offsetof(xfs_sb_t, sb_magicnum), 0 }, - { offsetof(xfs_sb_t, sb_blocksize), 0 }, - { offsetof(xfs_sb_t, sb_dblocks), 0 }, - { offsetof(xfs_sb_t, sb_rblocks), 0 }, - { offsetof(xfs_sb_t, sb_rextents), 0 }, - { offsetof(xfs_sb_t, sb_uuid), 1 }, - { offsetof(xfs_sb_t, sb_logstart), 0 }, - { offsetof(xfs_sb_t, sb_rootino), 0 }, - { offsetof(xfs_sb_t, sb_rbmino), 0 }, - { offsetof(xfs_sb_t, sb_rsumino), 0 }, - { offsetof(xfs_sb_t, sb_rextsize), 0 }, - { offsetof(xfs_sb_t, sb_agblocks), 0 }, - { offsetof(xfs_sb_t, sb_agcount), 0 }, - { offsetof(xfs_sb_t, sb_rbmblocks), 0 }, - { offsetof(xfs_sb_t, sb_logblocks), 0 }, - { offsetof(xfs_sb_t, sb_versionnum), 0 }, - { offsetof(xfs_sb_t, sb_sectsize), 0 }, - { offsetof(xfs_sb_t, sb_inodesize), 0 }, - { offsetof(xfs_sb_t, sb_inopblock), 0 }, - { offsetof(xfs_sb_t, sb_fname[0]), 1 }, - { offsetof(xfs_sb_t, sb_blocklog), 0 }, - { offsetof(xfs_sb_t, sb_sectlog), 0 }, - { offsetof(xfs_sb_t, sb_inodelog), 0 }, - { offsetof(xfs_sb_t, sb_inopblog), 0 }, - { offsetof(xfs_sb_t, sb_agblklog), 0 }, - { offsetof(xfs_sb_t, sb_rextslog), 0 }, - { offsetof(xfs_sb_t, sb_inprogress), 0 }, - { offsetof(xfs_sb_t, sb_imax_pct), 0 }, - { offsetof(xfs_sb_t, sb_icount), 0 }, - { offsetof(xfs_sb_t, sb_ifree), 0 }, - { offsetof(xfs_sb_t, sb_fdblocks), 0 }, - { offsetof(xfs_sb_t, sb_frextents), 0 }, - { offsetof(xfs_sb_t, sb_uquotino), 0 }, - { offsetof(xfs_sb_t, sb_gquotino), 0 }, - { offsetof(xfs_sb_t, sb_qflags), 0 }, - { offsetof(xfs_sb_t, sb_flags), 0 }, - { offsetof(xfs_sb_t, sb_shared_vn), 0 }, - { offsetof(xfs_sb_t, sb_inoalignmt), 0 }, - { offsetof(xfs_sb_t, sb_unit), 0 }, - { offsetof(xfs_sb_t, sb_width), 0 }, - { offsetof(xfs_sb_t, sb_dirblklog), 0 }, - { offsetof(xfs_sb_t, sb_logsectlog), 0 }, - { offsetof(xfs_sb_t, sb_logsectsize), 0 }, - { offsetof(xfs_sb_t, sb_logsunit), 0 }, - { offsetof(xfs_sb_t, sb_features2), 0 }, - { offsetof(xfs_sb_t, sb_bad_features2), 0 }, - { offsetof(xfs_sb_t, sb_features_compat), 0 }, - { offsetof(xfs_sb_t, sb_features_ro_compat), 0 }, - { offsetof(xfs_sb_t, sb_features_incompat), 0 }, - { offsetof(xfs_sb_t, sb_features_log_incompat), 0 }, - { offsetof(xfs_sb_t, sb_crc), 0 }, - { offsetof(xfs_sb_t, sb_pad), 0 }, - { offsetof(xfs_sb_t, sb_pquotino), 0 }, - { offsetof(xfs_sb_t, sb_lsn), 0 }, - { sizeof(xfs_sb_t), 0 } -}; - /* * Reference counting access wrappers to the perag structures. * Because we never free per-ag structures, the only thing we @@ -461,125 +398,119 @@ xfs_sb_from_disk( __xfs_sb_from_disk(to, from, true); } -static inline void +static void xfs_sb_quota_to_disk( - xfs_dsb_t *to, - xfs_sb_t *from, - __int64_t *fields) + struct xfs_dsb *to, + struct xfs_sb *from) { __uint16_t qflags = from->sb_qflags; + to->sb_uquotino = cpu_to_be64(from->sb_uquotino); + if (xfs_sb_version_has_pquotino(from)) { + to->sb_qflags = be16_to_cpu(from->sb_qflags); + to->sb_gquotino = cpu_to_be64(from->sb_gquotino); + to->sb_pquotino = cpu_to_be64(from->sb_pquotino); + return; + } + /* - * We need to do these manipilations only if we are working - * with an older version of on-disk superblock. + * The in-core version of sb_qflags do not have XFS_OQUOTA_* + * flags, whereas the on-disk version does. So, convert incore + * XFS_{PG}QUOTA_* flags to on-disk XFS_OQUOTA_* flags. */ - if (xfs_sb_version_has_pquotino(from)) - return; + qflags &= ~(XFS_PQUOTA_ENFD | XFS_PQUOTA_CHKD | + XFS_GQUOTA_ENFD | XFS_GQUOTA_CHKD); - if (*fields & XFS_SB_QFLAGS) { - /* - * The in-core version of sb_qflags do not have - * XFS_OQUOTA_* flags, whereas the on-disk version - * does. So, convert incore XFS_{PG}QUOTA_* flags - * to on-disk XFS_OQUOTA_* flags. - */ - qflags &= ~(XFS_PQUOTA_ENFD | XFS_PQUOTA_CHKD | - XFS_GQUOTA_ENFD | XFS_GQUOTA_CHKD); - - if (from->sb_qflags & - (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD)) - qflags |= XFS_OQUOTA_ENFD; - if (from->sb_qflags & - (XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD)) - qflags |= XFS_OQUOTA_CHKD; - to->sb_qflags = cpu_to_be16(qflags); - *fields &= ~XFS_SB_QFLAGS; - } + if (from->sb_qflags & + (XFS_PQUOTA_ENFD | XFS_GQUOTA_ENFD)) + qflags |= XFS_OQUOTA_ENFD; + if (from->sb_qflags & + (XFS_PQUOTA_CHKD | XFS_GQUOTA_CHKD)) + qflags |= XFS_OQUOTA_CHKD; + to->sb_qflags = cpu_to_be16(qflags); /* - * GQUOTINO and PQUOTINO cannot be used together in versions of - * superblock that do not have pquotino. from->sb_flags tells us which - * quota is active and should be copied to disk. If neither are active, - * make sure we write NULLFSINO to the sb_gquotino field as a quota - * inode value of "0" is invalid when the XFS_SB_VERSION_QUOTA feature - * bit is set. + * GQUOTINO and PQUOTINO cannot be used together in versions + * of superblock that do not have pquotino. from->sb_flags + * tells us which quota is active and should be copied to + * disk. If neither are active, we should NULL the inode. * - * Note that we don't need to handle the sb_uquotino or sb_pquotino here - * as they do not require any translation. Hence the main sb field loop - * will write them appropriately from the in-core superblock. + * In all cases, the separate pquotino must remain 0 because it + * it beyond the "end" of the valid non-pquotino superblock. */ - if ((*fields & XFS_SB_GQUOTINO) && - (from->sb_qflags & XFS_GQUOTA_ACCT)) + if (from->sb_qflags & XFS_GQUOTA_ACCT) to->sb_gquotino = cpu_to_be64(from->sb_gquotino); - else if ((*fields & XFS_SB_PQUOTINO) && - (from->sb_qflags & XFS_PQUOTA_ACCT)) + else if (from->sb_qflags & XFS_PQUOTA_ACCT) to->sb_gquotino = cpu_to_be64(from->sb_pquotino); - else { - /* - * We can't rely on just the fields being logged to tell us - * that it is safe to write NULLFSINO - we should only do that - * if quotas are not actually enabled. Hence only write - * NULLFSINO if both in-core quota inodes are NULL. - */ - if (from->sb_gquotino == NULLFSINO && - from->sb_pquotino == NULLFSINO) - to->sb_gquotino = cpu_to_be64(NULLFSINO); - } + else + to->sb_gquotino = cpu_to_be64(NULLFSINO); - *fields &= ~(XFS_SB_PQUOTINO | XFS_SB_GQUOTINO); + to->sb_pquotino = 0; } -/* - * Copy in core superblock to ondisk one. - * - * The fields argument is mask of superblock fields to copy. - */ void xfs_sb_to_disk( - xfs_dsb_t *to, - xfs_sb_t *from, - __int64_t fields) + struct xfs_dsb *to, + struct xfs_sb *from) { - xfs_caddr_t to_ptr = (xfs_caddr_t)to; - xfs_caddr_t from_ptr = (xfs_caddr_t)from; - xfs_sb_field_t f; - int first; - int size; - - ASSERT(fields); - if (!fields) - return; + xfs_sb_quota_to_disk(to, from); - xfs_sb_quota_to_disk(to, from, &fields); - while (fields) { - f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); - first = xfs_sb_info[f].offset; - size = xfs_sb_info[f + 1].offset - first; - - ASSERT(xfs_sb_info[f].type == 0 || xfs_sb_info[f].type == 1); - - if (size == 1 || xfs_sb_info[f].type == 1) { - memcpy(to_ptr + first, from_ptr + first, size); - } else { - switch (size) { - case 2: - *(__be16 *)(to_ptr + first) = - cpu_to_be16(*(__u16 *)(from_ptr + first)); - break; - case 4: - *(__be32 *)(to_ptr + first) = - cpu_to_be32(*(__u32 *)(from_ptr + first)); - break; - case 8: - *(__be64 *)(to_ptr + first) = - cpu_to_be64(*(__u64 *)(from_ptr + first)); - break; - default: - ASSERT(0); - } - } + to->sb_magicnum = cpu_to_be32(from->sb_magicnum); + to->sb_blocksize = cpu_to_be32(from->sb_blocksize); + to->sb_dblocks = cpu_to_be64(from->sb_dblocks); + to->sb_rblocks = cpu_to_be64(from->sb_rblocks); + to->sb_rextents = cpu_to_be64(from->sb_rextents); + memcpy(&to->sb_uuid, &from->sb_uuid, sizeof(to->sb_uuid)); + to->sb_logstart = cpu_to_be64(from->sb_logstart); + to->sb_rootino = cpu_to_be64(from->sb_rootino); + to->sb_rbmino = cpu_to_be64(from->sb_rbmino); + to->sb_rsumino = cpu_to_be64(from->sb_rsumino); + to->sb_rextsize = cpu_to_be32(from->sb_rextsize); + to->sb_agblocks = cpu_to_be32(from->sb_agblocks); + to->sb_agcount = cpu_to_be32(from->sb_agcount); + to->sb_rbmblocks = cpu_to_be32(from->sb_rbmblocks); + to->sb_logblocks = cpu_to_be32(from->sb_logblocks); + to->sb_versionnum = cpu_to_be16(from->sb_versionnum); + to->sb_sectsize = cpu_to_be16(from->sb_sectsize); + to->sb_inodesize = cpu_to_be16(from->sb_inodesize); + to->sb_inopblock = cpu_to_be16(from->sb_inopblock); + memcpy(&to->sb_fname, &from->sb_fname, sizeof(to->sb_fname)); + to->sb_blocklog = from->sb_blocklog; + to->sb_sectlog = from->sb_sectlog; + to->sb_inodelog = from->sb_inodelog; + to->sb_inopblog = from->sb_inopblog; + to->sb_agblklog = from->sb_agblklog; + to->sb_rextslog = from->sb_rextslog; + to->sb_inprogress = from->sb_inprogress; + to->sb_imax_pct = from->sb_imax_pct; + to->sb_icount = cpu_to_be64(from->sb_icount); + to->sb_ifree = cpu_to_be64(from->sb_ifree); + to->sb_fdblocks = cpu_to_be64(from->sb_fdblocks); + to->sb_frextents = cpu_to_be64(from->sb_frextents); - fields &= ~(1LL << f); + + to->sb_flags = from->sb_flags; + to->sb_shared_vn = from->sb_shared_vn; + to->sb_inoalignmt = cpu_to_be32(from->sb_inoalignmt); + to->sb_unit = cpu_to_be32(from->sb_unit); + to->sb_width = cpu_to_be32(from->sb_width); + to->sb_dirblklog = from->sb_dirblklog; + to->sb_logsectlog = from->sb_logsectlog; + to->sb_logsectsize = cpu_to_be16(from->sb_logsectsize); + to->sb_logsunit = cpu_to_be32(from->sb_logsunit); + to->sb_features2 = cpu_to_be32(from->sb_features2); + to->sb_bad_features2 = cpu_to_be32(from->sb_bad_features2); + + if (xfs_sb_version_hascrc(from)) { + to->sb_features_compat = cpu_to_be32(from->sb_features_compat); + to->sb_features_ro_compat = + cpu_to_be32(from->sb_features_ro_compat); + to->sb_features_incompat = + cpu_to_be32(from->sb_features_incompat); + to->sb_features_log_incompat = + cpu_to_be32(from->sb_features_log_incompat); + to->sb_pad = 0; + to->sb_lsn = cpu_to_be64(from->sb_lsn); } } @@ -820,35 +751,13 @@ xfs_initialize_perag_data( * access. */ void -xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) +xfs_mod_sb( + struct xfs_trans *tp) { - xfs_buf_t *bp; - int first; - int last; - xfs_mount_t *mp; - xfs_sb_field_t f; - - ASSERT(fields); - if (!fields) - return; - mp = tp->t_mountp; - bp = xfs_trans_getsb(tp, mp, 0); - first = sizeof(xfs_sb_t); - last = 0; - - /* translate/copy */ - - xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields); - - /* find modified range */ - f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields); - ASSERT((1LL << f) & XFS_SB_MOD_BITS); - last = xfs_sb_info[f + 1].offset - 1; - - f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); - ASSERT((1LL << f) & XFS_SB_MOD_BITS); - first = xfs_sb_info[f].offset; + struct xfs_mount *mp = tp->t_mountp; + struct xfs_buf *bp = xfs_trans_getsb(tp, mp, 0); + xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb); xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); - xfs_trans_log_buf(tp, bp, first, last); + xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb)); } diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h index 2e73970..c28b3c1 100644 --- a/fs/xfs/libxfs/xfs_sb.h +++ b/fs/xfs/libxfs/xfs_sb.h @@ -611,11 +611,11 @@ extern struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *, xfs_agnumber_t, extern void xfs_perag_put(struct xfs_perag *pag); extern int xfs_initialize_perag_data(struct xfs_mount *, xfs_agnumber_t); -extern void xfs_sb_calc_crc(struct xfs_buf *); -extern void xfs_mod_sb(struct xfs_trans *, __int64_t); -extern void xfs_sb_mount_common(struct xfs_mount *, struct xfs_sb *); -extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *); -extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t); +extern void xfs_sb_calc_crc(struct xfs_buf *bp); +extern void xfs_mod_sb(struct xfs_trans *tp); +extern void xfs_sb_mount_common(struct xfs_mount *mp, struct xfs_sb *sbp); +extern void xfs_sb_from_disk(struct xfs_sb *to, struct xfs_dsb *from); +extern void xfs_sb_to_disk(struct xfs_dsb *to, struct xfs_sb *from); extern void xfs_sb_quota_from_disk(struct xfs_sb *sbp); #endif /* __XFS_SB_H__ */ diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index f91de1e..2c44e0b 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -548,7 +548,7 @@ xfs_growfs_data_private( saved_error = error; continue; } - xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, XFS_SB_ALL_BITS); + xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb); error = xfs_bwrite(bp); xfs_buf_relse(bp); @@ -787,9 +787,7 @@ xfs_fs_log_dummy( xfs_trans_cancel(tp, 0); return error; } - - /* log the UUID because it is an unchanging field */ - xfs_mod_sb(tp, XFS_SB_UUID); + xfs_mod_sb(tp); xfs_trans_set_sync(tp); return xfs_trans_commit(tp, 0); } diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 9073895..e555411 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -618,7 +618,7 @@ xfs_mount_reset_sbqflags( return error; } - xfs_mod_sb(tp, XFS_SB_QFLAGS); + xfs_mod_sb(tp); return xfs_trans_commit(tp, 0); } @@ -901,7 +901,7 @@ xfs_mountfs( * perform the update e.g. for the root filesystem. */ if (mp->m_update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) { - error = xfs_mount_log_sb(mp, mp->m_update_flags); + error = xfs_mount_log_sb(mp); if (error) { xfs_warn(mp, "failed to write sb changes"); goto out_rtunmount; @@ -1127,7 +1127,7 @@ xfs_log_sbcount(xfs_mount_t *mp) return error; } - xfs_mod_sb(tp, XFS_SB_IFREE | XFS_SB_ICOUNT | XFS_SB_FDBLOCKS); + xfs_mod_sb(tp); xfs_trans_set_sync(tp); error = xfs_trans_commit(tp, 0); return error; @@ -1430,25 +1430,19 @@ xfs_freesb( */ int xfs_mount_log_sb( - xfs_mount_t *mp, - __int64_t fields) + xfs_mount_t *mp) { xfs_trans_t *tp; int error; - ASSERT(fields & (XFS_SB_UNIT | XFS_SB_WIDTH | XFS_SB_UUID | - XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2 | - XFS_SB_VERSIONNUM)); - tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT); error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0); if (error) { xfs_trans_cancel(tp, 0); return error; } - xfs_mod_sb(tp, fields); - error = xfs_trans_commit(tp, 0); - return error; + xfs_mod_sb(tp); + return xfs_trans_commit(tp, 0); } /* diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 30f85ca..01f66e5 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -380,7 +380,7 @@ extern void xfs_unmountfs(xfs_mount_t *); extern int xfs_mod_incore_sb(xfs_mount_t *, xfs_sb_field_t, int64_t, int); extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, uint, int); -extern int xfs_mount_log_sb(xfs_mount_t *, __int64_t); +extern int xfs_mount_log_sb(xfs_mount_t *); extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); extern int xfs_readsb(xfs_mount_t *, int); extern void xfs_freesb(xfs_mount_t *); diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index d68f230..1691edb 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -716,7 +716,6 @@ STATIC int xfs_qm_qino_alloc( xfs_mount_t *mp, xfs_inode_t **ip, - __int64_t sbfields, uint flags) { xfs_trans_t *tp; @@ -779,11 +778,6 @@ xfs_qm_qino_alloc( spin_lock(&mp->m_sb_lock); if (flags & XFS_QMOPT_SBVERSION) { ASSERT(!xfs_sb_version_hasquota(&mp->m_sb)); - ASSERT((sbfields & (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | - XFS_SB_GQUOTINO | XFS_SB_PQUOTINO | XFS_SB_QFLAGS)) == - (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | - XFS_SB_GQUOTINO | XFS_SB_PQUOTINO | - XFS_SB_QFLAGS)); xfs_sb_version_addquota(&mp->m_sb); mp->m_sb.sb_uquotino = NULLFSINO; @@ -800,7 +794,7 @@ xfs_qm_qino_alloc( else mp->m_sb.sb_pquotino = (*ip)->i_ino; spin_unlock(&mp->m_sb_lock); - xfs_mod_sb(tp, sbfields); + xfs_mod_sb(tp); if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES))) { xfs_alert(mp, "%s failed (error %d)!", __func__, error); @@ -1453,7 +1447,7 @@ xfs_qm_mount_quotas( spin_unlock(&mp->m_sb_lock); if (sbf != (mp->m_qflags & XFS_MOUNT_QUOTA_ALL)) { - if (xfs_qm_write_sb_changes(mp, XFS_SB_QFLAGS)) { + if (xfs_qm_write_sb_changes(mp)) { /* * We could only have been turning quotas off. * We aren't in very good shape actually because @@ -1484,7 +1478,6 @@ xfs_qm_init_quotainos( struct xfs_inode *gip = NULL; struct xfs_inode *pip = NULL; int error; - __int64_t sbflags = 0; uint flags = 0; ASSERT(mp->m_quotainfo); @@ -1519,9 +1512,6 @@ xfs_qm_init_quotainos( } } else { flags |= XFS_QMOPT_SBVERSION; - sbflags |= (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | - XFS_SB_GQUOTINO | XFS_SB_PQUOTINO | - XFS_SB_QFLAGS); } /* @@ -1532,7 +1522,6 @@ xfs_qm_init_quotainos( */ if (XFS_IS_UQUOTA_ON(mp) && uip == NULL) { error = xfs_qm_qino_alloc(mp, &uip, - sbflags | XFS_SB_UQUOTINO, flags | XFS_QMOPT_UQUOTA); if (error) goto error_rele; @@ -1541,7 +1530,6 @@ xfs_qm_init_quotainos( } if (XFS_IS_GQUOTA_ON(mp) && gip == NULL) { error = xfs_qm_qino_alloc(mp, &gip, - sbflags | XFS_SB_GQUOTINO, flags | XFS_QMOPT_GQUOTA); if (error) goto error_rele; @@ -1550,7 +1538,6 @@ xfs_qm_init_quotainos( } if (XFS_IS_PQUOTA_ON(mp) && pip == NULL) { error = xfs_qm_qino_alloc(mp, &pip, - sbflags | XFS_SB_PQUOTINO, flags | XFS_QMOPT_PQUOTA); if (error) goto error_rele; @@ -1595,8 +1582,7 @@ xfs_qm_dqfree_one( */ int xfs_qm_write_sb_changes( - xfs_mount_t *mp, - __int64_t flags) + struct xfs_mount *mp) { xfs_trans_t *tp; int error; @@ -1608,10 +1594,8 @@ xfs_qm_write_sb_changes( return error; } - xfs_mod_sb(tp, flags); - error = xfs_trans_commit(tp, 0); - - return error; + xfs_mod_sb(tp); + return xfs_trans_commit(tp, 0); } diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index 3a07a93..bddd23f 100644 --- a/fs/xfs/xfs_qm.h +++ b/fs/xfs/xfs_qm.h @@ -157,7 +157,7 @@ struct xfs_dquot_acct { #define XFS_QM_RTBWARNLIMIT 5 extern void xfs_qm_destroy_quotainfo(struct xfs_mount *); -extern int xfs_qm_write_sb_changes(struct xfs_mount *, __int64_t); +extern int xfs_qm_write_sb_changes(struct xfs_mount *); /* dquot stuff */ extern void xfs_qm_dqpurge_all(struct xfs_mount *, uint); diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 80f2d77..45f28f1 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -93,8 +93,7 @@ xfs_qm_scall_quotaoff( mutex_unlock(&q->qi_quotaofflock); /* XXX what to do if error ? Revert back to old vals incore ? */ - error = xfs_qm_write_sb_changes(mp, XFS_SB_QFLAGS); - return error; + return xfs_qm_write_sb_changes(mp); } dqtype = 0; @@ -315,7 +314,6 @@ xfs_qm_scall_quotaon( { int error; uint qf; - __int64_t sbflags; flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD); /* @@ -323,8 +321,6 @@ xfs_qm_scall_quotaon( */ flags &= ~(XFS_ALL_QUOTA_ACCT); - sbflags = 0; - if (flags == 0) { xfs_debug(mp, "%s: zero flags, m_qflags=%x", __func__, mp->m_qflags); @@ -371,11 +367,10 @@ xfs_qm_scall_quotaon( /* * There's nothing to change if it's the same. */ - if ((qf & flags) == flags && sbflags == 0) + if ((qf & flags) == flags) return -EEXIST; - sbflags |= XFS_SB_QFLAGS; - if ((error = xfs_qm_write_sb_changes(mp, sbflags))) + if ((error = xfs_qm_write_sb_changes(mp))) return error; /* * If we aren't trying to switch on quota enforcement, we are done. @@ -800,7 +795,7 @@ xfs_qm_log_quotaoff( mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL; spin_unlock(&mp->m_sb_lock); - xfs_mod_sb(tp, XFS_SB_QFLAGS); + xfs_mod_sb(tp); /* * We have to make sure that the transaction is secure on disk before we diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 9f622fe..a7d2def 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1255,7 +1255,7 @@ xfs_fs_remount( * might have some superblock changes to update. */ if (mp->m_update_flags) { - error = xfs_mount_log_sb(mp, mp->m_update_flags); + error = xfs_mount_log_sb(mp); if (error) { xfs_warn(mp, "failed to write sb changes"); return error; -- 2.0.0 From dave@fromorbit.com Thu Sep 25 07:20:52 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 1A1D77FA8 for ; Thu, 25 Sep 2014 07:20:52 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 0891C304059 for ; Thu, 25 Sep 2014 05:20:48 -0700 (PDT) X-ASG-Debug-ID: 1411647639-04cb6c50e71fae50003-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id Fwv2ILO7hD2gjhbG for ; Thu, 25 Sep 2014 05:20:45 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoYXAP8HJFR5LHimPGdsb2JhbABggw6BKoc4rnABAQEBAQEGnASBChcBBgEBAQE4OYQEAQUaDS8eFQgYMTkDBxQZiD3DC4YSiT9ChF0FhiawSCsvgQeBQwEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 21:50:38 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XX82H-0006kt-Ak for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:20:37 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XX82H-0007Mm-9e for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:20:37 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 3/3] xfs: consolidate superblock logging functions Date: Thu, 25 Sep 2014 22:20:32 +1000 X-ASG-Orig-Subj: [PATCH 3/3] xfs: consolidate superblock logging functions Message-Id: <1411647632-28240-4-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411647632-28240-1-git-send-email-david@fromorbit.com> References: <1411647632-28240-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411647645 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9861 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner We now have several superblock loggin functions that are identical except for the transaction reservation and whether it shoul dbe a synchronous transaction or not. Consolidate these all into a single function, a single reserveration and a sync flag and call it xfs_sync_sb(). Also, xfs_mod_sb() is not really a modification function - it's the operation of logging the superblock buffer. hence change the name of it to reflect this. Note that we have to change the mp->m_update_flags that are passed around at mount time to a boolean simply to indicate a superblock update is needed. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_attr_leaf.c | 2 +- fs/xfs/libxfs/xfs_bmap.c | 10 +++--- fs/xfs/libxfs/xfs_sb.c | 43 +++++++++++++++++++---- fs/xfs/libxfs/xfs_sb.h | 42 ++--------------------- fs/xfs/libxfs/xfs_shared.h | 26 ++++++-------- fs/xfs/libxfs/xfs_trans_resv.c | 14 -------- fs/xfs/libxfs/xfs_trans_resv.h | 1 - fs/xfs/xfs_fsops.c | 29 ---------------- fs/xfs/xfs_log.c | 17 ++++++++-- fs/xfs/xfs_mount.c | 77 ++++++------------------------------------ fs/xfs/xfs_mount.h | 3 +- fs/xfs/xfs_qm.c | 27 ++------------- fs/xfs/xfs_qm_syscalls.c | 7 ++-- fs/xfs/xfs_super.c | 13 +++---- 14 files changed, 95 insertions(+), 216 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index f4a47a7..bcb0ab1 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -405,7 +405,7 @@ xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp) if (!xfs_sb_version_hasattr2(&mp->m_sb)) { xfs_sb_version_addattr2(&mp->m_sb); spin_unlock(&mp->m_sb_lock); - xfs_mod_sb(tp); + xfs_log_sb(tp); } else spin_unlock(&mp->m_sb_lock); } diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index e33a780..d40be66 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1224,20 +1224,20 @@ xfs_bmap_add_attrfork( goto bmap_cancel; if (!xfs_sb_version_hasattr(&mp->m_sb) || (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) { - bool mod_sb = false; + bool log_sb = false; spin_lock(&mp->m_sb_lock); if (!xfs_sb_version_hasattr(&mp->m_sb)) { xfs_sb_version_addattr(&mp->m_sb); - mod_sb = true; + log_sb = true; } if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) { xfs_sb_version_addattr2(&mp->m_sb); - mod_sb = true; + log_sb = true; } spin_unlock(&mp->m_sb_lock); - if (mod_sb) - xfs_mod_sb(tp); + if (log_sb) + xfs_log_sb(tp); } error = xfs_bmap_finish(&tp, &flist, &committed); diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 2803325..b5ffbe4 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -744,14 +744,13 @@ xfs_initialize_perag_data( } /* - * xfs_mod_sb() can be used to copy arbitrary changes to the - * in-core superblock into the superblock buffer to be logged. - * It does not provide the higher level of locking that is - * needed to protect the in-core superblock from concurrent - * access. + * xfs_log_sb() can be used to copy arbitrary changes to the in-core superblock + * into the superblock buffer to be logged. It does not provide the higher + * level of locking that is needed to protect the in-core superblock from + * concurrent access. */ void -xfs_mod_sb( +xfs_log_sb( struct xfs_trans *tp) { struct xfs_mount *mp = tp->t_mountp; @@ -761,3 +760,35 @@ xfs_mod_sb( xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb)); } + +/* + * xfs_sync_sb + * + * Sync the superblock to disk. + * + * Note that the caller is responsible for checking the frozen state of the + * filesystem. This procedure uses the non-blocking transaction allocator and + * thus will allow modifications to a frozen fs. This is required because this + * code can be called during the process of freezing where use of the high-level + * allocator would deadlock. + */ +int +xfs_sync_sb( + struct xfs_mount *mp, + bool wait) +{ + struct xfs_trans *tp; + int error; + + tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_CHANGE, KM_SLEEP); + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0); + if (error) { + xfs_trans_cancel(tp, 0); + return error; + } + + xfs_log_sb(tp); + if (wait) + xfs_trans_set_sync(tp); + return xfs_trans_commit(tp, 0); +} diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h index c28b3c1..73dff28 100644 --- a/fs/xfs/libxfs/xfs_sb.h +++ b/fs/xfs/libxfs/xfs_sb.h @@ -274,45 +274,6 @@ typedef enum { XFS_SBS_FIELDCOUNT } xfs_sb_field_t; -/* - * Mask values, defined based on the xfs_sb_field_t values. - * Only define the ones we're using. - */ -#define XFS_SB_MVAL(x) (1LL << XFS_SBS_ ## x) -#define XFS_SB_UUID XFS_SB_MVAL(UUID) -#define XFS_SB_FNAME XFS_SB_MVAL(FNAME) -#define XFS_SB_ROOTINO XFS_SB_MVAL(ROOTINO) -#define XFS_SB_RBMINO XFS_SB_MVAL(RBMINO) -#define XFS_SB_RSUMINO XFS_SB_MVAL(RSUMINO) -#define XFS_SB_VERSIONNUM XFS_SB_MVAL(VERSIONNUM) -#define XFS_SB_UQUOTINO XFS_SB_MVAL(UQUOTINO) -#define XFS_SB_GQUOTINO XFS_SB_MVAL(GQUOTINO) -#define XFS_SB_QFLAGS XFS_SB_MVAL(QFLAGS) -#define XFS_SB_SHARED_VN XFS_SB_MVAL(SHARED_VN) -#define XFS_SB_UNIT XFS_SB_MVAL(UNIT) -#define XFS_SB_WIDTH XFS_SB_MVAL(WIDTH) -#define XFS_SB_ICOUNT XFS_SB_MVAL(ICOUNT) -#define XFS_SB_IFREE XFS_SB_MVAL(IFREE) -#define XFS_SB_FDBLOCKS XFS_SB_MVAL(FDBLOCKS) -#define XFS_SB_FEATURES2 XFS_SB_MVAL(FEATURES2) -#define XFS_SB_BAD_FEATURES2 XFS_SB_MVAL(BAD_FEATURES2) -#define XFS_SB_FEATURES_COMPAT XFS_SB_MVAL(FEATURES_COMPAT) -#define XFS_SB_FEATURES_RO_COMPAT XFS_SB_MVAL(FEATURES_RO_COMPAT) -#define XFS_SB_FEATURES_INCOMPAT XFS_SB_MVAL(FEATURES_INCOMPAT) -#define XFS_SB_FEATURES_LOG_INCOMPAT XFS_SB_MVAL(FEATURES_LOG_INCOMPAT) -#define XFS_SB_CRC XFS_SB_MVAL(CRC) -#define XFS_SB_PQUOTINO XFS_SB_MVAL(PQUOTINO) -#define XFS_SB_NUM_BITS ((int)XFS_SBS_FIELDCOUNT) -#define XFS_SB_ALL_BITS ((1LL << XFS_SB_NUM_BITS) - 1) -#define XFS_SB_MOD_BITS \ - (XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \ - XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \ - XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \ - XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2 | \ - XFS_SB_BAD_FEATURES2 | XFS_SB_FEATURES_COMPAT | \ - XFS_SB_FEATURES_RO_COMPAT | XFS_SB_FEATURES_INCOMPAT | \ - XFS_SB_FEATURES_LOG_INCOMPAT | XFS_SB_PQUOTINO) - /* * Misc. Flags - warning - these will be cleared by xfs_repair unless @@ -612,7 +573,8 @@ extern void xfs_perag_put(struct xfs_perag *pag); extern int xfs_initialize_perag_data(struct xfs_mount *, xfs_agnumber_t); extern void xfs_sb_calc_crc(struct xfs_buf *bp); -extern void xfs_mod_sb(struct xfs_trans *tp); +extern void xfs_log_sb(struct xfs_trans *tp); +extern int xfs_sync_sb(struct xfs_mount *mp, bool wait); extern void xfs_sb_mount_common(struct xfs_mount *mp, struct xfs_sb *sbp); extern void xfs_sb_from_disk(struct xfs_sb *to, struct xfs_dsb *from); extern void xfs_sb_to_disk(struct xfs_dsb *to, struct xfs_sb *from); diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h index 82404da..4ae617a 100644 --- a/fs/xfs/libxfs/xfs_shared.h +++ b/fs/xfs/libxfs/xfs_shared.h @@ -82,7 +82,7 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops; #define XFS_TRANS_ATTR_RM 23 #define XFS_TRANS_ATTR_FLAG 24 #define XFS_TRANS_CLEAR_AGI_BUCKET 25 -#define XFS_TRANS_QM_SBCHANGE 26 +#define XFS_TRANS_SB_CHANGE 26 /* * Dummy entries since we use the transaction type to index into the * trans_type[] in xlog_recover_print_trans_head() @@ -95,17 +95,15 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops; #define XFS_TRANS_QM_DQCLUSTER 32 #define XFS_TRANS_QM_QINOCREATE 33 #define XFS_TRANS_QM_QUOTAOFF_END 34 -#define XFS_TRANS_SB_UNIT 35 -#define XFS_TRANS_FSYNC_TS 36 -#define XFS_TRANS_GROWFSRT_ALLOC 37 -#define XFS_TRANS_GROWFSRT_ZERO 38 -#define XFS_TRANS_GROWFSRT_FREE 39 -#define XFS_TRANS_SWAPEXT 40 -#define XFS_TRANS_SB_COUNT 41 -#define XFS_TRANS_CHECKPOINT 42 -#define XFS_TRANS_ICREATE 43 -#define XFS_TRANS_CREATE_TMPFILE 44 -#define XFS_TRANS_TYPE_MAX 44 +#define XFS_TRANS_FSYNC_TS 35 +#define XFS_TRANS_GROWFSRT_ALLOC 36 +#define XFS_TRANS_GROWFSRT_ZERO 37 +#define XFS_TRANS_GROWFSRT_FREE 37 +#define XFS_TRANS_SWAPEXT 39 +#define XFS_TRANS_CHECKPOINT 40 +#define XFS_TRANS_ICREATE 41 +#define XFS_TRANS_CREATE_TMPFILE 42 +#define XFS_TRANS_TYPE_MAX 43 /* new transaction types need to be reflected in xfs_logprint(8) */ #define XFS_TRANS_TYPES \ @@ -134,20 +132,18 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops; { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \ { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \ { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \ - { XFS_TRANS_QM_SBCHANGE, "QM_SBCHANGE" }, \ + { XFS_TRANS_SB_CHANGE, "SBCHANGE" }, \ { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \ { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \ { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \ { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \ { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \ { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \ - { XFS_TRANS_SB_UNIT, "SB_UNIT" }, \ { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \ { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \ { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \ { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \ { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \ - { XFS_TRANS_SB_COUNT, "SB_COUNT" }, \ { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \ { XFS_TRANS_DUMMY1, "DUMMY1" }, \ { XFS_TRANS_DUMMY2, "DUMMY2" }, \ diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c index f2bda7c..7c42e2c 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.c +++ b/fs/xfs/libxfs/xfs_trans_resv.c @@ -718,17 +718,6 @@ xfs_calc_clear_agi_bucket_reservation( } /* - * Clearing the quotaflags in the superblock. - * the super block for changing quota flags: sector size - */ -STATIC uint -xfs_calc_qm_sbchange_reservation( - struct xfs_mount *mp) -{ - return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); -} - -/* * Adjusting quota limits. * the xfs_disk_dquot_t: sizeof(struct xfs_disk_dquot) */ @@ -866,9 +855,6 @@ xfs_trans_resv_calc( * The following transactions are logged in logical format with * a default log count. */ - resp->tr_qm_sbchange.tr_logres = xfs_calc_qm_sbchange_reservation(mp); - resp->tr_qm_sbchange.tr_logcount = XFS_DEFAULT_LOG_COUNT; - resp->tr_qm_setqlim.tr_logres = xfs_calc_qm_setqlim_reservation(mp); resp->tr_qm_setqlim.tr_logcount = XFS_DEFAULT_LOG_COUNT; diff --git a/fs/xfs/libxfs/xfs_trans_resv.h b/fs/xfs/libxfs/xfs_trans_resv.h index 1097d14..2d5bdfc 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.h +++ b/fs/xfs/libxfs/xfs_trans_resv.h @@ -56,7 +56,6 @@ struct xfs_trans_resv { struct xfs_trans_res tr_growrtalloc; /* grow realtime allocations */ struct xfs_trans_res tr_growrtzero; /* grow realtime zeroing */ struct xfs_trans_res tr_growrtfree; /* grow realtime freeing */ - struct xfs_trans_res tr_qm_sbchange; /* change quota flags */ struct xfs_trans_res tr_qm_setqlim; /* adjust quota limits */ struct xfs_trans_res tr_qm_dqalloc; /* allocate quota on disk */ struct xfs_trans_res tr_qm_quotaoff; /* turn quota off */ diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 2c44e0b..126b4b3 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -763,35 +763,6 @@ out: return 0; } -/* - * Dump a transaction into the log that contains no real change. This is needed - * to be able to make the log dirty or stamp the current tail LSN into the log - * during the covering operation. - * - * We cannot use an inode here for this - that will push dirty state back up - * into the VFS and then periodic inode flushing will prevent log covering from - * making progress. Hence we log a field in the superblock instead and use a - * synchronous transaction to ensure the superblock is immediately unpinned - * and can be written back. - */ -int -xfs_fs_log_dummy( - xfs_mount_t *mp) -{ - xfs_trans_t *tp; - int error; - - tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1, KM_SLEEP); - error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0); - if (error) { - xfs_trans_cancel(tp, 0); - return error; - } - xfs_mod_sb(tp); - xfs_trans_set_sync(tp); - return xfs_trans_commit(tp, 0); -} - int xfs_fs_goingdown( xfs_mount_t *mp, diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 7ada70c..b1131fe 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1292,9 +1292,20 @@ xfs_log_worker( struct xfs_mount *mp = log->l_mp; /* dgc: errors ignored - not fatal and nowhere to report them */ - if (xfs_log_need_covered(mp)) - xfs_fs_log_dummy(mp); - else + if (xfs_log_need_covered(mp)) { + /* + * Dump a transaction into the log that contains no real change. + * This is needed stamp the current tail LSN into the log during + * the covering operation. + * + * We cannot use an inode here for this - that will push dirty + * state back up into the VFS and then periodic inode flushing + * will prevent log covering from making progress. Hence we + * synchronously log the superblock instead to ensure the + * superblock is immediately unpinned and can be written back. + */ + xfs_sync_sb(mp, true); + } else xfs_log_force(mp, 0); /* start pushing all the metadata that is currently dirty */ diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index e555411..78a2799 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -416,11 +416,11 @@ xfs_update_alignment(xfs_mount_t *mp) if (xfs_sb_version_hasdalign(sbp)) { if (sbp->sb_unit != mp->m_dalign) { sbp->sb_unit = mp->m_dalign; - mp->m_update_flags |= XFS_SB_UNIT; + mp->m_update_sb = true; } if (sbp->sb_width != mp->m_swidth) { sbp->sb_width = mp->m_swidth; - mp->m_update_flags |= XFS_SB_WIDTH; + mp->m_update_sb = true; } } else { xfs_warn(mp, @@ -588,38 +588,18 @@ int xfs_mount_reset_sbqflags( struct xfs_mount *mp) { - int error; - struct xfs_trans *tp; - mp->m_qflags = 0; - /* - * It is OK to look at sb_qflags here in mount path, - * without m_sb_lock. - */ + /* It is OK to look at sb_qflags in the mount path without m_sb_lock. */ if (mp->m_sb.sb_qflags == 0) return 0; spin_lock(&mp->m_sb_lock); mp->m_sb.sb_qflags = 0; spin_unlock(&mp->m_sb_lock); - /* - * If the fs is readonly, let the incore superblock run - * with quotas off but don't flush the update out to disk - */ if (!xfs_fs_writable(mp, SB_UNFROZEN)) return 0; - - tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE); - error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_sbchange, 0, 0); - if (error) { - xfs_trans_cancel(tp, 0); - xfs_alert(mp, "%s: Superblock update failed!", __func__); - return error; - } - - xfs_mod_sb(tp); - return xfs_trans_commit(tp, 0); + return xfs_sync_sb(mp, false); } __uint64_t @@ -683,7 +663,7 @@ xfs_mountfs( xfs_warn(mp, "correcting sb_features alignment problem"); sbp->sb_features2 |= sbp->sb_bad_features2; sbp->sb_bad_features2 = sbp->sb_features2; - mp->m_update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2; + mp->m_update_sb = true; /* * Re-check for ATTR2 in case it was found in bad_features2 @@ -697,17 +677,17 @@ xfs_mountfs( if (xfs_sb_version_hasattr2(&mp->m_sb) && (mp->m_flags & XFS_MOUNT_NOATTR2)) { xfs_sb_version_removeattr2(&mp->m_sb); - mp->m_update_flags |= XFS_SB_FEATURES2; + mp->m_update_sb = true; /* update sb_versionnum for the clearing of the morebits */ if (!sbp->sb_features2) - mp->m_update_flags |= XFS_SB_VERSIONNUM; + mp->m_update_sb = true; } /* always use v2 inodes by default now */ if (!(mp->m_sb.sb_versionnum & XFS_SB_VERSION_NLINKBIT)) { mp->m_sb.sb_versionnum |= XFS_SB_VERSION_NLINKBIT; - mp->m_update_flags |= XFS_SB_VERSIONNUM; + mp->m_update_sb = true; } /* @@ -900,8 +880,8 @@ xfs_mountfs( * the next remount into writeable mode. Otherwise we would never * perform the update e.g. for the root filesystem. */ - if (mp->m_update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) { - error = xfs_mount_log_sb(mp); + if (mp->m_update_sb && !(mp->m_flags & XFS_MOUNT_RDONLY)) { + error = xfs_sync_sb(mp, false); if (error) { xfs_warn(mp, "failed to write sb changes"); goto out_rtunmount; @@ -1101,9 +1081,6 @@ xfs_fs_writable(xfs_mount_t *mp, int frozen_state) int xfs_log_sbcount(xfs_mount_t *mp) { - xfs_trans_t *tp; - int error; - /* * We can be called during the fs freeze process, and we need to be * able to write the superblock in that case. @@ -1120,17 +1097,7 @@ xfs_log_sbcount(xfs_mount_t *mp) if (!xfs_sb_version_haslazysbcount(&mp->m_sb)) return 0; - tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_COUNT, KM_SLEEP); - error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0); - if (error) { - xfs_trans_cancel(tp, 0); - return error; - } - - xfs_mod_sb(tp); - xfs_trans_set_sync(tp); - error = xfs_trans_commit(tp, 0); - return error; + return xfs_sync_sb(mp, true); } /* @@ -1424,28 +1391,6 @@ xfs_freesb( } /* - * Used to log changes to the superblock unit and width fields which could - * be altered by the mount options, as well as any potential sb_features2 - * fixup. Only the first superblock is updated. - */ -int -xfs_mount_log_sb( - xfs_mount_t *mp) -{ - xfs_trans_t *tp; - int error; - - tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT); - error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0); - if (error) { - xfs_trans_cancel(tp, 0); - return error; - } - xfs_mod_sb(tp); - return xfs_trans_commit(tp, 0); -} - -/* * If the underlying (data/log/rt) device is readonly, there are some * operations that cannot proceed. */ diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 01f66e5..06f16d5 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -162,8 +162,7 @@ typedef struct xfs_mount { struct delayed_work m_reclaim_work; /* background inode reclaim */ struct delayed_work m_eofblocks_work; /* background eof blocks trimming */ - __int64_t m_update_flags; /* sb flags we need to update - on the next remount,rw */ + bool m_update_sb; /* sb needs update in mount */ int64_t m_low_space[XFS_LOWSP_MAX]; /* low free space thresholds */ struct xfs_kobj m_kobj; diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 1691edb..bfb017d 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -794,7 +794,7 @@ xfs_qm_qino_alloc( else mp->m_sb.sb_pquotino = (*ip)->i_ino; spin_unlock(&mp->m_sb_lock); - xfs_mod_sb(tp); + xfs_log_sb(tp); if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES))) { xfs_alert(mp, "%s failed (error %d)!", __func__, error); @@ -1447,7 +1447,7 @@ xfs_qm_mount_quotas( spin_unlock(&mp->m_sb_lock); if (sbf != (mp->m_qflags & XFS_MOUNT_QUOTA_ALL)) { - if (xfs_qm_write_sb_changes(mp)) { + if (xfs_sync_sb(mp, false)) { /* * We could only have been turning quotas off. * We aren't in very good shape actually because @@ -1576,29 +1576,6 @@ xfs_qm_dqfree_one( xfs_qm_dqdestroy(dqp); } -/* - * Start a transaction and write the incore superblock changes to - * disk. flags parameter indicates which fields have changed. - */ -int -xfs_qm_write_sb_changes( - struct xfs_mount *mp) -{ - xfs_trans_t *tp; - int error; - - tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE); - error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_sbchange, 0, 0); - if (error) { - xfs_trans_cancel(tp, 0); - return error; - } - - xfs_mod_sb(tp); - return xfs_trans_commit(tp, 0); -} - - /* --------------- utility functions for vnodeops ---------------- */ diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 45f28f1..d558306 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -93,7 +93,7 @@ xfs_qm_scall_quotaoff( mutex_unlock(&q->qi_quotaofflock); /* XXX what to do if error ? Revert back to old vals incore ? */ - return xfs_qm_write_sb_changes(mp); + return xfs_sync_sb(mp, false); } dqtype = 0; @@ -370,7 +370,8 @@ xfs_qm_scall_quotaon( if ((qf & flags) == flags) return -EEXIST; - if ((error = xfs_qm_write_sb_changes(mp))) + error = xfs_sync_sb(mp, false); + if (error) return error; /* * If we aren't trying to switch on quota enforcement, we are done. @@ -795,7 +796,7 @@ xfs_qm_log_quotaoff( mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL; spin_unlock(&mp->m_sb_lock); - xfs_mod_sb(tp); + xfs_log_sb(tp); /* * We have to make sure that the transaction is secure on disk before we diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index a7d2def..d018f65 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1254,13 +1254,13 @@ xfs_fs_remount( * If this is the first remount to writeable state we * might have some superblock changes to update. */ - if (mp->m_update_flags) { - error = xfs_mount_log_sb(mp); + if (mp->m_update_sb) { + error = xfs_sync_sb(mp, false); if (error) { xfs_warn(mp, "failed to write sb changes"); return error; } - mp->m_update_flags = 0; + mp->m_update_sb = false; } /* @@ -1290,8 +1290,9 @@ xfs_fs_remount( /* * Second stage of a freeze. The data is already frozen so we only - * need to take care of the metadata. Once that's done write a dummy - * record to dirty the log in case of a crash while frozen. + * need to take care of the metadata. Once that's done sync the superblock + * to the log to dirty it in case of a crash while frozen. This ensures that we + * will recover the unlinked inode lists on the next mount. */ STATIC int xfs_fs_freeze( @@ -1301,7 +1302,7 @@ xfs_fs_freeze( xfs_save_resvblks(mp); xfs_quiesce_attr(mp); - return xfs_fs_log_dummy(mp); + return xfs_sync_sb(mp, true); } STATIC int -- 2.0.0 From dave@fromorbit.com Thu Sep 25 07:34:45 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id F3CEE7F9A for ; Thu, 25 Sep 2014 07:34:44 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id E18658F804C for ; Thu, 25 Sep 2014 05:34:44 -0700 (PDT) X-ASG-Debug-ID: 1411648482-04cb6c50e51ff7b0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id G5gHe9zGISclVZGy for ; Thu, 25 Sep 2014 05:34:43 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoEXAIULJFR5LHimPGdsb2JhbABggw6BKoc4rnABAQEBAQEGnQ4XAQYBAQEBODmEBAEFJy8zCBgxOQMHFBmIPcMDhhKKKYQ1BaldjRErL4JKAQEB Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 22:04:25 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XX8Fb-0006nA-Rz for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XX8Fb-0007gP-Qd for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 02/11] xfs: Don't use xfs_buf_iowait in the delwri buffer code Date: Thu, 25 Sep 2014 22:34:12 +1000 X-ASG-Orig-Subj: [PATCH 02/11] xfs: Don't use xfs_buf_iowait in the delwri buffer code Message-Id: <1411648461-29003-3-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411648461-29003-1-git-send-email-david@fromorbit.com> References: <1411648461-29003-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411648482 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9861 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner For the special case of delwri buffer submission and waiting, we don't need to issue IO synchronously at all. The second pass to call xfs_buf_iowait() can be replaced with blocking on xfs_buf_lock() - the buffer will be unlocked when the async IO is complete. This formalises a sane the method of waiting for async IO - take an extra reference, submit the IO, call xfs_buf_lock() when you want to wait for IO completion. i.e.: bp = xfs_buf_find(); xfs_buf_hold(bp); bp->b_flags |= XBF_ASYNC; xfs_buf_iosubmit(bp); xfs_buf_lock(bp) error = bp->b_error; .... xfs_buf_relse(bp); While this is somewhat racy for gathering IO errors, none of the code that calls xfs_buf_delwri_submit() will race against other users of the buffers being submitted. Even if they do, we don't really care if the error is detected by the delwri code or the user we raced against. Either way, the error will be detected and handled. Signed-off-by: Dave Chinner --- fs/xfs/xfs_buf.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index ec65050..f1bd238 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1813,12 +1813,17 @@ __xfs_buf_delwri_submit( blk_start_plug(&plug); list_for_each_entry_safe(bp, n, io_list, b_list) { bp->b_flags &= ~(_XBF_DELWRI_Q | XBF_ASYNC | XBF_WRITE_FAIL); - bp->b_flags |= XBF_WRITE; + bp->b_flags |= XBF_WRITE | XBF_ASYNC; - if (!wait) { - bp->b_flags |= XBF_ASYNC; + /* + * we do all Io submission async. This means if we need to wait + * for IO completion we need to take an extra reference so the + * buffer is still valid on the other side. + */ + if (wait) + xfs_buf_hold(bp); + else list_del_init(&bp->b_list); - } xfs_bdstrat_cb(bp); } blk_finish_plug(&plug); @@ -1866,7 +1871,10 @@ xfs_buf_delwri_submit( bp = list_first_entry(&io_list, struct xfs_buf, b_list); list_del_init(&bp->b_list); - error2 = xfs_buf_iowait(bp); + + /* locking the buffer will wait for async IO completion. */ + xfs_buf_lock(bp); + error2 = bp->b_error; xfs_buf_relse(bp); if (!error) error = error2; -- 2.0.0 From dave@fromorbit.com Thu Sep 25 07:34:46 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 0C2D57F9A for ; Thu, 25 Sep 2014 07:34:46 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id E5C4E8F804C for ; Thu, 25 Sep 2014 05:34:45 -0700 (PDT) X-ASG-Debug-ID: 1411648483-04cbb0730225ec90001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id pVRGT3vBttjag3fD for ; Thu, 25 Sep 2014 05:34:44 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoEXAIULJFR5LHimPGdsb2JhbABggw6BKoc4rnABAQEBAQEGnQ4XAQYBAQEBODmEBAEFJy8zCBgxOQMHFBmIPcMDhhKKKYQ1BYYmkjKeFisvgkoBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 22:04:25 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XX8Fb-0006n9-RG for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XX8Fb-0007gK-QG for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 01/11] xfs: force the log before shutting down Date: Thu, 25 Sep 2014 22:34:11 +1000 X-ASG-Orig-Subj: [PATCH 01/11] xfs: force the log before shutting down Message-Id: <1411648461-29003-2-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411648461-29003-1-git-send-email-david@fromorbit.com> References: <1411648461-29003-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411648483 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9862 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner When we have marked the filesystem for shutdown, we want to prevent any further buffer IO from being submitted. However, we currently force the log after marking the filesystem as shut down, hence allowing IO to the log *after* we have marked both the filesystem and the log as in an error state. Clean this up by forcing the log before we mark the filesytem with an error. This replaces the pure CIL flush that we currently have which works around this same issue (i.e the CIL can't be flushed once the shutdown flags are set) and hence enables us to clean up the logic substantially. Signed-off-by: Dave Chinner --- fs/xfs/xfs_log.c | 37 +++++++++---------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index b1131fe..a598955 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -3924,13 +3924,14 @@ xfs_log_force_umount( retval = 0; /* - * Flush the in memory commit item list before marking the log as - * being shut down. We need to do it in this order to ensure all the - * completed transactions are flushed to disk with the xfs_log_force() - * call below. + * Flush all the completed transactions to disk before marking the log + * being shut down. We need to do it in this order to ensure that + * completed operations are safely on disk before we shut down, and that + * we don't have to issue any buffer IO after the shutdown flags are set + * to guarantee this. */ if (!logerror) - xlog_cil_force(log); + _xfs_log_force(mp, XFS_LOG_SYNC, NULL); /* * mark the filesystem and the as in a shutdown state and wake @@ -3942,18 +3943,11 @@ xfs_log_force_umount( XFS_BUF_DONE(mp->m_sb_bp); /* - * This flag is sort of redundant because of the mount flag, but - * it's good to maintain the separation between the log and the rest - * of XFS. + * Mark the log and the iclogs with IO error flags to prevent any + * further log IO from being issued or completed. */ log->l_flags |= XLOG_IO_ERROR; - - /* - * If we hit a log error, we want to mark all the iclogs IOERROR - * while we're still holding the loglock. - */ - if (logerror) - retval = xlog_state_ioerror(log); + retval = xlog_state_ioerror(log); spin_unlock(&log->l_icloglock); /* @@ -3966,19 +3960,6 @@ xfs_log_force_umount( xlog_grant_head_wake_all(&log->l_reserve_head); xlog_grant_head_wake_all(&log->l_write_head); - if (!(log->l_iclog->ic_state & XLOG_STATE_IOERROR)) { - ASSERT(!logerror); - /* - * Force the incore logs to disk before shutting the - * log down completely. - */ - _xfs_log_force(mp, XFS_LOG_SYNC, NULL); - - spin_lock(&log->l_icloglock); - retval = xlog_state_ioerror(log); - spin_unlock(&log->l_icloglock); - } - /* * Wake up everybody waiting on xfs_log_force. Wake the CIL push first * as if the log writes were completed. The abort handling in the log -- 2.0.0 From dave@fromorbit.com Thu Sep 25 07:34:46 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 1D41F7F9B for ; Thu, 25 Sep 2014 07:34:46 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id F19328F8050 for ; Thu, 25 Sep 2014 05:34:45 -0700 (PDT) X-ASG-Debug-ID: 1411648482-04cb6c50e51ff7b0002-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id 1m4hw8tyIOpBoXww for ; Thu, 25 Sep 2014 05:34:44 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoEXAIULJFR5LHimPGdsb2JhbABggw6BKoc4rnABAQEBAQEGnQ4XAQYBAQEBODmEBAEFJy8zCBgxOQMHFBmIPcMDhhKOXgW2bisvgkoBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 22:04:25 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XX8Fb-0006nB-ST for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XX8Fb-0007gU-RL for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 03/11] xfs: synchronous buffer IO needs a reference Date: Thu, 25 Sep 2014 22:34:13 +1000 X-ASG-Orig-Subj: [PATCH 03/11] xfs: synchronous buffer IO needs a reference Message-Id: <1411648461-29003-4-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411648461-29003-1-git-send-email-david@fromorbit.com> References: <1411648461-29003-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411648484 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9861 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner When synchronous IO runs IO completion work, it does so without an IO reference or a hold reference on the buffer. The IO "hold reference" is owned by the submitter, and released when the submission is complete. The IO reference is released when both the submitter and the bio end_io processing is run, and so if the io completion work is run from IO completion context, it is run without an IO reference. Hence we can get the situation where the submitter can submit the IO, see an error on the buffer and unlock and free the buffer while there is still IO in progress. This leads to use-after-free and memory corruption. Fix this by taking a "sync IO hold" reference that is owned by the IO and not released until after the buffer completion calls are run to wake up synchronous waiters. This means that the buffer will not be freed in any circumstance until all IO processing is completed. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_buf.c | 51 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index f1bd238..5d8d2e1 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1019,6 +1019,9 @@ xfs_buf_iodone_work( else { ASSERT(read && bp->b_ops); complete(&bp->b_iowait); + + /* release the !XBF_ASYNC ref now we are done. */ + xfs_buf_rele(bp); } } @@ -1044,6 +1047,7 @@ xfs_buf_ioend( } else { bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_READ_AHEAD); complete(&bp->b_iowait); + xfs_buf_rele(bp); } } @@ -1086,8 +1090,11 @@ xfs_bioerror( xfs_buf_ioerror(bp, -EIO); /* - * We're calling xfs_buf_ioend, so delete XBF_DONE flag. + * We're calling xfs_buf_ioend, so delete XBF_DONE flag. For + * sync IO, xfs_buf_ioend is going to remove a ref here. */ + if (!(bp->b_flags & XBF_ASYNC)) + xfs_buf_hold(bp); XFS_BUF_UNREAD(bp); XFS_BUF_UNDONE(bp); xfs_buf_stale(bp); @@ -1383,22 +1390,48 @@ xfs_buf_iorequest( if (bp->b_flags & XBF_WRITE) xfs_buf_wait_unpin(bp); + + /* + * Take references to the buffer. For XBF_ASYNC buffers, holding a + * reference for as long as submission takes is all that is necessary + * here. The IO inherits the lock and hold count from the submitter, + * and these are release during IO completion processing. Taking a hold + * over submission ensures that the buffer is not freed until we have + * completed all processing, regardless of when IO errors occur or are + * reported. + * + * However, for synchronous IO, the IO does not inherit the submitters + * reference count, nor the buffer lock. Hence we need to take an extra + * reference to the buffer for the for the IO context so that we can + * guarantee the buffer is not freed until all IO completion processing + * is done. Otherwise the caller can drop their reference while the IO + * is still in progress and hence trigger a use-after-free situation. + */ xfs_buf_hold(bp); + if (!(bp->b_flags & XBF_ASYNC)) + xfs_buf_hold(bp); + /* - * Set the count to 1 initially, this will stop an I/O - * completion callout which happens before we have started - * all the I/O from calling xfs_buf_ioend too early. + * Set the count to 1 initially, this will stop an I/O completion + * callout which happens before we have started all the I/O from calling + * xfs_buf_ioend too early. */ atomic_set(&bp->b_io_remaining, 1); _xfs_buf_ioapply(bp); + /* - * If _xfs_buf_ioapply failed, we'll get back here with - * only the reference we took above. _xfs_buf_ioend will - * drop it to zero, so we'd better not queue it for later, - * or we'll free it before it's done. + * If _xfs_buf_ioapply failed or we are doing synchronous IO that + * completes extremely quickly, we can get back here with only the IO + * reference we took above. _xfs_buf_ioend will drop it to zero. Run + * completion processing synchronously so that we don't return to the + * caller with completion still pending. This avoids unnecessary context + * switches associated with the end_io workqueue. */ - _xfs_buf_ioend(bp, bp->b_error ? 0 : 1); + if (bp->b_error || !(bp->b_flags & XBF_ASYNC)) + _xfs_buf_ioend(bp, 0); + else + _xfs_buf_ioend(bp, 1); xfs_buf_rele(bp); } -- 2.0.0 From dave@fromorbit.com Thu Sep 25 07:34:48 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 25CD17FA6 for ; Thu, 25 Sep 2014 07:34:48 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id B5653AC009 for ; Thu, 25 Sep 2014 05:34:47 -0700 (PDT) X-ASG-Debug-ID: 1411648483-04cbb0730225ec90002-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id aD90h1U3RaxV9r4e for ; Thu, 25 Sep 2014 05:34:45 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AlFsAIULJFR5LHimPGdsb2JhbABggw5TV7YQAgoMAQEBAQEBBnIBhGqOWYhYFwEGAQEBATg5hGA7gQIDB4hqDp0HpW6GEod5gjCENQWWGpNDimMBgi0rLwGCSQEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 22:04:25 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XX8Fb-0006n8-Qs for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XX8Fb-0007gH-Pf for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 00/11 v2] xfs: clean up xfs_buf io interfaces Date: Thu, 25 Sep 2014 22:34:10 +1000 X-ASG-Orig-Subj: [PATCH 00/11 v2] xfs: clean up xfs_buf io interfaces Message-Id: <1411648461-29003-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411648485 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9862 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi folks, This is an updated version of the patch set I first posted here: http://oss.sgi.com/archives/xfs/2014-08/msg00203.html There are a few changes in the patchset as a result of review comments and bugs that I found. Version 2: - change shutdown log force code so that the log IO is done before we mark both the filesystem and the log as being shut down. (prevents a godown regression in xfstests introduced by having xfs_buf_submit() check for shutdown) - moved the delwri submission rework to the start of the patch set - moved reference count fixups in error handling to the patch that introduced the new reference counting. - dropped the xfs_trans_buf_read rework patch; it can be done at a later time after checking whether parts of the code are still needed or not. - added Christoph's xfs_zero_remaining_bytes simplification - reworked the error handling cleanups for xfs_buf_read_uncached - updated several comments -Dave. From dave@fromorbit.com Thu Sep 25 07:34:48 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 14C607FA5 for ; Thu, 25 Sep 2014 07:34:48 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 88F7AAC007 for ; Thu, 25 Sep 2014 05:34:47 -0700 (PDT) X-ASG-Debug-ID: 1411648482-04cb6c50e51ff7b0003-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id LHeAM0XABcCDjqmb for ; Thu, 25 Sep 2014 05:34:45 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoEXAIULJFR5LHimPGdsb2JhbABggw6BKoc4rnABAQEBAQEGnQ4XAQYBAQEBODmEBAEFJy8zCBgxOQMHFBmIPcMDhhKKKYQ1BYYmozeNESsvgkoBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 22:04:25 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XX8Fb-0006nE-U2 for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XX8Fb-0007gj-Sz for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 06/11] xfs: kill xfs_bdstrat_cb Date: Thu, 25 Sep 2014 22:34:16 +1000 X-ASG-Orig-Subj: [PATCH 06/11] xfs: kill xfs_bdstrat_cb Message-Id: <1411648461-29003-7-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411648461-29003-1-git-send-email-david@fromorbit.com> References: <1411648461-29003-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411648485 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9861 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner Only has two callers, and is just a shutdown check and error handler around xfs_buf_iorequest. However, the error handling is a mess of read and write semantics, and both internal callers only call it for writes. Hence kill the wrapper, and follow up with a patch to sanitise the error handling. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_buf.c | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index a8f4a39..411111a 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1146,27 +1146,6 @@ xfs_bioerror_relse( return -EIO; } -STATIC int -xfs_bdstrat_cb( - struct xfs_buf *bp) -{ - if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { - trace_xfs_bdstrat_shut(bp, _RET_IP_); - /* - * Metadata write that didn't get logged but - * written delayed anyway. These aren't associated - * with a transaction, and can be ignored. - */ - if (!bp->b_iodone && !XFS_BUF_ISREAD(bp)) - return xfs_bioerror_relse(bp); - else - return xfs_bioerror(bp); - } - - xfs_buf_iorequest(bp); - return 0; -} - int xfs_bwrite( struct xfs_buf *bp) @@ -1178,7 +1157,20 @@ xfs_bwrite( bp->b_flags |= XBF_WRITE; bp->b_flags &= ~(XBF_ASYNC | XBF_READ | _XBF_DELWRI_Q | XBF_WRITE_FAIL); - xfs_bdstrat_cb(bp); + if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { + trace_xfs_bdstrat_shut(bp, _RET_IP_); + + /* + * Metadata write that didn't get logged but written anyway. + * These aren't associated with a transaction, and can be + * ignored. + */ + if (!bp->b_iodone) + return xfs_bioerror_relse(bp); + return xfs_bioerror(bp); + } + + xfs_buf_iorequest(bp); error = xfs_buf_iowait(bp); if (error) { @@ -1861,7 +1853,17 @@ __xfs_buf_delwri_submit( xfs_buf_hold(bp); else list_del_init(&bp->b_list); - xfs_bdstrat_cb(bp); + + if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { + trace_xfs_bdstrat_shut(bp, _RET_IP_); + + if (!bp->b_iodone) + xfs_bioerror_relse(bp); + else + xfs_bioerror(bp); + continue; + } + xfs_buf_iorequest(bp); } blk_finish_plug(&plug); -- 2.0.0 From dave@fromorbit.com Thu Sep 25 07:34:48 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_FRT_FOLLOW2 autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 784617FA5 for ; Thu, 25 Sep 2014 07:34:48 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 5DC648F8039 for ; Thu, 25 Sep 2014 05:34:48 -0700 (PDT) X-ASG-Debug-ID: 1411648482-04cb6c50e51ff7b0004-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id yaIA8dymPJsXQSQo for ; Thu, 25 Sep 2014 05:34:47 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoEXAIULJFR5LHimPGdsb2JhbABggw6BKoc4rnABAQEBAQEGnQ4XAQYBAQEBODmEBAEFJy8zCBgxOQMHFBmIPcMDhhKKKYQ1BYYmozeNESsvgkoBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 22:04:25 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XX8Fc-0006nL-0F for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:24 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XX8Fb-0007h8-VQ for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 11/11] xfs: simplify xfs_zero_remaining_bytes Date: Thu, 25 Sep 2014 22:34:21 +1000 X-ASG-Orig-Subj: [PATCH 11/11] xfs: simplify xfs_zero_remaining_bytes Message-Id: <1411648461-29003-12-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411648461-29003-1-git-send-email-david@fromorbit.com> References: <1411648461-29003-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411648486 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9861 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Christoph Hellwig xfs_zero_remaining_bytes() open codes a log of buffer manupulations to do a read forllowed by a write. It can simply be replaced by an uncached read followed by a xfs_bwrite() call. [Christoph, can I get your sign-off for this?] Signed-off-by: Dave Chinner --- fs/xfs/xfs_bmap_util.c | 44 ++++++++++++++------------------------------ 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 41d9488..c2aaa58 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1122,14 +1122,6 @@ xfs_zero_remaining_bytes( if (endoff > XFS_ISIZE(ip)) endoff = XFS_ISIZE(ip); - bp = xfs_buf_get_uncached(XFS_IS_REALTIME_INODE(ip) ? - mp->m_rtdev_targp : mp->m_ddev_targp, - BTOBB(mp->m_sb.sb_blocksize), 0); - if (!bp) - return -ENOMEM; - - xfs_buf_unlock(bp); - for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { uint lock_mode; @@ -1152,32 +1144,24 @@ xfs_zero_remaining_bytes( ASSERT(imap.br_startblock != DELAYSTARTBLOCK); if (imap.br_state == XFS_EXT_UNWRITTEN) continue; - XFS_BUF_UNDONE(bp); - XFS_BUF_UNWRITE(bp); - XFS_BUF_READ(bp); - XFS_BUF_SET_ADDR(bp, xfs_fsb_to_db(ip, imap.br_startblock)); - error = xfs_buf_submit_wait(bp); - if (error) { - xfs_buf_ioerror_alert(bp, - "xfs_zero_remaining_bytes(read)"); - break; - } + error = xfs_buf_read_uncached(XFS_IS_REALTIME_INODE(ip) ? + mp->m_rtdev_targp : mp->m_ddev_targp, + xfs_fsb_to_db(ip, imap.br_startblock), + BTOBB(mp->m_sb.sb_blocksize), + 0, &bp, NULL); + if (error) + return error; + memset(bp->b_addr + - (offset - XFS_FSB_TO_B(mp, imap.br_startoff)), - 0, lastoffset - offset + 1); - XFS_BUF_UNDONE(bp); - XFS_BUF_UNREAD(bp); - XFS_BUF_WRITE(bp); + (offset - XFS_FSB_TO_B(mp, imap.br_startoff)), + 0, lastoffset - offset + 1); - error = xfs_buf_submit_wait(bp); - if (error) { - xfs_buf_ioerror_alert(bp, - "xfs_zero_remaining_bytes(write)"); - break; - } + error = xfs_bwrite(bp); + xfs_buf_relse(bp); + if (error) + return error; } - xfs_buf_free(bp); return error; } -- 2.0.0 From dave@fromorbit.com Thu Sep 25 07:34:49 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id F2DF47F9E for ; Thu, 25 Sep 2014 07:34:48 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id C4BFE304059 for ; Thu, 25 Sep 2014 05:34:48 -0700 (PDT) X-ASG-Debug-ID: 1411648485-04bdf003a0230ae0002-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id foB6ox3rnIyimH6H for ; Thu, 25 Sep 2014 05:34:47 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoEXAIULJFR5LHimPGdsb2JhbABggw6BKoc4rnABAQEBAQEGnQ4XAQYBAQEBODmEBAEFJy8zCBgxOQMHFBmIPcMDhhKKKYQ1BYYmozeNESsvgkoBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 22:04:26 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XX8Fb-0006nG-V9 for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:24 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XX8Fb-0007gt-U2 for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 08/11] xfs: kill xfs_bioerror_relse Date: Thu, 25 Sep 2014 22:34:18 +1000 X-ASG-Orig-Subj: [PATCH 08/11] xfs: kill xfs_bioerror_relse Message-Id: <1411648461-29003-9-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411648461-29003-1-git-send-email-david@fromorbit.com> References: <1411648461-29003-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411648486 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9862 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner There is only one caller now - xfs_trans_read_buf_map() - and it has very well defined call semantics - read, synchronous, and b_iodone is NULL. Hence it's pretty clear what error handling is necessary for this case. The bigger problem of untangling xfs_trans_read_buf_map error handling is left to a future patch. Signed-off-by: Dave Chinner --- fs/xfs/xfs_buf.c | 39 --------------------------------------- fs/xfs/xfs_buf.h | 2 -- fs/xfs/xfs_trans_buf.c | 9 ++++++--- 3 files changed, 6 insertions(+), 44 deletions(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index cc6a558..4696ff5 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1074,45 +1074,6 @@ xfs_buf_ioerror_alert( (__uint64_t)XFS_BUF_ADDR(bp), func, -bp->b_error, bp->b_length); } -/* - * Same as xfs_bioerror, except that we are releasing the buffer - * here ourselves, and avoiding the xfs_buf_ioend call. - * This is meant for userdata errors; metadata bufs come with - * iodone functions attached, so that we can track down errors. - */ -int -xfs_bioerror_relse( - struct xfs_buf *bp) -{ - int64_t fl = bp->b_flags; - /* - * No need to wait until the buffer is unpinned. - * We aren't flushing it. - * - * chunkhold expects B_DONE to be set, whether - * we actually finish the I/O or not. We don't want to - * change that interface. - */ - XFS_BUF_UNREAD(bp); - XFS_BUF_DONE(bp); - xfs_buf_stale(bp); - bp->b_iodone = NULL; - if (!(fl & XBF_ASYNC)) { - /* - * Mark b_error and B_ERROR _both_. - * Lot's of chunkcache code assumes that. - * There's no reason to mark error for - * ASYNC buffers. - */ - xfs_buf_ioerror(bp, -EIO); - complete(&bp->b_iowait); - } else { - xfs_buf_relse(bp); - } - - return -EIO; -} - int xfs_bwrite( struct xfs_buf *bp) diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 44db8cd..d8f57f6 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -297,8 +297,6 @@ extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *, #define xfs_buf_zero(bp, off, len) \ xfs_buf_iomove((bp), (off), (len), NULL, XBRW_ZERO) -extern int xfs_bioerror_relse(struct xfs_buf *); - /* Buffer Utility Routines */ extern xfs_caddr_t xfs_buf_offset(xfs_buf_t *, size_t); diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index 96c898e..db4be5b 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c @@ -324,11 +324,14 @@ xfs_trans_read_buf_map( */ if (XFS_FORCED_SHUTDOWN(mp)) { trace_xfs_bdstrat_shut(bp, _RET_IP_); - xfs_bioerror_relse(bp); - } else { - xfs_buf_iorequest(bp); + bp->b_flags &= ~(XBF_READ | XBF_DONE); + xfs_buf_ioerror(bp, -EIO); + xfs_buf_stale(bp); + xfs_buf_relse(bp); + return -EIO; } + xfs_buf_iorequest(bp); error = xfs_buf_iowait(bp); if (error) { xfs_buf_ioerror_alert(bp, __func__); -- 2.0.0 From dave@fromorbit.com Thu Sep 25 07:34:48 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 61CF07F9F for ; Thu, 25 Sep 2014 07:34:48 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 00F95AC00A for ; Thu, 25 Sep 2014 05:34:47 -0700 (PDT) X-ASG-Debug-ID: 1411648485-04bdf003a0230ae0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id t1DptmG3u0PjhAun for ; Thu, 25 Sep 2014 05:34:46 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoEXAIULJFR5LHimPGdsb2JhbABggw6BKoc4rnABAQEBAQEGnQ4XAQYBAQEBODmEBAEFJy8zCBgxOQMHFBmIPcMDhhKKKYQ1BaldjRErL4EIJIEeAQEB Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 22:04:25 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XX8Fb-0006nD-TZ for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XX8Fb-0007ge-SW for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 05/11] xfs: rework xfs_buf_bio_endio error handling Date: Thu, 25 Sep 2014 22:34:15 +1000 X-ASG-Orig-Subj: [PATCH 05/11] xfs: rework xfs_buf_bio_endio error handling Message-Id: <1411648461-29003-6-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411648461-29003-1-git-send-email-david@fromorbit.com> References: <1411648461-29003-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411648485 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9862 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner Currently the report of a bio error from completion immediately marks the buffer with an error. The issue is that this is racy w.r.t. synchronous IO - the submitter can see b_error being set before the IO is complete, and hence we cannot differentiate between submission failures and completion failures. Add an internal b_io_error field protected by the b_lock to catch IO completion errors, and only propagate that to the buffer during final IO completion handling. Hence we can tell in xfs_buf_iorequest if we've had a submission failure bey checking bp->b_error before dropping our b_io_remaining reference - that reference will prevent b_io_error values from being propagated to b_error in the event that completion races with submission. Signed-off-by: Dave Chinner --- fs/xfs/xfs_buf.c | 18 ++++++++++++++++-- fs/xfs/xfs_buf.h | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 08f9fca..a8f4a39 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1008,6 +1008,13 @@ xfs_buf_ioend( bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_READ_AHEAD); + /* + * Pull in IO completion errors now. We are guaranteed to be running + * single threaded, so we don't need the lock to read b_io_error. + */ + if (!bp->b_error && bp->b_io_error) + xfs_buf_ioerror(bp, bp->b_io_error); + /* Only validate buffers that were read without errors */ if (read && !bp->b_error && bp->b_ops) { ASSERT(!bp->b_iodone); @@ -1192,8 +1199,12 @@ xfs_buf_bio_end_io( * don't overwrite existing errors - otherwise we can lose errors on * buffers that require multiple bios to complete. */ - if (!bp->b_error) - xfs_buf_ioerror(bp, error); + if (error) { + spin_lock(&bp->b_lock); + if (!bp->b_io_error) + bp->b_io_error = error; + spin_unlock(&bp->b_lock); + } if (!bp->b_error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ)) invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp)); @@ -1379,6 +1390,9 @@ xfs_buf_iorequest( if (bp->b_flags & XBF_WRITE) xfs_buf_wait_unpin(bp); + /* clear the internal error state to avoid spurious errors */ + bp->b_io_error = 0; + /* * Take references to the buffer. For XBF_ASYNC buffers, holding a * reference for as long as submission takes is all that is necessary diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 4585c15..44db8cd 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -158,6 +158,7 @@ typedef struct xfs_buf { struct list_head b_lru; /* lru list */ spinlock_t b_lock; /* internal state lock */ unsigned int b_state; /* internal state flags */ + int b_io_error; /* internal IO error state */ wait_queue_head_t b_waiters; /* unpin waiters */ struct list_head b_list; struct xfs_perag *b_pag; /* contains rbtree root */ -- 2.0.0 From dave@fromorbit.com Thu Sep 25 07:34:50 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 024A67FAD for ; Thu, 25 Sep 2014 07:34:49 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id D8BF68F8039 for ; Thu, 25 Sep 2014 05:34:49 -0700 (PDT) X-ASG-Debug-ID: 1411648482-04cb6c50e51ff7b0005-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id 0JF4xtGR30htdU6T for ; Thu, 25 Sep 2014 05:34:48 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoEXAIULJFR5LHimPGdsb2JhbABggw6BKoc4rnABAQEBAQEGnQ4XAQYBAQEBODmEBAEFJy8zCBgxOQMHFBmIPcMDhhKOXgWGJqM3jRErL4JKAQEB Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 22:04:26 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XX8Fb-0006nF-Ug for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XX8Fb-0007go-TQ for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 07/11] xfs: xfs_bioerror can die. Date: Thu, 25 Sep 2014 22:34:17 +1000 X-ASG-Orig-Subj: [PATCH 07/11] xfs: xfs_bioerror can die. Message-Id: <1411648461-29003-8-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411648461-29003-1-git-send-email-david@fromorbit.com> References: <1411648461-29003-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411648487 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9861 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner Internal buffer write error handling is a mess due to the unnatural split between xfs_bioerror and xfs_bioerror_relse(). xfs_bwrite() only does sync IO and determines the handler to call based on b_iodone, so for this caller the only difference between xfs_bioerror() and xfs_bioerror_release() is the XBF_DONE flag. We don't care what the XBF_DONE flag state is because we stale the buffer in both paths - the next buffer lookup will clear XBF_DONE because XBF_STALE is set. Hence we can use common error handling for xfs_bwrite(). __xfs_buf_delwri_submit() is a similar - it's only ever called on writes - all sync or async - and again there's no reason to handle them any differently at all. Clean up the nasty error handling and remove xfs_bioerror(). Signed-off-by: Dave Chinner --- fs/xfs/xfs_buf.c | 58 ++++++++++++-------------------------------------------- 1 file changed, 12 insertions(+), 46 deletions(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 411111a..cc6a558 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1075,39 +1075,6 @@ xfs_buf_ioerror_alert( } /* - * Called when we want to stop a buffer from getting written or read. - * We attach the EIO error, muck with its flags, and call xfs_buf_ioend - * so that the proper iodone callbacks get called. - */ -STATIC int -xfs_bioerror( - xfs_buf_t *bp) -{ -#ifdef XFSERRORDEBUG - ASSERT(XFS_BUF_ISREAD(bp) || bp->b_iodone); -#endif - - /* - * No need to wait until the buffer is unpinned, we aren't flushing it. - */ - xfs_buf_ioerror(bp, -EIO); - - /* - * We're calling xfs_buf_ioend, so delete XBF_DONE flag. For - * sync IO, xfs_buf_ioend is going to remove a ref here. - */ - if (!(bp->b_flags & XBF_ASYNC)) - xfs_buf_hold(bp); - XFS_BUF_UNREAD(bp); - XFS_BUF_UNDONE(bp); - xfs_buf_stale(bp); - - xfs_buf_ioend(bp); - - return -EIO; -} - -/* * Same as xfs_bioerror, except that we are releasing the buffer * here ourselves, and avoiding the xfs_buf_ioend call. * This is meant for userdata errors; metadata bufs come with @@ -1155,19 +1122,19 @@ xfs_bwrite( ASSERT(xfs_buf_islocked(bp)); bp->b_flags |= XBF_WRITE; - bp->b_flags &= ~(XBF_ASYNC | XBF_READ | _XBF_DELWRI_Q | XBF_WRITE_FAIL); + bp->b_flags &= ~(XBF_ASYNC | XBF_READ | _XBF_DELWRI_Q | + XBF_WRITE_FAIL | XBF_DONE); if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { trace_xfs_bdstrat_shut(bp, _RET_IP_); - /* - * Metadata write that didn't get logged but written anyway. - * These aren't associated with a transaction, and can be - * ignored. - */ - if (!bp->b_iodone) - return xfs_bioerror_relse(bp); - return xfs_bioerror(bp); + xfs_buf_ioerror(bp, -EIO); + xfs_buf_stale(bp); + + /* sync IO, xfs_buf_ioend is going to remove a ref here */ + xfs_buf_hold(bp); + xfs_buf_ioend(bp); + return -EIO; } xfs_buf_iorequest(bp); @@ -1857,10 +1824,9 @@ __xfs_buf_delwri_submit( if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { trace_xfs_bdstrat_shut(bp, _RET_IP_); - if (!bp->b_iodone) - xfs_bioerror_relse(bp); - else - xfs_bioerror(bp); + xfs_buf_ioerror(bp, -EIO); + xfs_buf_stale(bp); + xfs_buf_ioend(bp); continue; } xfs_buf_iorequest(bp); -- 2.0.0 From dave@fromorbit.com Thu Sep 25 07:34:50 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CE1207FA7 for ; Thu, 25 Sep 2014 07:34:49 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5BCACAC003 for ; Thu, 25 Sep 2014 05:34:49 -0700 (PDT) X-ASG-Debug-ID: 1411648483-04cbb0730225ec90003-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id 5HtDNKE0xPjBHaIl for ; Thu, 25 Sep 2014 05:34:46 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoEXAIULJFR5LHimPGdsb2JhbABggw6BKoc4rnABAQEBAQEGnQ4XAQYBAQEBODmEBAEFJy8zCBgxOQMHFBmIPcMDhhKOXgWGJqM3jRErL4EIJIEeAQEB Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 22:04:25 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XX8Fb-0006nC-T6 for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XX8Fb-0007gZ-Rt for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 04/11] xfs: xfs_buf_ioend and xfs_buf_iodone_work duplicate functionality Date: Thu, 25 Sep 2014 22:34:14 +1000 X-ASG-Orig-Subj: [PATCH 04/11] xfs: xfs_buf_ioend and xfs_buf_iodone_work duplicate functionality Message-Id: <1411648461-29003-5-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411648461-29003-1-git-send-email-david@fromorbit.com> References: <1411648461-29003-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411648486 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9862 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner We do some work in xfs_buf_ioend, and some work in xfs_buf_iodone_work, but much of that functionality is the same. This work can all be done in a single function, leaving xfs_buf_iodone just a wrapper to determine if we should execute it by workqueue or directly. hence rename xfs_buf_iodone_work to xfs_buf_ioend(), and add a new xfs_buf_ioend_async() for places that need async processing. Signed-off-by: Dave Chinner --- fs/xfs/xfs_buf.c | 88 +++++++++++++++++++++--------------------------- fs/xfs/xfs_buf.h | 2 +- fs/xfs/xfs_buf_item.c | 4 +-- fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_log.c | 2 +- fs/xfs/xfs_log_recover.c | 2 +- 6 files changed, 45 insertions(+), 55 deletions(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 5d8d2e1..08f9fca 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -998,26 +998,30 @@ xfs_buf_wait_unpin( * Buffer Utility Routines */ -STATIC void -xfs_buf_iodone_work( - struct work_struct *work) +void +xfs_buf_ioend( + struct xfs_buf *bp) { - struct xfs_buf *bp = - container_of(work, xfs_buf_t, b_iodone_work); - bool read = !!(bp->b_flags & XBF_READ); + bool read = bp->b_flags & XBF_READ; + + trace_xfs_buf_iodone(bp, _RET_IP_); bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_READ_AHEAD); - /* only validate buffers that were read without errors */ - if (read && bp->b_ops && !bp->b_error && (bp->b_flags & XBF_DONE)) + /* Only validate buffers that were read without errors */ + if (read && !bp->b_error && bp->b_ops) { + ASSERT(!bp->b_iodone); bp->b_ops->verify_read(bp); + } + + if (!bp->b_error) + bp->b_flags |= XBF_DONE; if (bp->b_iodone) (*(bp->b_iodone))(bp); else if (bp->b_flags & XBF_ASYNC) xfs_buf_relse(bp); else { - ASSERT(read && bp->b_ops); complete(&bp->b_iowait); /* release the !XBF_ASYNC ref now we are done. */ @@ -1025,30 +1029,22 @@ xfs_buf_iodone_work( } } -void -xfs_buf_ioend( - struct xfs_buf *bp, - int schedule) +static void +xfs_buf_ioend_work( + struct work_struct *work) { - bool read = !!(bp->b_flags & XBF_READ); - - trace_xfs_buf_iodone(bp, _RET_IP_); + struct xfs_buf *bp = + container_of(work, xfs_buf_t, b_iodone_work); - if (bp->b_error == 0) - bp->b_flags |= XBF_DONE; + xfs_buf_ioend(bp); +} - if (bp->b_iodone || (read && bp->b_ops) || (bp->b_flags & XBF_ASYNC)) { - if (schedule) { - INIT_WORK(&bp->b_iodone_work, xfs_buf_iodone_work); - queue_work(xfslogd_workqueue, &bp->b_iodone_work); - } else { - xfs_buf_iodone_work(&bp->b_iodone_work); - } - } else { - bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_READ_AHEAD); - complete(&bp->b_iowait); - xfs_buf_rele(bp); - } +void +xfs_buf_ioend_async( + struct xfs_buf *bp) +{ + INIT_WORK(&bp->b_iodone_work, xfs_buf_ioend_work); + queue_work(xfslogd_workqueue, &bp->b_iodone_work); } void @@ -1099,7 +1095,7 @@ xfs_bioerror( XFS_BUF_UNDONE(bp); xfs_buf_stale(bp); - xfs_buf_ioend(bp, 0); + xfs_buf_ioend(bp); return -EIO; } @@ -1186,15 +1182,6 @@ xfs_bwrite( } STATIC void -_xfs_buf_ioend( - xfs_buf_t *bp, - int schedule) -{ - if (atomic_dec_and_test(&bp->b_io_remaining) == 1) - xfs_buf_ioend(bp, schedule); -} - -STATIC void xfs_buf_bio_end_io( struct bio *bio, int error) @@ -1211,7 +1198,8 @@ xfs_buf_bio_end_io( if (!bp->b_error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ)) invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp)); - _xfs_buf_ioend(bp, 1); + if (atomic_dec_and_test(&bp->b_io_remaining) == 1) + xfs_buf_ioend_async(bp); bio_put(bio); } @@ -1423,15 +1411,17 @@ xfs_buf_iorequest( /* * If _xfs_buf_ioapply failed or we are doing synchronous IO that * completes extremely quickly, we can get back here with only the IO - * reference we took above. _xfs_buf_ioend will drop it to zero. Run - * completion processing synchronously so that we don't return to the - * caller with completion still pending. This avoids unnecessary context - * switches associated with the end_io workqueue. + * reference we took above. If we drop it to zero, run completion + * processing synchronously so that we don't return to the caller with + * completion still pending. This avoids unnecessary context switches + * associated with the end_io workqueue. */ - if (bp->b_error || !(bp->b_flags & XBF_ASYNC)) - _xfs_buf_ioend(bp, 0); - else - _xfs_buf_ioend(bp, 1); + if (atomic_dec_and_test(&bp->b_io_remaining) == 1) { + if (bp->b_error || !(bp->b_flags & XBF_ASYNC)) + xfs_buf_ioend(bp); + else + xfs_buf_ioend_async(bp); + } xfs_buf_rele(bp); } diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index c753183..4585c15 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -286,7 +286,7 @@ extern void xfs_buf_unlock(xfs_buf_t *); /* Buffer Read and Write Routines */ extern int xfs_bwrite(struct xfs_buf *bp); -extern void xfs_buf_ioend(xfs_buf_t *, int); +extern void xfs_buf_ioend(struct xfs_buf *bp); extern void xfs_buf_ioerror(xfs_buf_t *, int); extern void xfs_buf_ioerror_alert(struct xfs_buf *, const char *func); extern void xfs_buf_iorequest(xfs_buf_t *); diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 30fa5db..3916384 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -491,7 +491,7 @@ xfs_buf_item_unpin( xfs_buf_ioerror(bp, -EIO); XFS_BUF_UNDONE(bp); xfs_buf_stale(bp); - xfs_buf_ioend(bp, 0); + xfs_buf_ioend(bp); } } @@ -1115,7 +1115,7 @@ do_callbacks: xfs_buf_do_callbacks(bp); bp->b_fspriv = NULL; bp->b_iodone = NULL; - xfs_buf_ioend(bp, 0); + xfs_buf_ioend(bp); } /* diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index c92cb48..e5bbc1f 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3062,7 +3062,7 @@ cluster_corrupt_out: XFS_BUF_UNDONE(bp); xfs_buf_stale(bp); xfs_buf_ioerror(bp, -EIO); - xfs_buf_ioend(bp, 0); + xfs_buf_ioend(bp); } else { xfs_buf_stale(bp); xfs_buf_relse(bp); diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index a598955..b5170e5 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1689,7 +1689,7 @@ xlog_bdstrat( if (iclog->ic_state & XLOG_STATE_IOERROR) { xfs_buf_ioerror(bp, -EIO); xfs_buf_stale(bp); - xfs_buf_ioend(bp, 0); + xfs_buf_ioend(bp); /* * It would seem logical to return EIO here, but we rely on * the log state machine to propagate I/O errors instead of diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 29e101f..02ad115 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -383,7 +383,7 @@ xlog_recover_iodone( SHUTDOWN_META_IO_ERROR); } bp->b_iodone = NULL; - xfs_buf_ioend(bp, 0); + xfs_buf_ioend(bp); } /* -- 2.0.0 From dave@fromorbit.com Thu Sep 25 07:34:51 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 73BFD7FB2 for ; Thu, 25 Sep 2014 07:34:50 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4455B304059 for ; Thu, 25 Sep 2014 05:34:50 -0700 (PDT) X-ASG-Debug-ID: 1411648485-04bdf003a0230ae0003-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id u4NZLGkSNQAomsXw for ; Thu, 25 Sep 2014 05:34:48 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoIXAIULJFR5LHimPGdsb2JhbABYCIMOgSqHOK5wAQEBAQEBBp0OFwEGAQEBATg5hAQBBScvMwgYMTkDBxQZiD3DA4YSiTaFKAWGJqM3jRErL4EGAh4EAoEeAQEB Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 22:04:26 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XX8Fb-0006nJ-WC for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:24 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XX8Fb-0007h3-V6 for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 10/11] xfs: check xfs_buf_read_uncached returns correctly Date: Thu, 25 Sep 2014 22:34:20 +1000 X-ASG-Orig-Subj: [PATCH 10/11] xfs: check xfs_buf_read_uncached returns correctly Message-Id: <1411648461-29003-11-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411648461-29003-1-git-send-email-david@fromorbit.com> References: <1411648461-29003-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411648487 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9862 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner xfs_buf_read_uncached() has two failure modes. If can either return NULL or bp->b_error != 0 depending on the type of failure, and not all callers check for both. Fix it up. Signed-off-by: Dave Chinner --- fs/xfs/xfs_buf.c | 18 ++++++++++++---- fs/xfs/xfs_buf.h | 6 +++--- fs/xfs/xfs_fsops.c | 11 +++------- fs/xfs/xfs_mount.c | 58 +++++++++++++++++++++++++--------------------------- fs/xfs/xfs_rtalloc.c | 30 +++++++++++---------------- 5 files changed, 60 insertions(+), 63 deletions(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index d1d3fe6..0ac54a0 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -688,29 +688,39 @@ xfs_buf_readahead_map( * Read an uncached buffer from disk. Allocates and returns a locked * buffer containing the disk contents or nothing. */ -struct xfs_buf * +int xfs_buf_read_uncached( struct xfs_buftarg *target, xfs_daddr_t daddr, size_t numblks, int flags, + struct xfs_buf **bpp, const struct xfs_buf_ops *ops) { struct xfs_buf *bp; + *bpp = NULL; + bp = xfs_buf_get_uncached(target, numblks, flags); if (!bp) - return NULL; + return ENOMEM; /* set up the buffer for a read IO */ ASSERT(bp->b_map_count == 1); - bp->b_bn = daddr; + bp->b_bn = XFS_BUF_DADDR_NULL; /* always null for uncached buffers */ bp->b_maps[0].bm_bn = daddr; bp->b_flags |= XBF_READ; bp->b_ops = ops; xfs_buf_submit_wait(bp); - return bp; + if (bp->b_error) { + int error = bp->b_error; + xfs_buf_relse(bp); + return error; + } + + *bpp = bp; + return 0; } /* diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 0acfc30..82002c0 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -269,9 +269,9 @@ int xfs_buf_associate_memory(struct xfs_buf *bp, void *mem, size_t length); struct xfs_buf *xfs_buf_get_uncached(struct xfs_buftarg *target, size_t numblks, int flags); -struct xfs_buf *xfs_buf_read_uncached(struct xfs_buftarg *target, - xfs_daddr_t daddr, size_t numblks, int flags, - const struct xfs_buf_ops *ops); +int xfs_buf_read_uncached(struct xfs_buftarg *target, xfs_daddr_t daddr, + size_t numblks, int flags, struct xfs_buf **bpp, + const struct xfs_buf_ops *ops); void xfs_buf_hold(struct xfs_buf *bp); /* Releasing Buffers */ diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 126b4b3..ece69c2 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -172,16 +172,11 @@ xfs_growfs_data_private( if ((error = xfs_sb_validate_fsb_count(&mp->m_sb, nb))) return error; dpct = pct - mp->m_sb.sb_imax_pct; - bp = xfs_buf_read_uncached(mp->m_ddev_targp, + error = xfs_buf_read_uncached(mp->m_ddev_targp, XFS_FSB_TO_BB(mp, nb) - XFS_FSS_TO_BB(mp, 1), - XFS_FSS_TO_BB(mp, 1), 0, NULL); - if (!bp) - return -EIO; - if (bp->b_error) { - error = bp->b_error; - xfs_buf_relse(bp); + XFS_FSS_TO_BB(mp, 1), 0, &bp, NULL); + if (error) return error; - } xfs_buf_relse(bp); new = nb; /* use new as a temporary here */ diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 78a2799..2adf6ce 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -300,21 +300,15 @@ xfs_readsb( * access to the superblock. */ reread: - bp = xfs_buf_read_uncached(mp->m_ddev_targp, XFS_SB_DADDR, - BTOBB(sector_size), 0, buf_ops); - if (!bp) { - if (loud) - xfs_warn(mp, "SB buffer read failed"); - return -EIO; - } - if (bp->b_error) { - error = bp->b_error; + error = xfs_buf_read_uncached(mp->m_ddev_targp, XFS_SB_DADDR, + BTOBB(sector_size), 0, &bp, buf_ops); + if (error) { if (loud) xfs_warn(mp, "SB validate failed with error %d.", error); /* bad CRC means corrupted metadata */ if (error == -EFSBADCRC) error = -EFSCORRUPTED; - goto release_buf; + return error; } /* @@ -366,7 +360,8 @@ reread: return 0; release_buf: - xfs_buf_relse(bp); + if (bp) + xfs_buf_relse(bp); return error; } @@ -544,40 +539,43 @@ xfs_set_inoalignment(xfs_mount_t *mp) * Check that the data (and log if separate) is an ok size. */ STATIC int -xfs_check_sizes(xfs_mount_t *mp) +xfs_check_sizes( + struct xfs_mount *mp) { - xfs_buf_t *bp; + struct xfs_buf *bp; xfs_daddr_t d; + int error; d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) { xfs_warn(mp, "filesystem size mismatch detected"); return -EFBIG; } - bp = xfs_buf_read_uncached(mp->m_ddev_targp, + error = xfs_buf_read_uncached(mp->m_ddev_targp, d - XFS_FSS_TO_BB(mp, 1), - XFS_FSS_TO_BB(mp, 1), 0, NULL); - if (!bp) { + XFS_FSS_TO_BB(mp, 1), 0, &bp, NULL); + if (error) { xfs_warn(mp, "last sector read failed"); - return -EIO; + return error; } xfs_buf_relse(bp); - if (mp->m_logdev_targp != mp->m_ddev_targp) { - d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); - if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) { - xfs_warn(mp, "log size mismatch detected"); - return -EFBIG; - } - bp = xfs_buf_read_uncached(mp->m_logdev_targp, + if (mp->m_logdev_targp == mp->m_ddev_targp) + return 0; + + d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); + if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) { + xfs_warn(mp, "log size mismatch detected"); + return -EFBIG; + } + error = xfs_buf_read_uncached(mp->m_logdev_targp, d - XFS_FSB_TO_BB(mp, 1), - XFS_FSB_TO_BB(mp, 1), 0, NULL); - if (!bp) { - xfs_warn(mp, "log device read failed"); - return -EIO; - } - xfs_buf_relse(bp); + XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL); + if (error) { + xfs_warn(mp, "log device read failed"); + return error; } + xfs_buf_relse(bp); return 0; } diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index d45aebe..e1175ea 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -921,16 +921,11 @@ xfs_growfs_rt( /* * Read in the last block of the device, make sure it exists. */ - bp = xfs_buf_read_uncached(mp->m_rtdev_targp, + error = xfs_buf_read_uncached(mp->m_rtdev_targp, XFS_FSB_TO_BB(mp, nrblocks - 1), - XFS_FSB_TO_BB(mp, 1), 0, NULL); - if (!bp) - return -EIO; - if (bp->b_error) { - error = bp->b_error; - xfs_buf_relse(bp); + XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL); + if (error) return error; - } xfs_buf_relse(bp); /* @@ -1184,11 +1179,12 @@ xfs_rtallocate_extent( */ int /* error */ xfs_rtmount_init( - xfs_mount_t *mp) /* file system mount structure */ + struct xfs_mount *mp) /* file system mount structure */ { - xfs_buf_t *bp; /* buffer for last block of subvolume */ - xfs_daddr_t d; /* address of last block of subvolume */ - xfs_sb_t *sbp; /* filesystem superblock copy in mount */ + struct xfs_buf *bp; /* buffer for last block of subvolume */ + struct xfs_sb *sbp; /* filesystem superblock copy in mount */ + xfs_daddr_t d; /* address of last block of subvolume */ + int error; sbp = &mp->m_sb; if (sbp->sb_rblocks == 0) @@ -1214,14 +1210,12 @@ xfs_rtmount_init( (unsigned long long) mp->m_sb.sb_rblocks); return -EFBIG; } - bp = xfs_buf_read_uncached(mp->m_rtdev_targp, + error = xfs_buf_read_uncached(mp->m_rtdev_targp, d - XFS_FSB_TO_BB(mp, 1), - XFS_FSB_TO_BB(mp, 1), 0, NULL); - if (!bp || bp->b_error) { + XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL); + if (error) { xfs_warn(mp, "realtime device size check failed"); - if (bp) - xfs_buf_relse(bp); - return -EIO; + return error; } xfs_buf_relse(bp); return 0; -- 2.0.0 From dave@fromorbit.com Thu Sep 25 07:34:51 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 8F24C7FAD for ; Thu, 25 Sep 2014 07:34:51 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6F8518F8035 for ; Thu, 25 Sep 2014 05:34:51 -0700 (PDT) X-ASG-Debug-ID: 1411648483-04cbb0730225ec90004-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id cwp9ZMbRyhZerw88 for ; Thu, 25 Sep 2014 05:34:48 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoIXAIULJFR5LHimPGdsb2JhbABggw6BKoc4rnABAQEBAQEGnQ4XAQYBAQEBODmEBAEFJy8zCBgxOQMHFBAJiD3DA4YShBiKRgWGJqM3jRErL4JKAQEB Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 25 Sep 2014 22:04:26 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XX8Fb-0006nH-Vp for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:24 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XX8Fb-0007gy-UY for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:34:23 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 09/11] xfs: introduce xfs_buf_submit[_wait] Date: Thu, 25 Sep 2014 22:34:19 +1000 X-ASG-Orig-Subj: [PATCH 09/11] xfs: introduce xfs_buf_submit[_wait] Message-Id: <1411648461-29003-10-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411648461-29003-1-git-send-email-david@fromorbit.com> References: <1411648461-29003-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411648488 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9862 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner There is a lot of cookie-cutter code that looks like: if (shutdown) handle buffer error xfs_buf_iorequest(bp) error = xfs_buf_iowait(bp) if (error) handle buffer error spread through XFS. There's significant complexity now in xfs_buf_iorequest() to specifically handle this sort of synchronous IO pattern, but there's all sorts of nasty surprises in different error handling code dependent on who owns the buffer references and the locks. Pull this pattern into a single helper, where we can hide all the synchronous IO warts and hence make the error handling for all the callers much saner. This removes the need for a special extra reference to protect IO completion processing, as we can now hold a single reference across dispatch and waiting, simplifying the sync IO smeantics and error handling. In doing this, also rename xfs_buf_iorequest to xfs_buf_submit and make it explicitly handle on asynchronous IO. This forces all users to be switched specifically to one interface or the other and removes any ambiguity between how the interfaces are to be used. It also means that xfs_buf_iowait() goes away. For the special case of delwri buffer submission and waiting, we don't need to issue IO synchronously at all. The second pass to cal xfs_buf_iowait() can now just block on xfs_buf_lock() - the buffer will be unlocked when the async IO is complete. This formalises a sane the method of waiting for async IO - take an extra reference, submit the IO, call xfs_buf_lock() when you want to wait for IO completion. i.e.: bp = xfs_buf_find(); xfs_buf_hold(bp); bp->b_flags |= XBF_ASYNC; xfs_buf_iosubmit(bp); xfs_buf_lock(bp) error = bp->b_error; .... xfs_buf_relse(bp); Signed-off-by: Dave Chinner --- fs/xfs/xfs_bmap_util.c | 14 +--- fs/xfs/xfs_buf.c | 169 ++++++++++++++++++++++++++--------------------- fs/xfs/xfs_buf.h | 4 +- fs/xfs/xfs_buf_item.c | 4 +- fs/xfs/xfs_log.c | 2 +- fs/xfs/xfs_log_recover.c | 30 ++++----- fs/xfs/xfs_trace.h | 3 +- fs/xfs/xfs_trans_buf.c | 19 +----- 8 files changed, 117 insertions(+), 128 deletions(-) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index d8b77b5..41d9488 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1157,12 +1157,7 @@ xfs_zero_remaining_bytes( XFS_BUF_READ(bp); XFS_BUF_SET_ADDR(bp, xfs_fsb_to_db(ip, imap.br_startblock)); - if (XFS_FORCED_SHUTDOWN(mp)) { - error = -EIO; - break; - } - xfs_buf_iorequest(bp); - error = xfs_buf_iowait(bp); + error = xfs_buf_submit_wait(bp); if (error) { xfs_buf_ioerror_alert(bp, "xfs_zero_remaining_bytes(read)"); @@ -1175,12 +1170,7 @@ xfs_zero_remaining_bytes( XFS_BUF_UNREAD(bp); XFS_BUF_WRITE(bp); - if (XFS_FORCED_SHUTDOWN(mp)) { - error = -EIO; - break; - } - xfs_buf_iorequest(bp); - error = xfs_buf_iowait(bp); + error = xfs_buf_submit_wait(bp); if (error) { xfs_buf_ioerror_alert(bp, "xfs_zero_remaining_bytes(write)"); diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 4696ff5..d1d3fe6 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -623,10 +623,11 @@ _xfs_buf_read( bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_READ_AHEAD); bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | XBF_READ_AHEAD); - xfs_buf_iorequest(bp); - if (flags & XBF_ASYNC) + if (flags & XBF_ASYNC) { + xfs_buf_submit(bp); return 0; - return xfs_buf_iowait(bp); + } + return xfs_buf_submit_wait(bp); } xfs_buf_t * @@ -708,12 +709,7 @@ xfs_buf_read_uncached( bp->b_flags |= XBF_READ; bp->b_ops = ops; - if (XFS_FORCED_SHUTDOWN(target->bt_mount)) { - xfs_buf_relse(bp); - return NULL; - } - xfs_buf_iorequest(bp); - xfs_buf_iowait(bp); + xfs_buf_submit_wait(bp); return bp; } @@ -1028,12 +1024,8 @@ xfs_buf_ioend( (*(bp->b_iodone))(bp); else if (bp->b_flags & XBF_ASYNC) xfs_buf_relse(bp); - else { + else complete(&bp->b_iowait); - - /* release the !XBF_ASYNC ref now we are done. */ - xfs_buf_rele(bp); - } } static void @@ -1086,21 +1078,7 @@ xfs_bwrite( bp->b_flags &= ~(XBF_ASYNC | XBF_READ | _XBF_DELWRI_Q | XBF_WRITE_FAIL | XBF_DONE); - if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { - trace_xfs_bdstrat_shut(bp, _RET_IP_); - - xfs_buf_ioerror(bp, -EIO); - xfs_buf_stale(bp); - - /* sync IO, xfs_buf_ioend is going to remove a ref here */ - xfs_buf_hold(bp); - xfs_buf_ioend(bp); - return -EIO; - } - - xfs_buf_iorequest(bp); - - error = xfs_buf_iowait(bp); + error = xfs_buf_submit_wait(bp); if (error) { xfs_force_shutdown(bp->b_target->bt_mount, SHUTDOWN_META_IO_ERROR); @@ -1209,7 +1187,7 @@ next_chunk: } else { /* * This is guaranteed not to be the last io reference count - * because the caller (xfs_buf_iorequest) holds a count itself. + * because the caller (xfs_buf_submit) holds a count itself. */ atomic_dec(&bp->b_io_remaining); xfs_buf_ioerror(bp, -EIO); @@ -1299,13 +1277,29 @@ _xfs_buf_ioapply( blk_finish_plug(&plug); } +/* + * Asynchronous IO submission path. This transfers the buffer lock ownership and + * the current reference to the IO. It is not safe to reference the buffer after + * a call to this function unless the caller holds an additional reference + * itself. + */ void -xfs_buf_iorequest( - xfs_buf_t *bp) +xfs_buf_submit( + struct xfs_buf *bp) { - trace_xfs_buf_iorequest(bp, _RET_IP_); + trace_xfs_buf_submit(bp, _RET_IP_); ASSERT(!(bp->b_flags & _XBF_DELWRI_Q)); + ASSERT(bp->b_flags & XBF_ASYNC); + + /* on shutdown we stale and complete the buffer immediately */ + if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { + xfs_buf_ioerror(bp, -EIO); + bp->b_flags &= ~XBF_DONE; + xfs_buf_stale(bp); + xfs_buf_ioend(bp); + return; + } if (bp->b_flags & XBF_WRITE) xfs_buf_wait_unpin(bp); @@ -1314,25 +1308,14 @@ xfs_buf_iorequest( bp->b_io_error = 0; /* - * Take references to the buffer. For XBF_ASYNC buffers, holding a - * reference for as long as submission takes is all that is necessary - * here. The IO inherits the lock and hold count from the submitter, - * and these are release during IO completion processing. Taking a hold - * over submission ensures that the buffer is not freed until we have - * completed all processing, regardless of when IO errors occur or are - * reported. - * - * However, for synchronous IO, the IO does not inherit the submitters - * reference count, nor the buffer lock. Hence we need to take an extra - * reference to the buffer for the for the IO context so that we can - * guarantee the buffer is not freed until all IO completion processing - * is done. Otherwise the caller can drop their reference while the IO - * is still in progress and hence trigger a use-after-free situation. + * The caller's reference is released during I/O completion. + * This occurs some time after the last b_io_remaining reference is + * released, so after we drop our Io reference we have to have some + * other reference to ensure the buffer doesn't go away from underneath + * us. Take a direct reference to ensure we have safe access to the + * buffer until we are finished with it. */ xfs_buf_hold(bp); - if (!(bp->b_flags & XBF_ASYNC)) - xfs_buf_hold(bp); - /* * Set the count to 1 initially, this will stop an I/O completion @@ -1343,40 +1326,82 @@ xfs_buf_iorequest( _xfs_buf_ioapply(bp); /* - * If _xfs_buf_ioapply failed or we are doing synchronous IO that - * completes extremely quickly, we can get back here with only the IO - * reference we took above. If we drop it to zero, run completion - * processing synchronously so that we don't return to the caller with - * completion still pending. This avoids unnecessary context switches - * associated with the end_io workqueue. + * If _xfs_buf_ioapply failed, we can get back here with only the IO + * reference we took above. If we drop it to zero, run completion so + * that we don't return to the caller with completion still pending. */ if (atomic_dec_and_test(&bp->b_io_remaining) == 1) { - if (bp->b_error || !(bp->b_flags & XBF_ASYNC)) + if (bp->b_error) xfs_buf_ioend(bp); else xfs_buf_ioend_async(bp); } xfs_buf_rele(bp); + /* Note: it is not safe to reference bp now we've dropped our ref */ } /* - * Waits for I/O to complete on the buffer supplied. It returns immediately if - * no I/O is pending or there is already a pending error on the buffer, in which - * case nothing will ever complete. It returns the I/O error code, if any, or - * 0 if there was no error. + * Synchronous buffer IO submission path, read or write. */ int -xfs_buf_iowait( - xfs_buf_t *bp) +xfs_buf_submit_wait( + struct xfs_buf *bp) { - trace_xfs_buf_iowait(bp, _RET_IP_); + int error; - if (!bp->b_error) - wait_for_completion(&bp->b_iowait); + trace_xfs_buf_submit_wait(bp, _RET_IP_); + + ASSERT(!(bp->b_flags & (_XBF_DELWRI_Q | XBF_ASYNC))); + if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { + xfs_buf_ioerror(bp, -EIO); + xfs_buf_stale(bp); + bp->b_flags &= ~XBF_DONE; + return -EIO; + } + + if (bp->b_flags & XBF_WRITE) + xfs_buf_wait_unpin(bp); + + /* clear the internal error state to avoid spurious errors */ + bp->b_io_error = 0; + + /* + * For synchronous IO, the IO does not inherit the submitters reference + * count, nor the buffer lock. Hence we cannot release the reference we + * are about to take until we've waited for all IO completion to occur, + * including any xfs_buf_ioend_async() work that may be pending. + */ + xfs_buf_hold(bp); + + /* + * Set the count to 1 initially, this will stop an I/O completion + * callout which happens before we have started all the I/O from calling + * xfs_buf_ioend too early. + */ + atomic_set(&bp->b_io_remaining, 1); + _xfs_buf_ioapply(bp); + + /* + * make sure we run completion synchronously if it raced with us and is + * already complete. + */ + if (atomic_dec_and_test(&bp->b_io_remaining) == 1) + xfs_buf_ioend(bp); + + /* wait for completion before gathering the error from the buffer */ + trace_xfs_buf_iowait(bp, _RET_IP_); + wait_for_completion(&bp->b_iowait); trace_xfs_buf_iowait_done(bp, _RET_IP_); - return bp->b_error; + error = bp->b_error; + + /* + * all done now, we can release the hold that keeps the buffer + * referenced for the entire IO. + */ + xfs_buf_rele(bp); + return error; } xfs_caddr_t @@ -1782,15 +1807,7 @@ __xfs_buf_delwri_submit( else list_del_init(&bp->b_list); - if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { - trace_xfs_bdstrat_shut(bp, _RET_IP_); - - xfs_buf_ioerror(bp, -EIO); - xfs_buf_stale(bp); - xfs_buf_ioend(bp); - continue; - } - xfs_buf_iorequest(bp); + xfs_buf_submit(bp); } blk_finish_plug(&plug); diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index d8f57f6..0acfc30 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -290,8 +290,8 @@ extern int xfs_bwrite(struct xfs_buf *bp); extern void xfs_buf_ioend(struct xfs_buf *bp); extern void xfs_buf_ioerror(xfs_buf_t *, int); extern void xfs_buf_ioerror_alert(struct xfs_buf *, const char *func); -extern void xfs_buf_iorequest(xfs_buf_t *); -extern int xfs_buf_iowait(xfs_buf_t *); +extern void xfs_buf_submit(struct xfs_buf *bp); +extern int xfs_buf_submit_wait(struct xfs_buf *bp); extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *, xfs_buf_rw_t); #define xfs_buf_zero(bp, off, len) \ diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 3916384..f159695 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -1081,7 +1081,7 @@ xfs_buf_iodone_callbacks( * a way to shut the filesystem down if the writes keep failing. * * In practice we'll shut the filesystem down soon as non-transient - * erorrs tend to affect the whole device and a failing log write + * errors tend to affect the whole device and a failing log write * will make us give up. But we really ought to do better here. */ if (XFS_BUF_ISASYNC(bp)) { @@ -1094,7 +1094,7 @@ xfs_buf_iodone_callbacks( if (!(bp->b_flags & (XBF_STALE|XBF_WRITE_FAIL))) { bp->b_flags |= XBF_WRITE | XBF_ASYNC | XBF_DONE | XBF_WRITE_FAIL; - xfs_buf_iorequest(bp); + xfs_buf_submit(bp); } else { xfs_buf_relse(bp); } diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index b5170e5..ed4845f 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1699,7 +1699,7 @@ xlog_bdstrat( return 0; } - xfs_buf_iorequest(bp); + xfs_buf_submit(bp); return 0; } diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 02ad115..c6427b3 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -193,12 +193,8 @@ xlog_bread_noalign( bp->b_io_length = nbblks; bp->b_error = 0; - if (XFS_FORCED_SHUTDOWN(log->l_mp)) - return -EIO; - - xfs_buf_iorequest(bp); - error = xfs_buf_iowait(bp); - if (error) + error = xfs_buf_submit_wait(bp); + if (error && !XFS_FORCED_SHUTDOWN(log->l_mp)) xfs_buf_ioerror_alert(bp, __func__); return error; } @@ -378,9 +374,11 @@ xlog_recover_iodone( * We're not going to bother about retrying * this during recovery. One strike! */ - xfs_buf_ioerror_alert(bp, __func__); - xfs_force_shutdown(bp->b_target->bt_mount, - SHUTDOWN_META_IO_ERROR); + if (!XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { + xfs_buf_ioerror_alert(bp, __func__); + xfs_force_shutdown(bp->b_target->bt_mount, + SHUTDOWN_META_IO_ERROR); + } } bp->b_iodone = NULL; xfs_buf_ioend(bp); @@ -4400,16 +4398,12 @@ xlog_do_recover( XFS_BUF_UNASYNC(bp); bp->b_ops = &xfs_sb_buf_ops; - if (XFS_FORCED_SHUTDOWN(log->l_mp)) { - xfs_buf_relse(bp); - return -EIO; - } - - xfs_buf_iorequest(bp); - error = xfs_buf_iowait(bp); + error = xfs_buf_submit_wait(bp); if (error) { - xfs_buf_ioerror_alert(bp, __func__); - ASSERT(0); + if (!XFS_FORCED_SHUTDOWN(log->l_mp)) { + xfs_buf_ioerror_alert(bp, __func__); + ASSERT(0); + } xfs_buf_relse(bp); return error; } diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 152f827..51372e3 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -349,7 +349,8 @@ DEFINE_BUF_EVENT(xfs_buf_free); DEFINE_BUF_EVENT(xfs_buf_hold); DEFINE_BUF_EVENT(xfs_buf_rele); DEFINE_BUF_EVENT(xfs_buf_iodone); -DEFINE_BUF_EVENT(xfs_buf_iorequest); +DEFINE_BUF_EVENT(xfs_buf_submit); +DEFINE_BUF_EVENT(xfs_buf_submit_wait); DEFINE_BUF_EVENT(xfs_buf_bawrite); DEFINE_BUF_EVENT(xfs_buf_lock); DEFINE_BUF_EVENT(xfs_buf_lock_done); diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index db4be5b..e2b2216 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c @@ -318,23 +318,10 @@ xfs_trans_read_buf_map( XFS_BUF_READ(bp); bp->b_ops = ops; - /* - * XXX(hch): clean up the error handling here to be less - * of a mess.. - */ - if (XFS_FORCED_SHUTDOWN(mp)) { - trace_xfs_bdstrat_shut(bp, _RET_IP_); - bp->b_flags &= ~(XBF_READ | XBF_DONE); - xfs_buf_ioerror(bp, -EIO); - xfs_buf_stale(bp); - xfs_buf_relse(bp); - return -EIO; - } - - xfs_buf_iorequest(bp); - error = xfs_buf_iowait(bp); + error = xfs_buf_submit_wait(bp); if (error) { - xfs_buf_ioerror_alert(bp, __func__); + if (!XFS_FORCED_SHUTDOWN(mp)) + xfs_buf_ioerror_alert(bp, __func__); xfs_buf_relse(bp); /* * We can gracefully recover from most read -- 2.0.0 From jack@suse.cz Thu Sep 25 07:42:07 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 2EB1B7F9F for ; Thu, 25 Sep 2014 07:42:07 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1AE4F304032 for ; Thu, 25 Sep 2014 05:42:07 -0700 (PDT) X-ASG-Debug-ID: 1411648924-04cbb07302263950001-NocioJ Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id wWi1DYn44skjW1eM (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 25 Sep 2014 05:42:05 -0700 (PDT) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 750F2AB1E; Thu, 25 Sep 2014 12:42:04 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 091D981FA9; Thu, 25 Sep 2014 14:42:03 +0200 (CEST) From: Jan Kara To: linux-fsdevel@vger.kernel.org Cc: linux-ext4@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner , Ted Tso , Jan Kara Subject: [PATCH 0/2 v2] Fix data corruption when blocksize < pagesize for mmapped data Date: Thu, 25 Sep 2014 14:41:54 +0200 X-ASG-Orig-Subj: [PATCH 0/2 v2] Fix data corruption when blocksize < pagesize for mmapped data Message-Id: <1411648916-16773-1-git-send-email-jack@suse.cz> X-Mailer: git-send-email 1.8.1.4 X-Barracuda-Connect: cantor2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1411648925 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9862 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Hello, this is a second version of the patches to fix data corruption in mmapped data when blocksize < pagesize as tested by xfstests generic/030 test. The patchset fixes XFS and ext4. I've checked and btrfs doesn't need fixing because it doesn't support blocksize < pagesize. If that's ever going to change btrfs will likely need a similar treatment. ocfs2, ext2, ext3 are OK since they happily allocate blocks during writeback. For other filesystems like gfs2, ubifs, nilfs, ceph,... I'm not sure whether they support blocksize < pagesize at all. Interesting is also NFS which may care but I don't understand its ->page_mkwrite() handler good enough to judge. Changes since v1: - changed helper function name and moved it to mm/truncate.c - I originally thought we can make the helper function update i_size to simplify the interface but it's actually impossible due to generic_write_end() lock ordering constraints. - used round_up() instead of ALIGN() - taught truncate_setsize() to use the helper function Honza From jack@suse.cz Thu Sep 25 07:42:07 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 9C4E47F9F for ; Thu, 25 Sep 2014 07:42:07 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7C384304051 for ; Thu, 25 Sep 2014 05:42:07 -0700 (PDT) X-ASG-Debug-ID: 1411648924-04bdf0039f230f20001-NocioJ Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id bQPGLqwLdj6Hbz84 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 25 Sep 2014 05:42:05 -0700 (PDT) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 8F89DACA0; Thu, 25 Sep 2014 12:42:04 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 0F7B881F97; Thu, 25 Sep 2014 14:42:03 +0200 (CEST) From: Jan Kara To: linux-fsdevel@vger.kernel.org Cc: linux-ext4@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner , Ted Tso , Jan Kara Subject: [PATCH 2/2] ext4: Fix mmap data corruption when blocksize < pagesize Date: Thu, 25 Sep 2014 14:41:56 +0200 X-ASG-Orig-Subj: [PATCH 2/2] ext4: Fix mmap data corruption when blocksize < pagesize Message-Id: <1411648916-16773-3-git-send-email-jack@suse.cz> X-Mailer: git-send-email 1.8.1.4 In-Reply-To: <1411648916-16773-1-git-send-email-jack@suse.cz> References: <1411648916-16773-1-git-send-email-jack@suse.cz> X-Barracuda-Connect: cantor2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1411648925 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9862 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Use truncate_isize_extended() when hole is being created in a file so that ->page_mkwrite() will get called for the partial tail page if it is mmaped (see the first patch in the series for details). Signed-off-by: Jan Kara --- fs/ext4/inode.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 3aa26e9117c4..9e269489e094 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4536,8 +4536,12 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) ext4_orphan_del(NULL, inode); goto err_out; } - } else + } else { + loff_t oldsize = inode->i_size; + i_size_write(inode, attr->ia_size); + pagecache_isize_extended(inode, oldsize, inode->i_size); + } /* * Blocks are going to be removed from the inode. Wait -- 1.8.1.4 From jack@suse.cz Thu Sep 25 07:42:08 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 12C0C7F9F for ; Thu, 25 Sep 2014 07:42:08 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id C97DC304051 for ; Thu, 25 Sep 2014 05:42:07 -0700 (PDT) X-ASG-Debug-ID: 1411648924-04bdf003a1230f30001-NocioJ Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id 1sVCN7Vw3btZVcCp (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 25 Sep 2014 05:42:06 -0700 (PDT) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 9967EACD2; Thu, 25 Sep 2014 12:42:04 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 0D8F480BAA; Thu, 25 Sep 2014 14:42:03 +0200 (CEST) From: Jan Kara To: linux-fsdevel@vger.kernel.org Cc: linux-ext4@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner , Ted Tso , Jan Kara Subject: [PATCH 1/2] vfs: Fix data corruption when blocksize < pagesize for mmaped data Date: Thu, 25 Sep 2014 14:41:55 +0200 X-ASG-Orig-Subj: [PATCH 1/2] vfs: Fix data corruption when blocksize < pagesize for mmaped data Message-Id: <1411648916-16773-2-git-send-email-jack@suse.cz> X-Mailer: git-send-email 1.8.1.4 In-Reply-To: <1411648916-16773-1-git-send-email-jack@suse.cz> References: <1411648916-16773-1-git-send-email-jack@suse.cz> X-Barracuda-Connect: cantor2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1411648925 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9862 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header ->page_mkwrite() is used by filesystems to allocate blocks under a page which is becoming writeably mmapped in some process' address space. This allows a filesystem to return a page fault if there is not enough space available, user exceeds quota or similar problem happens, rather than silently discarding data later when writepage is called. However VFS fails to call ->page_mkwrite() in all the cases where filesystems need it when blocksize < pagesize. For example when blocksize = 1024, pagesize = 4096 the following is problematic: ftruncate(fd, 0); pwrite(fd, buf, 1024, 0); map = mmap(NULL, 1024, PROT_WRITE, MAP_SHARED, fd, 0); map[0] = 'a'; ----> page_mkwrite() for index 0 is called ftruncate(fd, 10000); /* or even pwrite(fd, buf, 1, 10000) */ mremap(map, 1024, 10000, 0); map[4095] = 'a'; ----> no page_mkwrite() called At the moment ->page_mkwrite() is called, filesystem can allocate only one block for the page because i_size == 1024. Otherwise it would create blocks beyond i_size which is generally undesirable. But later at ->writepage() time, we also need to store data at offset 4095 but we don't have block allocated for it. This patch introduces a helper function filesystems can use to have ->page_mkwrite() called at all the necessary moments. Signed-off-by: Jan Kara --- fs/buffer.c | 3 +++ include/linux/mm.h | 8 ++++++++ mm/truncate.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/fs/buffer.c b/fs/buffer.c index 8f05111bbb8b..3ba5a6a1bc5f 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2080,6 +2080,7 @@ int generic_write_end(struct file *file, struct address_space *mapping, struct page *page, void *fsdata) { struct inode *inode = mapping->host; + loff_t old_size = inode->i_size; int i_size_changed = 0; copied = block_write_end(file, mapping, pos, len, copied, page, fsdata); @@ -2099,6 +2100,8 @@ int generic_write_end(struct file *file, struct address_space *mapping, unlock_page(page); page_cache_release(page); + if (old_size < pos) + pagecache_isize_extended(inode, old_size, pos); /* * Don't mark the inode dirty under page lock. First, it unnecessarily * makes the holding time of page lock longer. Second, it forces lock diff --git a/include/linux/mm.h b/include/linux/mm.h index 8981cc882ed2..f0e53e5a3b17 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1155,6 +1155,14 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping, extern void truncate_pagecache(struct inode *inode, loff_t new); extern void truncate_setsize(struct inode *inode, loff_t newsize); +#ifdef CONFIG_MMU +void pagecache_isize_extended(struct inode *inode, loff_t from, loff_t to); +#else +static inline void pagecache_isize_extended(struct inode *inode, loff_t from, + loff_t to) +{ +} +#endif void truncate_pagecache_range(struct inode *inode, loff_t offset, loff_t end); int truncate_inode_page(struct address_space *mapping, struct page *page); int generic_error_remove_page(struct address_space *mapping, struct page *page); diff --git a/mm/truncate.c b/mm/truncate.c index 96d167372d89..261eaf6e5a19 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -20,6 +20,7 @@ #include /* grr. try_to_release_page, do_invalidatepage */ #include +#include #include "internal.h" static void clear_exceptional_entry(struct address_space *mapping, @@ -719,12 +720,68 @@ EXPORT_SYMBOL(truncate_pagecache); */ void truncate_setsize(struct inode *inode, loff_t newsize) { + loff_t oldsize = inode->i_size; + i_size_write(inode, newsize); + if (newsize > oldsize) + pagecache_isize_extended(inode, oldsize, newsize); truncate_pagecache(inode, newsize); } EXPORT_SYMBOL(truncate_setsize); /** + * pagecache_isize_extended - update pagecache after extension of i_size + * @inode: inode for which i_size was extended + * @from: original inode size + * @to: new inode size + * + * Handle extension of inode size either caused by extending truncate or by + * write starting after current i_size. We mark the page straddling current + * i_size RO so that page_mkwrite() is called on the nearest write access to + * the page. This way filesystem can be sure that page_mkwrite() is called on + * the page before user writes to the page via mmap after the i_size has been + * changed. + * + * The function must be called after i_size is updated so that page fault + * coming after we unlock the page will already see the new i_size. + * The function must be called while we still hold i_mutex - this not only + * makes sure i_size is stable but also that userspace cannot observe new + * i_size value before we are prepared to store mmap writes at new inode size. + */ +void pagecache_isize_extended(struct inode *inode, loff_t from, loff_t to) +{ + int bsize = 1 << inode->i_blkbits; + loff_t rounded_from; + struct page *page; + pgoff_t index; + + WARN_ON(!mutex_is_locked(&inode->i_mutex)); + WARN_ON(to > inode->i_size); + + if (from >= to || bsize == PAGE_CACHE_SIZE) + return; + /* Page straddling @from will not have any hole block created? */ + rounded_from = round_up(from, bsize); + if (to <= rounded_from || !(rounded_from & (PAGE_CACHE_SIZE - 1))) + return; + + index = from >> PAGE_CACHE_SHIFT; + page = find_lock_page(inode->i_mapping, index); + /* Page not cached? Nothing to do */ + if (!page) + return; + /* + * See clear_page_dirty_for_io() for details why set_page_dirty() + * is needed. + */ + if (page_mkclean(page)) + set_page_dirty(page); + unlock_page(page); + page_cache_release(page); +} +EXPORT_SYMBOL(pagecache_isize_extended); + +/** * truncate_pagecache_range - unmap and remove pagecache that is hole-punched * @inode: inode * @lstart: offset of beginning of hole -- 1.8.1.4 From borisz@hp.com Thu Sep 25 08:34:08 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 3892A7FB0 for ; Thu, 25 Sep 2014 08:34:08 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 183448F8033 for ; Thu, 25 Sep 2014 06:34:05 -0700 (PDT) X-ASG-Debug-ID: 1411652043-04cbb0730427e1d0001-NocioJ Received: from g4t3425.houston.hp.com (g4t3425.houston.hp.com [15.201.208.53]) by cuda.sgi.com with ESMTP id L8gK0eV2bSObhdjC (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 25 Sep 2014 06:34:03 -0700 (PDT) X-Barracuda-Envelope-From: borisz@hp.com X-Barracuda-Apparent-Source-IP: 15.201.208.53 Received: from G4W6310.americas.hpqcorp.net (g4w6310.houston.hp.com [16.210.26.217]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by g4t3425.houston.hp.com (Postfix) with ESMTPS id 6F968105; Thu, 25 Sep 2014 13:34:03 +0000 (UTC) Received: from G4W6303.americas.hpqcorp.net (16.210.26.228) by G4W6310.americas.hpqcorp.net (16.210.26.217) with Microsoft SMTP Server (TLS) id 14.3.169.1; Thu, 25 Sep 2014 13:33:10 +0000 Received: from G4W3303.americas.hpqcorp.net ([169.254.5.77]) by G4W6303.americas.hpqcorp.net ([16.210.26.228]) with mapi id 14.03.0169.001; Thu, 25 Sep 2014 13:33:10 +0000 From: "Zuckerman, Boris" To: Dave Chinner , Olaf Weber CC: Ben Myers , "linux-fsdevel@vger.kernel.org" , "tinguely@sgi.com" , "xfs@oss.sgi.com" Subject: RE: [RFC v2] Unicode/UTF-8 support for XFS Thread-Topic: [RFC v2] Unicode/UTF-8 support for XFS X-ASG-Orig-Subj: RE: [RFC v2] Unicode/UTF-8 support for XFS Thread-Index: AQHP03v8opbMMceUwEm80AhsAqbz8JwNwXSAgAKMXACAAKSoAIAA8ByQ Date: Thu, 25 Sep 2014 13:33:09 +0000 Message-ID: <4C30833E5CDF444D84D942543DF65BDA6E045594@G4W3303.americas.hpqcorp.net> References: <20140918195650.GI19952@sgi.com> <20140922222611.GZ4322@dastard> <5422C540.1060007@sgi.com> <20140924231024.GA4758@dastard> In-Reply-To: <20140924231024.GA4758@dastard> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [16.210.192.234] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Barracuda-Connect: g4t3425.houston.hp.com[15.201.208.53] X-Barracuda-Start-Time: 1411652043 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.02 X-Barracuda-Spam-Status: No, SCORE=0.02 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=THREAD_INDEX, THREAD_TOPIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9863 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.01 THREAD_TOPIC Thread-Topic: ...(Japanese Subject)... > -----Original Message----- > From: linux-fsdevel-owner@vger.kernel.org [mailto:linux-fsdevel- > owner@vger.kernel.org] On Behalf Of Dave Chinner > Sent: Wednesday, September 24, 2014 7:10 PM > To: Olaf Weber > Cc: Ben Myers; linux-fsdevel@vger.kernel.org; tinguely@sgi.com; xfs@oss.s= gi.com > Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS >=20 > On Wed, Sep 24, 2014 at 03:21:04PM +0200, Olaf Weber wrote: > > On 23-09-14 00:26, Dave Chinner wrote: > > >On Thu, Sep 18, 2014 at 02:56:50PM -0500, Ben Myers wrote: > > > > [...] > > > > >>TODO: Store the unicode version number of the filesystem on disk in > > >>the super block. > > > > > >So, if the filesystem has to store the specific unicode version it > > >was created with so that we know what version to put in trie lookups, > > >again I'll ask: why are we loading the trie as a generic kernel > > >module and not as metadata in the filesystem that is demand paged and > > >cached? > > > > This way the trie can be shared, and the code using it is not > > entangled with the XFS code. >=20 > The trie parsing code can still be common - just the location and content= s of the data is > determined by the end-user. >=20 Both these approaches can co-exists (as I recall was done in Windows). A sy= stem may have "a default trie" and a caller (name space) can provide its ow= n... From tytso@thunk.org Thu Sep 25 08:42:19 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id AEBAB7FB3 for ; Thu, 25 Sep 2014 08:42:19 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9A9A18F8040 for ; Thu, 25 Sep 2014 06:42:19 -0700 (PDT) X-ASG-Debug-ID: 1411652537-04cb6c50e720e910001-NocioJ Received: from imap.thunk.org (imap.thunk.org [74.207.234.97]) by cuda.sgi.com with ESMTP id RNgXu2ZWcEpnGjuh (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO) for ; Thu, 25 Sep 2014 06:42:17 -0700 (PDT) X-Barracuda-Envelope-From: tytso@thunk.org X-Barracuda-Apparent-Source-IP: 74.207.234.97 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=thunk.org; s=ef5046eb; h=In-Reply-To:Content-Type:MIME-Version:References:Message-ID:Subject:Cc:To:From:Date; bh=CobGLaQb/5sKxp+PvK5q5pXF8otHo4Cqli5Eyp/lcVE=; b=kqYqxJmo5uHKwjf19WZ7CANMkhe6VOzK1+Q+tAsAc9vIZAyMD3w7VpteejyskTWJyuiEC2JN5fOkK4j6UGmFi8jYxv5APVGvQBE6hOra7zkqOOvD3F4oBAufvC1pDArwpaY/fYD6Aq369Fm1nZy1BlctRqD3eklzAx/sGC+mGLQ=; Received: from root (helo=closure.thunk.org) by imap.thunk.org with local-esmtp (Exim 4.80) (envelope-from ) id 1XX9Ih-0008Mn-1N; Thu, 25 Sep 2014 13:41:39 +0000 Received: by closure.thunk.org (Postfix, from userid 15806) id 6FFBA580238; Thu, 25 Sep 2014 09:41:37 -0400 (EDT) Date: Thu, 25 Sep 2014 09:41:37 -0400 From: Theodore Ts'o To: Dave Chinner Cc: Jan Kara , Christoph Hellwig , adilger@dilger.ca, linux-api@vger.kernel.org, xfs@oss.sgi.com, dmonakhov@openvz.org, viro@zeniv.linux.org.uk, Li Xi , linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org Subject: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project Message-ID: <20140925134136.GE4592@thunk.org> X-ASG-Orig-Subj: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project References: <1411567470-31799-1-git-send-email-lixi@ddn.com> <1411567470-31799-5-git-send-email-lixi@ddn.com> <20140924162507.GC27000@quack.suse.cz> <20140924162634.GA16886@infradead.org> <20140924170105.GE27000@quack.suse.cz> <20140925075912.GG4758@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140925075912.GG4758@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: tytso@thunk.org X-SA-Exim-Scanned: No (on imap.thunk.org); SAEximRunCond expanded to false X-Barracuda-Connect: imap.thunk.org[74.207.234.97] X-Barracuda-Start-Time: 1411652537 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9863 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Thu, Sep 25, 2014 at 05:59:12PM +1000, Dave Chinner wrote: > > Also I'm afraid we may quickly run out of > > 32 available flags in xflags so we'd need to extend that. But all this > > seems to be doable. > > The struct fsxattr was designed to be extensible - it has unused > padding and enough space in the flags field to allow us to > conditionally use that padding.... I agree that it would be useful for ext4 to support as much of the XFS_IOC_GETXATTR/XFS_IOC_SETATTR as would make sense for ext4, and to use that to set/get the project ID. (And that we should probably do that as a separate set of patches that we could potentially go into ext4 ahead of the project quota while it is undergoing testing and review.) A few questions of Dave and other XFS folks: 1) If we only implement a partial set of the flags or other functionality, are there going to be tools that get confused? i.e., are there any userspace programs that will test for whether the ioctl is supported, and then assume that some minimal set of functionality must be implemented? 2) Unless I'm missing something, there is nothing that enforces that fsx_pad must be zero. I assume that means that the only way you can expand use of fields into that space is via a flag bit being consumed? Cheers, - Ted From jack@suse.cz Thu Sep 25 08:52:20 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id CEADD7F9A for ; Thu, 25 Sep 2014 08:52:20 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8A6278F8039 for ; Thu, 25 Sep 2014 06:52:20 -0700 (PDT) X-ASG-Debug-ID: 1411653137-04bdf003a02438e0001-NocioJ Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id 939kXG9C95zcUsNK (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 25 Sep 2014 06:52:18 -0700 (PDT) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id BA3D3AD5D; Thu, 25 Sep 2014 13:52:16 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 49EC881F97; Thu, 25 Sep 2014 15:52:13 +0200 (CEST) Date: Thu, 25 Sep 2014 15:52:13 +0200 From: Jan Kara To: Dave Chinner Cc: Jan Kara , Christoph Hellwig , adilger@dilger.ca, linux-api@vger.kernel.org, xfs@oss.sgi.com, dmonakhov@openvz.org, viro@zeniv.linux.org.uk, Li Xi , linux-fsdevel@vger.kernel.org, tytso@mit.edu, linux-ext4@vger.kernel.org Subject: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project Message-ID: <20140925135213.GB15352@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project References: <1411567470-31799-1-git-send-email-lixi@ddn.com> <1411567470-31799-5-git-send-email-lixi@ddn.com> <20140924162507.GC27000@quack.suse.cz> <20140924162634.GA16886@infradead.org> <20140924170105.GE27000@quack.suse.cz> <20140925075912.GG4758@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140925075912.GG4758@dastard> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: cantor2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1411653138 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9864 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu 25-09-14 17:59:12, Dave Chinner wrote: > On Wed, Sep 24, 2014 at 07:01:05PM +0200, Jan Kara wrote: > > On Wed 24-09-14 09:26:34, Christoph Hellwig wrote: > > > On Wed, Sep 24, 2014 at 06:25:07PM +0200, Jan Kara wrote: > > > > On Wed 24-09-14 22:04:30, Li Xi wrote: > > > > > This patch adds ioctl interface for setting/getting project of ext4. > > > > The patch looks good to me. I was just wondering whether it won't be > > > > useful to add an ioctl() which isn't ext4 specific. We could just extend > > > > ->setattr() to allow setting of project ID (most filesystems would just > > > > return -EOPNOTSUPP but ext4 and xfs could do the right thing) and then call > > > > ->setattr from the generic ioctl. That way userspace won't have to care > > > > about filesystem type when setting project ID... What do others think? > > > > > > Absolutely. In general I also wonder why this patch doesn't implement > > > the full XFS API. Maybe there is a reason it was considered and > > > rejected, but it would be helpful to document why. > > Do you mean full get/setfsxattr API? > > That's a good start. > > The bigger issue in my mind is that we already have a fully featured > quota API that supports project quotas and userspace tools available > that manipulate it. xfstests already uses those tools and API > for testing project quotas. Well, the VFS quota API is trivially extended by adding additional quota type so I don't really see about which reinventing of quota API are you speaking here... > This whole patchset reinvents all the quota APIs, and will require > adding support in userspace, and hence require re-inventing all the > test infrastructure we already have because it won't be compatible > with the existing project quota test code. Well, quota-tools will have to extended to know about the new quota type. Yes. But that's easy to do. I think teaching xfs quota tools to work with ext4 will be a bigger project plus I don't think I want to force sysadmins which are used to work with quota-tools to switch to other utilities just because of project quotas. Regarding xfstests - I've checked and most of the project quota tests in xfs directory aren't directly usable for ext4 anyway because of other functionality ext4 doesn't support. So we'll need to distill the least common denominator from them anyway... > > That basically contains project ID, > > flags (those that are currently get/set with FS_IOC_GETFLAGS/SETFLAGS), and > > extent size hint right? > > It's a different set of flag definitions. We translate the interface > XFS_XFLAG_* values to/from the inode on-disk XFS_DIFLAG_* inode values, just > like we translate the VFS FS_*_FL flags that get passed through the > FS_IOC_GETFLAGS/SETFLAGS ioctl. > > > That seems workable and it would also make setting > > of PROJINHERIT flag fs agnostic. Only we would have to create some generic > > flags namespace and merge into that ext4 flags and have a translation > > function for the old ext4 flags. > > The XFS_XFLAGS_* are already filesystem agnostic - they are flags > that are only used for interfacing with userspace and hence only > exist at the ioctl copy in/out layer..... > > > Also I'm afraid we may quickly run out of > > 32 available flags in xflags so we'd need to extend that. But all this > > seems to be doable. > > The struct fsxattr was designed to be extensible - it has unused > padding and enough space in the flags field to allow us to > conditionally use that padding.... Yeah, this should all be easy. Honza -- Jan Kara SUSE Labs, CR From bfoster@redhat.com Thu Sep 25 10:07:11 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 77BEF7F6C for ; Thu, 25 Sep 2014 10:07:11 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 57369304062 for ; Thu, 25 Sep 2014 08:07:08 -0700 (PDT) X-ASG-Debug-ID: 1411657626-04cbb073012aae50001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id MniOlrjtDKAiVSul (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 25 Sep 2014 08:07:07 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8PF75U0030716 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 25 Sep 2014 11:07:05 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8PF75ZQ018796; Thu, 25 Sep 2014 11:07:05 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 12895120064; Thu, 25 Sep 2014 11:07:04 -0400 (EDT) Date: Thu, 25 Sep 2014 11:07:04 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [RFC PATCH] xfs: borrow indirect blocks from freed extent when available Message-ID: <20140925150703.GB47304@bfoster.bfoster> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: borrow indirect blocks from freed extent when available References: <1411500538-6831-1-git-send-email-bfoster@redhat.com> <20140923215816.GC4322@dastard> <20140924122746.GA53094@bfoster.bfoster> <20140924233014.GB4758@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140924233014.GB4758@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411657627 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Sep 25, 2014 at 09:30:14AM +1000, Dave Chinner wrote: > On Wed, Sep 24, 2014 at 08:27:46AM -0400, Brian Foster wrote: > > On Wed, Sep 24, 2014 at 07:58:16AM +1000, Dave Chinner wrote: > > > On Tue, Sep 23, 2014 at 03:28:58PM -0400, Brian Foster wrote: > > > > xfs_bmap_del_extent() handles extent removal from the in-core and > > > > on-disk extent lists. When removing a delalloc range, it updates the > > > > indirect block reservation appropriately based on the removal. It > > > > currently enforces that the new indirect block reservation is less than > > > > or equal to the original. This is normally the case in all situations > > > > except for when the removed range creates a hole in a single delalloc > > > > extent, thus splitting a single delalloc extent in two. > > > > > > > > The indirect block reservation is divided evenly between the two new > > > > extents in this scenario. However, it is possible with small enough > > > > extents to split an indlen==1 extent into two such slightly smaller > > > > extents. This leaves one extent with 0 indirect blocks and leads to > > > > assert failures in other areas (e.g., xfs_bunmapi() if the extent > > > > happens to be removed). > > > > > > I had long suspected we had an issue in this code, but was never > > > able to nail down a reproducer that triggered it. Do you have a > > > reproducer, or did you find this by reading/tracing the code? > > > > > > > I have a setup on which fsx reproduces an instance of this within a few > > minutes consistently. It looks like the same sequence of events each > > occurrence so I can try to derive a more specific test case for it. I > > suspect the right sequence of delayed allocation followed by hole > > punching or zeroing should be able to trigger it. > > *nod* > > > > > Refactor xfs_bunmapi() to make the updates that must be consistent > > > > against the inode (e.g., delalloc block counter, quota reservation) > > > > right before the extent is deleted. Move the sb block counter update > > > > after the extent is deleted and update xfs_bmap_del_extent() to steal > > > > some blocks from the freed extent if a larger overall indirect > > > > reservation is required by the extent removal. > > > > > > > > Signed-off-by: Brian Foster > > > > --- > > > > > > > > Hi all, > > > > > > > > I'm seeing the following assert more frequently with fsx and the recent > > > > xfs_free_file_space() changes (at least on 1k fsb fs'): > > > > > > > > XFS: Assertion failed: startblockval(del.br_startblock) > 0, file: fs/xfs/libxfs/xfs_bmap.c, line: 5281 > > > > > > > > This occurs for the reason described in the commit log description. This > > > > is a quick experiment I wanted to test to verify the problem goes away > > > > (so far, so good). Very lightly tested so far. > > > > > > I suspect it's also the cause of these occasional assert failures > > > that I see: > > > > > > XFS: Assertion failed: tp->t_blk_res_used <= tp->t_blk_res, file: fs/xfs/xfs_trans.c, line: 327 > > > > > > during delalloc conversion because there wasn't a space reservation > > > for the blocks allocated (i.e. indlen was zero) and so we overrun > > > the transaction block reservation. > > > > > > > Interesting, I've seen this as well though I'll have to go back and see > > where I was getting it from. I did run fsx overnight without any assert > > failures at all, which seems rare lately. ;) I wasn't running my usual > > parallel fsstress however. I've started that and I reproduce an instance > > of that assert failure within a few minutes, so if related it appears > > this might not be the only contributer. I'll look more into that one > > next. > > I knew I'd looked at this before: > > http://oss.sgi.com/archives/xfs/2014-03/msg00314.html > > That got lost because I wrote it in a topic branch and not my usual > working branch, so when I dropped the topic branch. Guilt, however, > keeps all the patches from topic branches around, and so when I just > did a grep for da_new across .git/patch, this showed up. > > It's basically the same "steal blocks from the deleted extent > reservation fix, and it was trying to address the above failure. > However, there are some other details in it (like changing the > location of delalloc accounting updates) that might be relevant. > Ah, right. I thought I had seen something like this before. In fact I had it in my head that we already did something like this when I narrowed in on the code so I was somewhat surprised, but I didn't go back and look through the list. That explains that. :) This version moves the entire delalloc accounting hunk after the xfs_bmap_del_extent() call. I think the problem with that is the sb counter is the only record keeping that encompasses data blocks and indirect blocks, which is why I only moved that update in xfs_bunmapi(). That's also precisely why I consider using a separate parameter rather than updating br_blockcount. Let me know if you wanted to resurrect this one, otherwise I'll try to double check all of that when I get back to reworking mine... > > I'm pretty sure the test case was simply something like: > > xfs_io -f -c "pwrite 0 1m" \ > -c "fzero 4k 8k" \ > -c "fzero 16k 8k" \ > -c "fzero 32k 8k" \ > -c "fzero 64k 8k" \ > ..... > > To basically split the delalloc extent repeatedly and hence drain > the reservation. > Yep, thanks. I assume you saw the test I posted: http://oss.sgi.com/archives/xfs/2014-09/msg00371.html Brian > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Thu Sep 25 10:14:30 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=LOTS_OF_MONEY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 692A47FA3 for ; Thu, 25 Sep 2014 10:14:30 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 36E9D304062 for ; Thu, 25 Sep 2014 08:14:30 -0700 (PDT) X-ASG-Debug-ID: 1411658068-04bdf0039f25c980001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id JXCZEEVdIATEdome (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 25 Sep 2014 08:14:29 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8PFEQB0004244 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 25 Sep 2014 11:14:26 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8PFEPrO006733; Thu, 25 Sep 2014 11:14:26 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id D3A77120064; Thu, 25 Sep 2014 11:14:24 -0400 (EDT) Date: Thu, 25 Sep 2014 11:14:24 -0400 From: Brian Foster To: Eryu Guan Cc: fstests@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH] generic/033: add xfs delalloc indirect block depletion reproducer Message-ID: <20140925151424.GC47304@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] generic/033: add xfs delalloc indirect block depletion reproducer References: <1411584425-52709-1-git-send-email-bfoster@redhat.com> <20140925035416.GC13950@dhcp-13-216.nay.redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140925035416.GC13950@dhcp-13-216.nay.redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411658069 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Sep 25, 2014 at 11:54:16AM +0800, Eryu Guan wrote: > On Wed, Sep 24, 2014 at 02:47:05PM -0400, Brian Foster wrote: > > XFS allocates extra indirect blocks for delayed allocation extents at > > write time. When delalloc extents are split, the existing indirect block > > reservation was historically divided up evenly among the new extents > > even though the overall requirement for two extents could exceed the > > requirement for the original. Repeated delalloc extent splits ultimately > > leads to extents with 0 indirect blocks and in turn leads to assert > > failures in XFS. > > > > Add a test to stress indirect block reservation for delayed allocation > > extents. The test converts a single delalloc extent to many and operates > > on the remaining extents to detect or trigger potential problems. > > > > Signed-off-by: Brian Foster > > --- > > > > Here's a simple reproducer for the indirect block reservation problem > > called out here: > > > > http://oss.sgi.com/archives/xfs/2014-09/msg00337.html > > > > It reproduces the assert failures described therein: > > > > XFS: Assertion failed: startblockval(del.br_startblock) > 0, file: fs/xfs/libxfs/xfs_bmap.c, line: 5281 > > > > Note that this test also unintentionally fails on XFS. The test file > > ends up zero-sized after the remount and thus hexdump doesn't produce > > any output. This doesn't occur on ext4, I suspect due to the fact that > > the range being zeroed is flushed beforehand, though I could be wrong > > about that. > > Tested with ext4 and xfs, and ext4 passes/xfs fails the test as > described here. > > Reviewed-by: Eryu Guan > > With one nitpick below.. > > > > > In any event, this calls out a separate bug in XFS where if appending > > data is chucked from cache by zero range before written back (eof is > > page aligned), we lose the on-disk inode size update and the inode size > > changes unexpectedly across the remount (assuming nothing else changes > > the size, of course). > > > > Brian > > > > tests/generic/033 | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++ > > tests/generic/033.out | 4 +++ > > tests/generic/group | 1 + > > 3 files changed, 93 insertions(+) > > create mode 100755 tests/generic/033 > > create mode 100644 tests/generic/033.out > > > > diff --git a/tests/generic/033 b/tests/generic/033 > > new file mode 100755 > > index 0000000..41198b7 > > --- /dev/null > > +++ b/tests/generic/033 > > @@ -0,0 +1,88 @@ > > +#! /bin/bash > > +# FS QA Test No. 033 > > +# > > +# This test stresses indirect block reservation for delayed allocation extents. > > +# XFS reserves extra blocks for deferred allocation of delalloc extents. These > > +# reserved blocks can be divided among more extents than anticipated if the > > +# original extent for which the blocks were reserved is split into multiple > > +# delalloc extents. If this scenario repeats, eventually some extents are left > > +# without any indirect block reservation whatsoever. This leads to assert > > +# failures and possibly other problems in XFS. > > +# > > +#----------------------------------------------------------------------- > > +# Copyright (c) 2014 Red Hat, Inc. All Rights Reserved. > > +# > > +# This program 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. > > +# > > +# This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, > > +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > > +#----------------------------------------------------------------------- > > +# > > + > > +seq=`basename $0` > > +seqres=$RESULT_DIR/$seq > > +echo "QA output created by $seq" > > + > > +here=`pwd` > > +tmp=/tmp/$$ > > +status=1 # failure is the default! > > +trap "_cleanup; exit \$status" 0 1 2 3 15 > > + > > +_cleanup() > > +{ > > + cd / > > + rm -f $tmp.* > > +} > > + > > +# get standard environment, filters and checks > > +. ./common/rc > > +. ./common/filter > > + > > +# real QA test starts here > > +rm -f $seqres.full > > + > > +# Modify as appropriate. > > +_supported_fs generic > > +_supported_os Linux > > +_require_scratch > > +_require_xfs_io_command "fzero" > > + > > +_scratch_mkfs >/dev/null 2>&1 > > +_scratch_mount > > + > > +file=$SCRATCH_MNT/file.$seq > > +bytes=$((64 * 1024)) > > + > > +# create sequential delayed allocation > > +$XFS_IO_PROG -f -c "pwrite 0 $bytes" $file | _filter_xfs_io \ > > + >> $seqres.full 2>&1 > > The output of xfs_io is redirected to $seqres.full, so it's not > necessary to be filtered, for debug purpose. > > And the following two xfs_io calls. > Indeed, I'll post v2. Thanks for the review. Brian > Thanks, > Eryu > > > + > > +# Zero every other 4k range to split the larger delalloc extent into many more > > +# smaller extents. Use zero instead of hole punch because the former does not > > +# force writeback (and hence delalloc conversion). It can simply discard > > +# delalloc blocks and convert the ranges to unwritten. > > +endoff=$((bytes - 4096)) > > +for i in $(seq 0 8192 $endoff); do > > + $XFS_IO_PROG -c "fzero -k $i 4k" $file | _filter_xfs_io \ > > + >> $seqres.full 2>&1 > > +done > > + > > +# now zero the opposite set to remove remaining delalloc extents > > +for i in $(seq 4096 8192 $endoff); do > > + $XFS_IO_PROG -c "fzero -k $i 4k" $file | _filter_xfs_io \ > > + >> $seqres.full 2>&1 > > +done > > + > > +_scratch_remount > > +hexdump $file > > + > > +status=0 > > +exit > > diff --git a/tests/generic/033.out b/tests/generic/033.out > > new file mode 100644 > > index 0000000..419d831 > > --- /dev/null > > +++ b/tests/generic/033.out > > @@ -0,0 +1,4 @@ > > +QA output created by 033 > > +0000000 0000 0000 0000 0000 0000 0000 0000 0000 > > +* > > +0010000 > > diff --git a/tests/generic/group b/tests/generic/group > > index 8e0c22a..1227408 100644 > > --- a/tests/generic/group > > +++ b/tests/generic/group > > @@ -32,6 +32,7 @@ > > 027 auto enospc > > 028 auto quick > > 032 auto quick rw > > +033 auto quick rw > > 053 acl repair auto quick > > 062 attr udf auto quick > > 068 other auto freeze dangerous stress > > -- > > 1.8.3.1 > > > > _______________________________________________ > > xfs mailing list > > xfs@oss.sgi.com > > http://oss.sgi.com/mailman/listinfo/xfs > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Thu Sep 25 10:21:55 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1834A7FAF for ; Thu, 25 Sep 2014 10:21:55 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9C41EAC003 for ; Thu, 25 Sep 2014 08:21:51 -0700 (PDT) X-ASG-Debug-ID: 1411658509-04cbb073032b50b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id DItW6nT0vAJDjicl (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 25 Sep 2014 08:21:50 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8PFLlnJ004374 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 25 Sep 2014 11:21:48 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8PFLkRv022100; Thu, 25 Sep 2014 11:21:47 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id D985B120064; Thu, 25 Sep 2014 11:21:45 -0400 (EDT) Date: Thu, 25 Sep 2014 11:21:45 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: flush the range before zero range conversion Message-ID: <20140925152145.GD47304@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs: flush the range before zero range conversion References: <1411585591-55975-1-git-send-email-bfoster@redhat.com> <20140925120155.GF4945@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140925120155.GF4945@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411658510 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Sep 25, 2014 at 10:01:55PM +1000, Dave Chinner wrote: > On Wed, Sep 24, 2014 at 03:06:31PM -0400, Brian Foster wrote: > > XFS currently discards delalloc blocks within the target range of a zero > > range request. Unaligned start and end offsets are zeroed through the > > page cache and the internal, aligned blocks are converted to unwritten > > extents. > > > > If EOF is page aligned and covered by a delayed allocation extent. The > > inode size is not updated until I/O completion. If a zero range request > > discards a delalloc range that covers page aligned EOF as such, the > > inode size update never occurs. For example: > > > > $ rm -f /mnt/file > > $ xfs_io -fc "pwrite 0 64k" -c "zero 60k 4k" /mnt/file > > $ stat -c "%s" /mnt/file > > 65536 > > $ umount /mnt > > $ mount /mnt > > $ stat -c "%s" /mnt/file > > 61440 > > > > Update xfs_zero_file_space() to flush the range rather than discard > > delalloc blocks to ensure that inode size updates occur appropriately. > > > > Signed-off-by: Brian Foster > > --- > > > > I suppose we could be more clever here and only flush the range in this > > particular scenario, but I'm not sure if there's a major benefit there. > > Punching the delalloc range rather than flushing the file > was done intentionally - this was added primarily for speeding up > the zeroing of large VM image files. i.e. it's an extent > manipulation operation rather than a data Io operation. Flushing the > file defeats the primary reason for the operation existing. > > We can easily detect this situation and just zero the last block in > the file directly after punching out all the delalloc state. This > should happen anyway when the region to be zeroed is not page > aligned.... > Hmm, good point. xfs_iozero() goes through page cache. It seems like that should work and it's something we already have to handle in this path. I'll give it a shot. Brian > > FWIW, this implicitly addresses the indlen==0 assert failures described > > in the xfs_bmap_del_extent() rfc, but doesn't necessarily mean we > > shouldn't fix that code IMO. > > We punch delalloc extents elsewhere, so that still needs fixing. > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From BATV+13b43cd15e22c45ddf3c+4050+infradead.org+hch@bombadil.srs.infradead.org Thu Sep 25 10:56:07 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id AE96D7FC3 for ; Thu, 25 Sep 2014 10:56:07 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7DF30304059 for ; Thu, 25 Sep 2014 08:56:07 -0700 (PDT) X-ASG-Debug-ID: 1411660565-04bdf003a1268790001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id 9Yla7hypEnisjp3d (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 25 Sep 2014 08:56:05 -0700 (PDT) X-Barracuda-Envelope-From: BATV+13b43cd15e22c45ddf3c+4050+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXBOm-0004tm-Tu; Thu, 25 Sep 2014 15:56:04 +0000 Date: Thu, 25 Sep 2014 08:56:04 -0700 From: Christoph Hellwig To: Carlos Maiolino Cc: xfs@oss.sgi.com Subject: Re: beginners project: RENAME_EXCHANGE Message-ID: <20140925155604.GB12480@infradead.org> X-ASG-Orig-Subj: Re: beginners project: RENAME_EXCHANGE References: <20140922173545.GA20308@infradead.org> <20140923034351.GB25353@localhost.localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140923034351.GB25353@localhost.localdomain> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411660565 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9867 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Tue, Sep 23, 2014 at 12:43:52AM -0300, Carlos Maiolino wrote: > Hi, for some time I don't work on anything upstream due being very busy with > another stuff, I'm interested in take this project if nobody has objections I don't think you still qualify as beginner :) Joking aside: I'd love you take on this one! From cmaiolino@redhat.com Thu Sep 25 11:10:04 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 3AF947FC4 for ; Thu, 25 Sep 2014 11:10:04 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 292C78F8039 for ; Thu, 25 Sep 2014 09:10:00 -0700 (PDT) X-ASG-Debug-ID: 1411661399-04cb6c50e52394e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id zE6wwqPAS1HqmqFf (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 25 Sep 2014 09:10:00 -0700 (PDT) X-Barracuda-Envelope-From: cmaiolino@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8PG9b7X017047 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 25 Sep 2014 12:09:37 -0400 Received: from localhost.localdomain (ovpn-113-183.phx2.redhat.com [10.3.113.183]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8PG9X1r028373 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Thu, 25 Sep 2014 12:09:36 -0400 Date: Thu, 25 Sep 2014 13:09:33 -0300 From: Carlos Maiolino To: Christoph Hellwig Cc: xfs@oss.sgi.com Subject: Re: beginners project: RENAME_EXCHANGE Message-ID: <20140925160932.GA21381@localhost.localdomain> X-ASG-Orig-Subj: Re: beginners project: RENAME_EXCHANGE Mail-Followup-To: Christoph Hellwig , xfs@oss.sgi.com References: <20140922173545.GA20308@infradead.org> <20140923034351.GB25353@localhost.localdomain> <20140925155604.GB12480@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140925155604.GB12480@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411661400 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Sep 25, 2014 at 08:56:04AM -0700, Christoph Hellwig wrote: > On Tue, Sep 23, 2014 at 12:43:52AM -0300, Carlos Maiolino wrote: > > Hi, for some time I don't work on anything upstream due being very busy with > > another stuff, I'm interested in take this project if nobody has objections > > I don't think you still qualify as beginner :) Joking aside: I'd love > you take on this one! > :) I'm a bit rusty with upstream stuff, so, good way to get myself involved again. Will work on that soon. Cheers > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs -- Carlos From BATV+13b43cd15e22c45ddf3c+4050+infradead.org+hch@bombadil.srs.infradead.org Thu Sep 25 11:17:58 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 9DF0E7FC7 for ; Thu, 25 Sep 2014 11:17:58 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7B3D58F8035 for ; Thu, 25 Sep 2014 09:17:58 -0700 (PDT) X-ASG-Debug-ID: 1411661877-04cbb073032d22f0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id KZAmLvtJDWfe4T4b (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 25 Sep 2014 09:17:57 -0700 (PDT) X-Barracuda-Envelope-From: BATV+13b43cd15e22c45ddf3c+4050+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXBjw-0008Dw-Ip; Thu, 25 Sep 2014 16:17:56 +0000 Date: Thu, 25 Sep 2014 09:17:56 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/3] xfs: consider freeze levels in xfs_fs_writable() Message-ID: <20140925161756.GA25798@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 1/3] xfs: consider freeze levels in xfs_fs_writable() References: <1411647632-28240-1-git-send-email-david@fromorbit.com> <1411647632-28240-2-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411647632-28240-2-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411661877 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9867 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS > index d36bdbc..9073895 100644 > --- a/fs/xfs/xfs_mount.c > +++ b/fs/xfs/xfs_mount.c > @@ -607,7 +607,7 @@ xfs_mount_reset_sbqflags( > * If the fs is readonly, let the incore superblock run > * with quotas off but don't flush the update out to disk > */ > - if (mp->m_flags & XFS_MOUNT_RDONLY) > + if (!xfs_fs_writable(mp, SB_UNFROZEN)) This adds a new caller of xfs_fs_writable, which isn't mentioned in the changelog. > + /* > + * We can be called during the fs freeze process, and we need to be > + * able to write the superblock in that case. > + */ > + if (!xfs_fs_writable(mp, SB_FREEZE_FS)) > return 0; And this already changes the checked freeze level, also not mentioned. From BATV+13b43cd15e22c45ddf3c+4050+infradead.org+hch@bombadil.srs.infradead.org Thu Sep 25 11:19:49 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id DF3777FC7 for ; Thu, 25 Sep 2014 11:19:49 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id BE9A08F8035 for ; Thu, 25 Sep 2014 09:19:49 -0700 (PDT) X-ASG-Debug-ID: 1411661988-04cb6c50e623a760001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id RZyTXqiMeJmPB8Rn (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 25 Sep 2014 09:19:48 -0700 (PDT) X-Barracuda-Envelope-From: BATV+13b43cd15e22c45ddf3c+4050+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXBlk-0002h8-64; Thu, 25 Sep 2014 16:19:48 +0000 Date: Thu, 25 Sep 2014 09:19:48 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 02/11] xfs: Don't use xfs_buf_iowait in the delwri buffer code Message-ID: <20140925161948.GB25798@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 02/11] xfs: Don't use xfs_buf_iowait in the delwri buffer code References: <1411648461-29003-1-git-send-email-david@fromorbit.com> <1411648461-29003-3-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411648461-29003-3-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411661988 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9868 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS Looks good, Reviewed-by: Christoph Hellwig From bfoster@redhat.com Thu Sep 25 11:26:40 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=LOTS_OF_MONEY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 0A4DE7FC7 for ; Thu, 25 Sep 2014 11:26:40 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id DE34C304059 for ; Thu, 25 Sep 2014 09:26:36 -0700 (PDT) X-ASG-Debug-ID: 1411662395-04cbb073032d5f90001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id e2IQzFBPVKFTcaNg (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 25 Sep 2014 09:26:36 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8PGQXOJ005139 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 25 Sep 2014 12:26:34 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8PGQW7t015869; Thu, 25 Sep 2014 12:26:33 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id D51F5120064; Thu, 25 Sep 2014 12:26:31 -0400 (EDT) From: Brian Foster To: fstests@vger.kernel.org Cc: xfs@oss.sgi.com Subject: [PATCH v2] generic/033: add xfs delalloc indirect block depletion reproducer Date: Thu, 25 Sep 2014 12:26:31 -0400 X-ASG-Orig-Subj: [PATCH v2] generic/033: add xfs delalloc indirect block depletion reproducer Message-Id: <1411662391-56463-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411662395 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 XFS allocates extra indirect blocks for delayed allocation extents at write time. When delalloc extents are split, the existing indirect block reservation was historically divided up evenly among the new extents even though the overall requirement for two extents could exceed the requirement for the original. Repeated delalloc extent splits ultimately leads to extents with 0 indirect blocks and in turn leads to assert failures in XFS. Add a test to stress indirect block reservation for delayed allocation extents. The test converts a single delalloc extent to many and operates on the remaining extents to detect or trigger potential problems. Signed-off-by: Brian Foster Reviewed-by: Eryu Guan --- v2: - Remove xfs_io output filter from output to $seqres.full. v1: http://oss.sgi.com/archives/xfs/2014-09/msg00371.html tests/generic/033 | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/033.out | 4 +++ tests/generic/group | 1 + 3 files changed, 89 insertions(+) create mode 100755 tests/generic/033 create mode 100644 tests/generic/033.out diff --git a/tests/generic/033 b/tests/generic/033 new file mode 100755 index 0000000..d221fcd --- /dev/null +++ b/tests/generic/033 @@ -0,0 +1,84 @@ +#! /bin/bash +# FS QA Test No. 033 +# +# This test stresses indirect block reservation for delayed allocation extents. +# XFS reserves extra blocks for deferred allocation of delalloc extents. These +# reserved blocks can be divided among more extents than anticipated if the +# original extent for which the blocks were reserved is split into multiple +# delalloc extents. If this scenario repeats, eventually some extents are left +# without any indirect block reservation whatsoever. This leads to assert +# failures and possibly other problems in XFS. +# +#----------------------------------------------------------------------- +# Copyright (c) 2014 Red Hat, Inc. All Rights Reserved. +# +# This program 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. +# +# This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -f $tmp.* +} + +# get standard environment, filters and checks +. ./common/rc + +# real QA test starts here +rm -f $seqres.full + +# Modify as appropriate. +_supported_fs generic +_supported_os Linux +_require_scratch +_require_xfs_io_command "fzero" + +_scratch_mkfs >/dev/null 2>&1 +_scratch_mount + +file=$SCRATCH_MNT/file.$seq +bytes=$((64 * 1024)) + +# create sequential delayed allocation +$XFS_IO_PROG -f -c "pwrite 0 $bytes" $file >> $seqres.full 2>&1 + +# Zero every other 4k range to split the larger delalloc extent into many more +# smaller extents. Use zero instead of hole punch because the former does not +# force writeback (and hence delalloc conversion). It can simply discard +# delalloc blocks and convert the ranges to unwritten. +endoff=$((bytes - 4096)) +for i in $(seq 0 8192 $endoff); do + $XFS_IO_PROG -c "fzero -k $i 4k" $file >> $seqres.full 2>&1 +done + +# now zero the opposite set to remove remaining delalloc extents +for i in $(seq 4096 8192 $endoff); do + $XFS_IO_PROG -c "fzero -k $i 4k" $file >> $seqres.full 2>&1 +done + +_scratch_remount +hexdump $file + +status=0 +exit diff --git a/tests/generic/033.out b/tests/generic/033.out new file mode 100644 index 0000000..419d831 --- /dev/null +++ b/tests/generic/033.out @@ -0,0 +1,4 @@ +QA output created by 033 +0000000 0000 0000 0000 0000 0000 0000 0000 0000 +* +0010000 diff --git a/tests/generic/group b/tests/generic/group index 8e0c22a..1227408 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -32,6 +32,7 @@ 027 auto enospc 028 auto quick 032 auto quick rw +033 auto quick rw 053 acl repair auto quick 062 attr udf auto quick 068 other auto freeze dangerous stress -- 1.8.3.1 From anton.gamel@physik.uni-freiburg.de Thu Sep 25 15:01:19 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id DEE937FCD for ; Thu, 25 Sep 2014 15:01:18 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4398DAC008 for ; Thu, 25 Sep 2014 13:01:14 -0700 (PDT) X-ASG-Debug-ID: 1411675269-04bdf0039f2ae4f0001-NocioJ Received: from mailgateway3.uni-freiburg.de (mailgateway3.uni-freiburg.de [132.230.2.213]) by cuda.sgi.com with ESMTP id jEz1QwvBimxwN2av (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 25 Sep 2014 13:01:11 -0700 (PDT) X-Barracuda-Envelope-From: anton.gamel@physik.uni-freiburg.de X-Barracuda-Apparent-Source-IP: 132.230.2.213 Delivery-date: Thu, 25 Sep 2014 22:01:11 +0200 Received: from ms2.uni-freiburg.de ([132.230.2.3] helo=uni-freiburg.de) port 34924 by mailgateway3.uni-freiburg.de with esmtp (Exim 4.80.1 #2 built 18-Dec-2013 10:01:47 running on Gentoo) id 1XXFDx-0007Un-BC for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:01:09 +0200 Received: from proton.ruf.uni-freiburg.de (account anton.gamel@physik.uni-freiburg.de [132.230.8.150] verified) by physik.uni-freiburg.de (CommuniGate Pro SMTP 6.0.9) with ESMTPA id 241100125 for xfs@oss.sgi.com; Thu, 25 Sep 2014 22:01:08 +0200 Message-ID: <54247484.2030808@physik.uni-freiburg.de> Date: Thu, 25 Sep 2014 22:01:08 +0200 From: "Gamel Anton J." Organization: =?ISO-8859-1?Q?Universit=E4t_Freiburg?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: xfs@oss.sgi.com Subject: irregular mkfs.xfs results on identical HW Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="------------ms060901090108060206010307" X-ASG-Orig-Subj: irregular mkfs.xfs results on identical HW X-Barracuda-Connect: mailgateway3.uni-freiburg.de[132.230.2.213] X-Barracuda-Start-Time: 1411675270 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9875 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This is a cryptographically signed message in MIME format. --------------ms060901090108060206010307 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: quoted-printable Dear all, servers with identical disk setup (HW RAID0 H310a): Disk /dev/sda: 598.9 GB, 598879502336 bytes /dev/sda1 1 49152 394813439+ 82 Linux swap / Sola= ris /dev/sda2 49153 50176 8225280 83 Linux /dev/sda3 6399 72809 533446357+ 44 Unknown mkfs.xfs creates on 28 of them: meta-data=3D/dev/sda3 isize=3D256 agcount=3D16, agsize=3D= 8335099 blks =3D sectsz=3D512 attr=3D1, projid32bit=3D= 0 data =3D bsize=3D4096 blocks=3D133361584, ima= xpct=3D25 =3D sunit=3D0 swidth=3D0 blks naming =3Dversion 2 bsize=3D4096 ascii-ci=3D0 log =3Dinternal bsize=3D4096 blocks=3D32768, version= =3D1 =3D sectsz=3D512 sunit=3D0 blks, lazy-c= ount=3D1 realtime =3Dnone extsz=3D4096 blocks=3D0, rtextents=3D= 0 but on four out of them: meta-data=3D/dev/sda3 isize=3D256 agcount=3D4, agsize=3D3= 3340398 blks =3D sectsz=3D512 attr=3D2, projid32bit=3D= 0 data =3D bsize=3D4096 blocks=3D133361589, ima= xpct=3D25 =3D sunit=3D0 swidth=3D0 blks naming =3Dversion 2 bsize=3D4096 ascii-ci=3D0 log =3Dinternal bsize=3D4096 blocks=3D65117, version= =3D2 =3D sectsz=3D512 sunit=3D0 blks, lazy-c= ount=3D1 realtime =3Dnone extsz=3D4096 blocks=3D0, rtextents=3D= 0 I did not find a way to add mkfs.xfs options to get the identical filesystem setup on all nodes, e.g. # mkfs.xfs -d agcount=3D16 -b size=3D4096 /dev/sda3 -f meta-data=3D/dev/sda3 isize=3D256 agcount=3D16, agsize=3D= 8335100 blks =3D sectsz=3D512 attr=3D2, projid32bit=3D= 0 data =3D bsize=3D4096 blocks=3D133361589, ima= xpct=3D25 =3D sunit=3D0 swidth=3D0 blks naming =3Dversion 2 bsize=3D4096 ascii-ci=3D0 log =3Dinternal log bsize=3D4096 blocks=3D65117, version= =3D2 =3D sectsz=3D512 sunit=3D0 blks, lazy-c= ount=3D1 realtime =3Dnone extsz=3D4096 blocks=3D0, rtextents=3D= 0 The only way it worked was to dump nodeA:/dev/sda3 to nodeB:/dev/sda3 Is there an explanation? May be I missed something ... hints? Cheers and thanks in advance Anton --=20 Beste Gruesse Anton J. Gamel HPC und GRID-Computing Physikalisches Institut Abteilung Professor Schumacher c/o Rechenzentrum der Universit=E4t Freiburg Arbeitsgruppe Dr. Winterer Hermann-Herder-Stra=DFe 10 79104 Freiburg Tel.: ++49 (0)761 203 -4670 -- Es bleibt immer ein Rest - und ein Rest vom Rest. --------------ms060901090108060206010307 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIEQjCC BD4wggMmoAMCAQICAlwKMA0GCSqGSIb3DQEBDQUAMDYxCzAJBgNVBAYTAkRFMRMwEQYDVQQK EwpHZXJtYW5HcmlkMRIwEAYDVQQDEwlHcmlkS2EtQ0EwHhcNMTQwNjMwMTMzMzI2WhcNMTUw NzMwMTMzMzI2WjBUMQswCQYDVQQGEwJERTETMBEGA1UEChMKR2VybWFuR3JpZDEUMBIGA1UE CxMLVW5pRnJlaWJ1cmcxGjAYBgNVBAMTEUFudG9uIEpvc2VmIEdhbWVsMIIBIjANBgkqhkiG 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvx9uDrse74v5oGPzZLMat9I50/WrLOIshXX7jwXxGH/1 RCdOKLOi3nEOg48i4/24IxwlxJNe1XPl8BIhBnKGWeTEt9rmu9rRoir4ogeGnBSm7mTinMOJ TmlonXEiIPerAIjAGdKVZNvCbup557HJ92bMiq/8IoNCpgD+Yu8r6VqoArws2APwVr3U/JcW njFQj0xX6ZMJwuF55HFC1mNQ3QifcobgWaHdFZK//eK9uT/13r5kB/BeX3X1Ha1xom26otPG Rl30bVMPLdxi8VyHK65zPIPGNh7FsXG32FS3iKQDhesXgrxh1heiFgyBff3xS1qa0bYcvUCT F3giJ8KPfQIDAQABo4IBNjCCATIwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBLAwHQYD VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBQDiUhVzQiNx2h2W9g8mGm4 05Y3wTAfBgNVHSMEGDAWgBTGdckorNEL/Dz/ubUe0187gGISNDAtBgNVHREEJjAkgSJhbnRv bi5nYW1lbEBwaHlzaWsudW5pLWZyZWlidXJnLmRlMBwGA1UdEgQVMBOBEWdyaWRrYS1jYUBr aXQuZWR1MDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9ncmlka2EtY2Eua2l0LmVkdS9jcmwv Z3JpZGthLWNybC5kZXIwKAYDVR0gBCEwHzAPBg0rBgEEAZQ2qywBAQEJMAwGCiqGSIb3TAUC AgEwDQYJKoZIhvcNAQENBQADggEBANWSgkn5qzIUp5/XZfuQ42OHhuppguXtrbzblWe2gtkf WOWm4GrX4oRRHaUvIRkjrgOlc7jPHnLRMwccQJf1EMRRNFRqd5RrQeZxetMzxoOG4GxpSxOJ 5wqHoNYThl4c/73Ph2F+dpSBoqsWucUZPbrjcrQTQ0s630uB9XHinDeicidT4WynSAgE13Zl mr2jXDVGTzA7Ja3CTYCZaDZH5KV7fnOBnAxvZnyGAg24eL65fJhEyQxj5oPDjZsnw78UQevt r+n1jdSEI0PzlFi/2/7TX1ZmGOejxvBOd0WwFtzl8omz92R0jRUiDXgg5SV1kEAo5lTgiSMY n92mUIEYlwwxggLOMIICygIBATA8MDYxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpHZXJtYW5H cmlkMRIwEAYDVQQDEwlHcmlkS2EtQ0ECAlwKMAkGBSsOAwIaBQCgggFnMBgGCSqGSIb3DQEJ AzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE0MDkyNTIwMDEwOFowIwYJKoZIhvcN AQkEMRYEFJzFWiQ3vyrCLx8pPYc7n4IxnYdoMEsGCSsGAQQBgjcQBDE+MDwwNjELMAkGA1UE BhMCREUxEzARBgNVBAoTCkdlcm1hbkdyaWQxEjAQBgNVBAMTCUdyaWRLYS1DQQICXAowTQYL KoZIhvcNAQkQAgsxPqA8MDYxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpHZXJtYW5HcmlkMRIw EAYDVQQDEwlHcmlkS2EtQ0ECAlwKMGwGCSqGSIb3DQEJDzFfMF0wCwYJYIZIAWUDBAEqMAsG CWCGSAFlAwQBAjAKBggqhkiG9w0DBzAOBggqhkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAw BwYFKw4DAgcwDQYIKoZIhvcNAwICASgwDQYJKoZIhvcNAQEBBQAEggEAOGxmTOA3SHPdOqIw qp6IsLVhsqnrOClIQK0mTs9ZlHjwAp9i7rU4dN1dJPXsqIUP8DRtl/i48GGJYd22HcsQjGFf EnOKeDQVFkn/9bEROyE+p7xeaq0OyXGrITj0OgsOmwQ2U9CzmTyMtg+cXoQiZGz9BOkzxA0N VOLAGJ/toSYttSl9bB62YRsRUMBFXsS7T59vvxX621KzFxsxtilvH3q0iZpM6jiTtU9Sc/1L GGQRwXT1U/TuejbKCxotdKT2FeRZKenQcgLjboECN7fsRh3I/BiFslmGeIC/FoZmC00Cc50Y 4kvrKFP5J7qwigExZWb761EDIjJQjRLAZsmY3AAAAAAAAA== --------------ms060901090108060206010307-- From david@fromorbit.com Thu Sep 25 16:03:40 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 1AAE47FD0 for ; Thu, 25 Sep 2014 16:03:40 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 092DF304039 for ; Thu, 25 Sep 2014 14:03:36 -0700 (PDT) X-ASG-Debug-ID: 1411679014-04cbb07304359cc0001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id JKib7tZNwBaec7bK for ; Thu, 25 Sep 2014 14:03:34 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ai43ACWCJFR5LHimPGdsb2JhbABggw6BKoIxhQeudgEBAQEBAQaWE4VrBAICgQUXAQYBAQEBODmEBAEBBCcTHCMQCAMOCgklDwUlAwcaE4g9wWYYGIV6igwHhEsFnSKMO40RKy+CSgEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail05.adl6.internode.on.net with ESMTP; 26 Sep 2014 06:33:32 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XXGCI-00089s-R2; Fri, 26 Sep 2014 07:03:30 +1000 Date: Fri, 26 Sep 2014 07:03:30 +1000 From: Dave Chinner To: Christoph Hellwig Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/3] xfs: consider freeze levels in xfs_fs_writable() Message-ID: <20140925210330.GG4945@dastard> X-ASG-Orig-Subj: Re: [PATCH 1/3] xfs: consider freeze levels in xfs_fs_writable() References: <1411647632-28240-1-git-send-email-david@fromorbit.com> <1411647632-28240-2-git-send-email-david@fromorbit.com> <20140925161756.GA25798@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140925161756.GA25798@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1411679014 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9877 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 25, 2014 at 09:17:56AM -0700, Christoph Hellwig wrote: > > index d36bdbc..9073895 100644 > > --- a/fs/xfs/xfs_mount.c > > +++ b/fs/xfs/xfs_mount.c > > @@ -607,7 +607,7 @@ xfs_mount_reset_sbqflags( > > * If the fs is readonly, let the incore superblock run > > * with quotas off but don't flush the update out to disk > > */ > > - if (mp->m_flags & XFS_MOUNT_RDONLY) > > + if (!xfs_fs_writable(mp, SB_UNFROZEN)) > > This adds a new caller of xfs_fs_writable, which isn't mentioned in the > changelog. I can mention it, but it's so trivial I didn't think it was worth it. > > + /* > > + * We can be called during the fs freeze process, and we need to be > > + * able to write the superblock in that case. > > + */ > > + if (!xfs_fs_writable(mp, SB_FREEZE_FS)) > > return 0; > > And this already changes the checked freeze level, also not mentioned. The changelog says "Hence allow the caller to pass in the freeze level it is allowed to write" which is exactly what this code is doing. Cheers, Dave. -- Dave Chinner david@fromorbit.com From sandeen@sandeen.net Thu Sep 25 16:06:00 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id DCB367FD3 for ; Thu, 25 Sep 2014 16:05:59 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7A7E6AC001 for ; Thu, 25 Sep 2014 14:05:56 -0700 (PDT) X-ASG-Debug-ID: 1411679154-04bdf003a02bc1f0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id 681CBNxsEZkjgP9b for ; Thu, 25 Sep 2014 14:05:54 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id EE24863BEC36; Thu, 25 Sep 2014 16:05:53 -0500 (CDT) Message-ID: <542483B3.3070104@sandeen.net> Date: Thu, 25 Sep 2014 16:05:55 -0500 From: Eric Sandeen MIME-Version: 1.0 To: "Gamel Anton J." , xfs@oss.sgi.com Subject: Re: irregular mkfs.xfs results on identical HW References: <54247484.2030808@physik.uni-freiburg.de> X-ASG-Orig-Subj: Re: irregular mkfs.xfs results on identical HW In-Reply-To: <54247484.2030808@physik.uni-freiburg.de> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1411679154 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9877 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/25/14 3:01 PM, Gamel Anton J. wrote: > Dear all, > > servers with identical disk setup (HW RAID0 H310a): and identical xfsprogs versions? Are these linux boxes? > Disk /dev/sda: 598.9 GB, 598879502336 bytes > /dev/sda1 1 49152 394813439+ 82 Linux swap / Solaris > /dev/sda2 49153 50176 8225280 83 Linux > /dev/sda3 6399 72809 533446357+ 44 Unknown > > mkfs.xfs creates on 28 of them: > meta-data=/dev/sda3 isize=256 agcount=16, agsize=8335099 blks agcount was higher on older mkfs's... > = sectsz=512 attr=1, projid32bit=0 attr=1? that looks ancient. The only way to override the default (2) is with a commandline argument, unless your mkfs is so old that it has different defaults. check your xfsprogs versions on both hosts. -Eric > data = bsize=4096 blocks=133361584, imaxpct=25 > = sunit=0 swidth=0 blks > naming =version 2 bsize=4096 ascii-ci=0 > log =internal bsize=4096 blocks=32768, version=1 > = sectsz=512 sunit=0 blks, lazy-count=1 > realtime =none extsz=4096 blocks=0, rtextents=0 > > but on four out of them: > meta-data=/dev/sda3 isize=256 agcount=4, agsize=33340398 blks > = sectsz=512 attr=2, projid32bit=0 > data = bsize=4096 blocks=133361589, imaxpct=25 > = sunit=0 swidth=0 blks > naming =version 2 bsize=4096 ascii-ci=0 > log =internal bsize=4096 blocks=65117, version=2 > = sectsz=512 sunit=0 blks, lazy-count=1 > realtime =none extsz=4096 blocks=0, rtextents=0 > > I did not find a way to add mkfs.xfs options to get the identical > filesystem setup on all nodes, e.g. > # mkfs.xfs -d agcount=16 -b size=4096 /dev/sda3 -f > meta-data=/dev/sda3 isize=256 agcount=16, agsize=8335100 blks > = sectsz=512 attr=2, projid32bit=0 > data = bsize=4096 blocks=133361589, imaxpct=25 > = sunit=0 swidth=0 blks > naming =version 2 bsize=4096 ascii-ci=0 > log =internal log bsize=4096 blocks=65117, version=2 > = sectsz=512 sunit=0 blks, lazy-count=1 > realtime =none extsz=4096 blocks=0, rtextents=0 > > The only way it worked was to dump nodeA:/dev/sda3 to nodeB:/dev/sda3 > Is there an explanation? May be I missed something ... hints? > > Cheers and thanks in advance > > Anton > > > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs > From david@fromorbit.com Thu Sep 25 16:19:06 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B4C607FD5 for ; Thu, 25 Sep 2014 16:19:06 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id A1A45304039 for ; Thu, 25 Sep 2014 14:19:06 -0700 (PDT) X-ASG-Debug-ID: 1411679943-04cb6c50e628b720001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id 8mx9p7RODCMEtGJ7 for ; Thu, 25 Sep 2014 14:19:04 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ai83AKOFJFR5LHimPGdsb2JhbABggw6BKoIxhQeudgEBAQEBAQaWE4VrBAICgQUXAQYBAQEBODmEAwEBAQMBOhwjBQsIAxgJJQ8FJQMHGhOINgfBbQEXGIV6iUNJB4RLBZ0il0EggWsrL4EHgUMBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail05.adl6.internode.on.net with ESMTP; 26 Sep 2014 06:49:03 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XXGRJ-0008Bs-TH; Fri, 26 Sep 2014 07:19:01 +1000 Date: Fri, 26 Sep 2014 07:19:01 +1000 From: Dave Chinner To: "Gamel Anton J." Cc: xfs@oss.sgi.com Subject: Re: irregular mkfs.xfs results on identical HW Message-ID: <20140925211901.GH4945@dastard> X-ASG-Orig-Subj: Re: irregular mkfs.xfs results on identical HW References: <54247484.2030808@physik.uni-freiburg.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <54247484.2030808@physik.uni-freiburg.de> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1411679943 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9878 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header On Thu, Sep 25, 2014 at 10:01:08PM +0200, Gamel Anton J. wrote: > Dear all, > > servers with identical disk setup (HW RAID0 H310a): > > Disk /dev/sda: 598.9 GB, 598879502336 bytes > /dev/sda1 1 49152 394813439+ 82 Linux swap / Solaris > /dev/sda2 49153 50176 8225280 83 Linux > /dev/sda3 6399 72809 533446357+ 44 Unknown > > mkfs.xfs creates on 28 of them: > meta-data=/dev/sda3 isize=256 agcount=16, agsize=8335099 blks > = sectsz=512 attr=1, projid32bit=0 > data = bsize=4096 blocks=133361584, imaxpct=25 > = sunit=0 swidth=0 blks > naming =version 2 bsize=4096 ascii-ci=0 > log =internal bsize=4096 blocks=32768, version=1 > = sectsz=512 sunit=0 blks, lazy-count=1 > realtime =none extsz=4096 blocks=0, rtextents=0 THat's clearly an old version of mkfs - it's selected version 1 logs and attr1 by default and a log size of only 128MB. mkfs.xfs has defaulted to v2 logs since 3.0.0 (2007). > but on four out of them: > meta-data=/dev/sda3 isize=256 agcount=4, agsize=33340398 blks > = sectsz=512 attr=2, projid32bit=0 > data = bsize=4096 blocks=133361589, imaxpct=25 > = sunit=0 swidth=0 blks > naming =version 2 bsize=4096 ascii-ci=0 > log =internal bsize=4096 blocks=65117, version=2 > = sectsz=512 sunit=0 blks, lazy-count=1 > realtime =none extsz=4096 blocks=0, rtextents=0 Clearly much newer - attr2, log v2, log larger than 128MB... mkfs.xfs -V on each of the nodes will tell you that they are running different versions of mkfs, I think. > The only way it worked was to dump nodeA:/dev/sda3 to nodeB:/dev/sda3 > Is there an explanation? May be I missed something ... hints? If you are building a new storage system, then I'd highly recommend all the nodes run the same software and that software is the newest possible release you can get.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Thu Sep 25 17:22:30 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2AD987FD0 for ; Thu, 25 Sep 2014 17:22:30 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0AC2C8F8035 for ; Thu, 25 Sep 2014 15:22:26 -0700 (PDT) X-ASG-Debug-ID: 1411683744-04cb6c50e429af80001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id v1UNEsyS9JaWrRMR for ; Thu, 25 Sep 2014 15:22:25 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AkQ0ABmVJFR5LHimPGdsb2JhbABgDoMAgSqCMYUHrnUBAQEBAQEGiB2DDooqhWsEAgKBBRcBBgEBAQE4OYQDAQEBAwE6HCMFCwgDGAklDwUlAwcaE4g2B8FmGBiFeok/TQeESwWdIoxCBIw0UisvgQeBQwEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail05.adl6.internode.on.net with ESMTP; 26 Sep 2014 07:52:23 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XXHQb-0008Oj-Mu; Fri, 26 Sep 2014 08:22:21 +1000 Date: Fri, 26 Sep 2014 08:22:21 +1000 From: Dave Chinner To: Theodore Ts'o Cc: Jan Kara , Christoph Hellwig , adilger@dilger.ca, linux-api@vger.kernel.org, xfs@oss.sgi.com, dmonakhov@openvz.org, viro@zeniv.linux.org.uk, Li Xi , linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org Subject: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project Message-ID: <20140925222221.GI4945@dastard> X-ASG-Orig-Subj: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project References: <1411567470-31799-1-git-send-email-lixi@ddn.com> <1411567470-31799-5-git-send-email-lixi@ddn.com> <20140924162507.GC27000@quack.suse.cz> <20140924162634.GA16886@infradead.org> <20140924170105.GE27000@quack.suse.cz> <20140925075912.GG4758@dastard> <20140925134136.GE4592@thunk.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140925134136.GE4592@thunk.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1411683744 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9880 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 25, 2014 at 09:41:37AM -0400, Theodore Ts'o wrote: > On Thu, Sep 25, 2014 at 05:59:12PM +1000, Dave Chinner wrote: > > > Also I'm afraid we may quickly run out of > > > 32 available flags in xflags so we'd need to extend that. But all this > > > seems to be doable. > > > > The struct fsxattr was designed to be extensible - it has unused > > padding and enough space in the flags field to allow us to > > conditionally use that padding.... > > I agree that it would be useful for ext4 to support as much of the > XFS_IOC_GETXATTR/XFS_IOC_SETATTR as would make sense for ext4, and to > use that to set/get the project ID. (And that we should probably do > that as a separate set of patches that we could potentially go into > ext4 ahead of the project quota while it is undergoing testing and > review.) > > A few questions of Dave and other XFS folks: > > 1) If we only implement a partial set of the flags or other > functionality, are there going to be tools that get confused? i.e., > are there any userspace programs that will test for whether the ioctl > is supported, and then assume that some minimal set of functionality > must be implemented? No, I don't think they will get confused. The use of the flags is get/modify/set just like other flag setting functions. The extsize and projid fields are condition on the relevant flag being set on return from a get (i.e. projid is only valid if XFS_XFLAG_PROJID[_INHERIT] is set), and those fields are only considered valid on set if those flags are set by the application (or remain set as a result of the getxattr). Hence the applications that use the getxattr/setxattr interface correctly shouldn't care what set of flags and values the filesystem supports other than the specific flags the application needs the filesystem to understand. > 2) Unless I'm missing something, there is nothing that enforces that > fsx_pad must be zero. I assume that means that the only way you can > expand use of fields into that space is via a flag bit being consumed? Yup, that's exactly what I meant by "conditionally use the padding". Even if the padding was guaranteed to be zero, I'd strongly recommend a flag bit to indicate the application understands that the padding region has actual meaning to guard against buggy applications. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Thu Sep 25 17:42:30 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 4B1477FDA for ; Thu, 25 Sep 2014 17:42:30 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 18E158F8035 for ; Thu, 25 Sep 2014 15:42:29 -0700 (PDT) X-ASG-Debug-ID: 1411684947-04bdf003a22d19c0001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id GWYiDD27zsQetr39 for ; Thu, 25 Sep 2014 15:42:28 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AkQ0AMqZJFR5LHimPGdsb2JhbABggw6BKoIxhQeudQEBAQEBAQaIHYMOiiqFawQCAoEFFwEGAQEBATg5hAMBAQEDAScTHCMQCAMOCgklDwUlAwcaE4g2B8FlGBiFeok/TQeESwWdIoxCBIp5gg0rL4EHgUMBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail05.adl6.internode.on.net with ESMTP; 26 Sep 2014 08:12:26 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XXHk1-0008Qq-EX; Fri, 26 Sep 2014 08:42:25 +1000 Date: Fri, 26 Sep 2014 08:42:25 +1000 From: Dave Chinner To: Jan Kara Cc: Christoph Hellwig , adilger@dilger.ca, linux-api@vger.kernel.org, xfs@oss.sgi.com, dmonakhov@openvz.org, viro@zeniv.linux.org.uk, Li Xi , linux-fsdevel@vger.kernel.org, tytso@mit.edu, linux-ext4@vger.kernel.org Subject: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project Message-ID: <20140925224225.GJ4945@dastard> X-ASG-Orig-Subj: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project References: <1411567470-31799-1-git-send-email-lixi@ddn.com> <1411567470-31799-5-git-send-email-lixi@ddn.com> <20140924162507.GC27000@quack.suse.cz> <20140924162634.GA16886@infradead.org> <20140924170105.GE27000@quack.suse.cz> <20140925075912.GG4758@dastard> <20140925135213.GB15352@quack.suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140925135213.GB15352@quack.suse.cz> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1411684947 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9881 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 25, 2014 at 03:52:13PM +0200, Jan Kara wrote: > On Thu 25-09-14 17:59:12, Dave Chinner wrote: > > On Wed, Sep 24, 2014 at 07:01:05PM +0200, Jan Kara wrote: > > > On Wed 24-09-14 09:26:34, Christoph Hellwig wrote: > > > > On Wed, Sep 24, 2014 at 06:25:07PM +0200, Jan Kara wrote: > > > > > On Wed 24-09-14 22:04:30, Li Xi wrote: > > > > > > This patch adds ioctl interface for setting/getting project of ext4. > > > > > The patch looks good to me. I was just wondering whether it won't be > > > > > useful to add an ioctl() which isn't ext4 specific. We could just extend > > > > > ->setattr() to allow setting of project ID (most filesystems would just > > > > > return -EOPNOTSUPP but ext4 and xfs could do the right thing) and then call > > > > > ->setattr from the generic ioctl. That way userspace won't have to care > > > > > about filesystem type when setting project ID... What do others think? > > > > > > > > Absolutely. In general I also wonder why this patch doesn't implement > > > > the full XFS API. Maybe there is a reason it was considered and > > > > rejected, but it would be helpful to document why. > > > Do you mean full get/setfsxattr API? > > > > That's a good start. > > > > The bigger issue in my mind is that we already have a fully featured > > quota API that supports project quotas and userspace tools available > > that manipulate it. xfstests already uses those tools and API > > for testing project quotas. > Well, the VFS quota API is trivially extended by adding additional quota > type so I don't really see about which reinventing of quota API are you > speaking here... It doesn't seem quite as trivial as you make out given all thei issues so far around increasing MAXQUOTA, the increase in size of the inode, etc. > > This whole patchset reinvents all the quota APIs, and will require > > adding support in userspace, and hence require re-inventing all the > > test infrastructure we already have because it won't be compatible > > with the existing project quota test code. > Well, quota-tools will have to extended to know about the new quota type. > Yes. But that's easy to do. I think teaching xfs quota tools to work with > ext4 will be a bigger project plus I don't think I want to force sysadmins > which are used to work with quota-tools to switch to other utilities just > because of project quotas. > > Regarding xfstests - I've checked and most of the project quota tests in > xfs directory aren't directly usable for ext4 anyway because of other > functionality ext4 doesn't support. So we'll need to distill the least > common denominator from them anyway... I just did a quick scan - of the ~13 tests in tests/xfs that exercise project quotas, only 2 of them test things that are xfs specific (e.g. use xfs_db to peer at things, or use xfs_admin, etc). The rest all rely on xfs_quota to manage and configure project quotas but otherwise don't do anything XFS specific. We want project quotas to have the same management interface for administrators regardless of the filesystem they are using. The only way we can do that is to ensure that the same tools work on either filesystem, and right now it seems to me that the ext4 NIH syndrome is winning out over what is best for our users... Look, I have no problems with extending the existing quota interfaces to support project quotas, but that should be a *secondary* improvement as userspace tools are updated. The primary goal needs to be "works identically to XFS" and so it needs to implement the interfaces that are currently used for management so that we can actually test that it does work identically. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Thu Sep 25 19:18:39 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 3B35E7FDD for ; Thu, 25 Sep 2014 19:18:39 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 29EAD8F8033 for ; Thu, 25 Sep 2014 17:18:36 -0700 (PDT) X-ASG-Debug-ID: 1411690712-04cbb07303398c80001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id 2DjEf0eNsytVHvOw for ; Thu, 25 Sep 2014 17:18:33 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AlI0AA2wJFR5LHimPGdsb2JhbABggw6BKoIxUIQ3rnkBAQEBAQEGiB2DDooqhWsEAgKBAhcBBgEBAQE4OYQDAQEBAwEjDwEjIwULCAMYAgIFIQICDwUlAwcaEx+IFwerX5YqGIEUhGaEGIUnTQeCeIFTBZ0ijEIEinmCDSsvgQeBQwEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail05.adl6.internode.on.net with ESMTP; 26 Sep 2014 09:40:51 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XXJ7Z-0000B7-T4; Fri, 26 Sep 2014 10:10:49 +1000 Date: Fri, 26 Sep 2014 10:10:49 +1000 From: Dave Chinner To: lixi Cc: Jan Kara , Christoph Hellwig , Andreas Dilger , linux-api@vger.kernel.org, xfs@oss.sgi.com, Dmitry Monakhov , viro@zeniv.linux.org.uk, linux-fsdevel@vger.kernel.org, Theodore Ts'o , Ext4 Developers List Subject: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project Message-ID: <20140926001049.GK4945@dastard> X-ASG-Orig-Subj: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project References: <1411567470-31799-1-git-send-email-lixi@ddn.com> <1411567470-31799-5-git-send-email-lixi@ddn.com> <20140924162507.GC27000@quack.suse.cz> <20140924162634.GA16886@infradead.org> <20140924170105.GE27000@quack.suse.cz> <20140925075912.GG4758@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1411690712 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9886 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 25, 2014 at 07:34:38PM +0800, lixi wrote: > Hi Dave, > > I was mostly working on the semantics of inherit flag on these patches. And > I didn’t realized that the interface differences would bother you so much. Sorry > for that. It's not the differences that bother me - it's the fact that I was repeatedly ignored until someone else raised the same issue.... > I agree that we should choose a good interface. It would be good that it is > general so that it works well for all file systems. I agree that adding an > ext4 specific ioctl() is far from the best choice. I am willing to change it to > any general interface. A general ioctl() sounds good to me. Extend setattr() > and getattr() for project ID sounds even better, since project ID looks like > UID/GID. Ah, no, project ID is not a uid/gid. It's a completely independent construct. [ Which brings me to, once again, the issue of being ignored during reviews: project IDs should not be mapped by user namespaces, nor be accessible from anything other than the init namespace. In XFS we've turned off access to project IDs within namespace containers because they are used for container space management (i.e. by the init namespace) to manage the amount of filesystem space a container or set of containers can use. We do not want project IDs to be manipulated from within such containers, and therefore have to prevent access to them from within user namespaces. ] > And general xattr name is another choice. But it is might be a little > bit confusing if we use xattr actually, since we are not saving project ID as > extended attribute on Ext4. Any choice is fine with me, as long as the > implementation won't introduce nasty codes or inconsistent design. We can easily create another ioctl name if we have to. It just needs sto be defined to the same value as the XFS ioctl names currently are. We've done this before when making ioctls that originated in XFS generic (e.g. with freeze/thaw ioctls).... > However, the problem is, I do not quite understand why we should keep > the interface exactly the same with XFS. It would be good if we can. But > as far as I can see, it seems hard. XFS uses a lot interfaces which are > not so standard and used by other file systems. For example, struct > fsxattr is not used by other file systems at all except XFS. Moving a existing structure definitions to a different header file is too hard? > I am not sure why we should introduce this into Ext4 if there are > a lot of other better ways. I would be happy to change to XFS > interfaces, if it is general. However, I don’t think it is > general enough. How is it not general enough? Examples, please, not handwaving: which bit of the quota interface can't ext4 use because it's XFS specific? We already have a perfectly functional interface and a large body of code that implements and tests it. You're saying "oh, it's too much work for me to implement an existing interface" and ignoring the fact that not implementing the existing interface forces a huge amount of downstream work. e.g. - we need completely new test infrastructure to replicate existing tests. - we need new tests to ensure the different APIs and utilities provide the same functionality, and that the work identically. - administrators are going to have to learn how ext4 is different to what they already know and understand. - administrators that has tools written to manage project quotas is going to have to rewrite them to support ext4. It's an entirely selfish argument that ignores what already existing out in userspace. i.e. you're saying that existing downstream users of project quotas simple don't matter to you... > I know xfstest is using the existing project quota interfaces of XFS. And > maybe there are some applications which are using them too. But > keeping the interfaces exactly the same with XFS would cost so much > effort that I’d like to get enough reasons before start working on it. Is it > really necessary? I am not so sure. You have to have a stronger argument than that to justify creating a new incompatible user interface. The XFS interfaces have been available for more than 10 years and support all the functionality ext4 requires. If it was any other userspace interface (e.g. syscalls) or any filesystem other than ext4 there would be people from all over telling you "use the existing interfaces!" and you'd need very strong reasons for creating a new one. i.e. you need to demonstrate that the existing interfaces are inadequate for the intended purpose of the new functionality. That's clearly not the case here so why should we allow you to create an incompatible userspace API rather than use the existing, fully functional API? > It is so easy to change user space applications comparing to > changing a weird interfaces. The existing generic quota tools (i.e quotactl, repquota, etc) already implement the XFS quota API to be able to query XFS filesystems. There's no "changing to wierd interfaces" necessary for userspace; it's already all there. Hence any work you do to add project quota awareness to those generic userspace tools will need to add the support to the XFS queries anyway. IOWs, you're not making it any easier for yourself in userspace by creating a new API for ext4 - it just doubles the amount of work you have to in userspace to make existing tools project quota aware. > For > example, I think it won’t cost even more than a day to add xfstest > support for new Ext4 project quota. A day of whose time? Ever thought about how much time it will take reviewers to look at your tests and iterate over them to get it all right? If you're introducing new userspace infrastructure that xfstests will need to depend on and test for, then it's a lot more than just writing new tests. Indeed, I'm likely to want new project quota tests to be generic (i.e. works and passes on any filesystem that supports project quotas) with the introduction of ext4 project quota support. It's the same functionality and so it should work the same just like user and group quotas do across all filesystems. > And since project quota is far from > a widely used feature, I don't think you realise quite how widespread it's use is on XFS. > I don’t think there is much compatibility problems > for existing applications. And If the new project interface are general > enough, there won’t be any compatibility problems for new applications > at all. Again, you are ignoring the compatibility problems with existing applications that are project quota aware. For them you are *creating new compatibility problems* by implementing a new interface. i.e. Existing applications will not work on ext4, and new applications written to work on ext4 won't work on XFS. That's the crux of the issue - we have existing applications using the existing interface and so introducing a new interface introduces compatibility problems. You can't just wave this problem away because you don't think the existing interface matters. "It's easier for me to create a new interface" is not a valid reason for creating a new interface.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Thu Sep 25 20:59:42 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id DEFCA7FE0 for ; Thu, 25 Sep 2014 20:59:42 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id B023A8F8035 for ; Thu, 25 Sep 2014 18:59:42 -0700 (PDT) X-ASG-Debug-ID: 1411696774-04bdf0039f308a90001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id OyDZSEEPjHNnCZvW for ; Thu, 25 Sep 2014 18:59:34 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ar0eALDHJFR5LHimPGdsb2JhbABggw5TV4Ixs3QMAQEBAQEBBpN4gV2FawQCAoECFwEGAQEBATg5hAMBAQEDATocIxAIAw4KCSUPBSUDBxoTiDYHDsFVGBiFeod5ghMHhEsFlhqHCJlMKy8BgkkBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail05.adl6.internode.on.net with ESMTP; 26 Sep 2014 11:29:33 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XXKol-0000NY-P3; Fri, 26 Sep 2014 11:59:31 +1000 Date: Fri, 26 Sep 2014 11:59:31 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [RFC PATCH] xfs: borrow indirect blocks from freed extent when available Message-ID: <20140926015931.GL4945@dastard> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: borrow indirect blocks from freed extent when available References: <1411500538-6831-1-git-send-email-bfoster@redhat.com> <20140923215816.GC4322@dastard> <20140924122746.GA53094@bfoster.bfoster> <20140924233014.GB4758@dastard> <20140925150703.GB47304@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140925150703.GB47304@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1411696774 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9888 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 25, 2014 at 11:07:04AM -0400, Brian Foster wrote: > On Thu, Sep 25, 2014 at 09:30:14AM +1000, Dave Chinner wrote: > > I knew I'd looked at this before: > > > > http://oss.sgi.com/archives/xfs/2014-03/msg00314.html > > > > That got lost because I wrote it in a topic branch and not my usual > > working branch, so when I dropped the topic branch. Guilt, however, > > keeps all the patches from topic branches around, and so when I just > > did a grep for da_new across .git/patch, this showed up. > > > > It's basically the same "steal blocks from the deleted extent > > reservation fix, and it was trying to address the above failure. > > However, there are some other details in it (like changing the > > location of delalloc accounting updates) that might be relevant. > > > > Ah, right. I thought I had seen something like this before. In fact I > had it in my head that we already did something like this when I > narrowed in on the code so I was somewhat surprised, but I didn't go > back and look through the list. That explains that. :) > > This version moves the entire delalloc accounting hunk after the > xfs_bmap_del_extent() call. I think the problem with that is the sb > counter is the only record keeping that encompasses data blocks and > indirect blocks, which is why I only moved that update in xfs_bunmapi(). > That's also precisely why I consider using a separate parameter rather > than updating br_blockcount. > > Let me know if you wanted to resurrect this one, otherwise I'll try to > double check all of that when I get back to reworking mine... It doesn't need to be resurrected if you've got a better fix. ;) > > I'm pretty sure the test case was simply something like: > > > > xfs_io -f -c "pwrite 0 1m" \ > > -c "fzero 4k 8k" \ > > -c "fzero 16k 8k" \ > > -c "fzero 32k 8k" \ > > -c "fzero 64k 8k" \ > > ..... > > > > To basically split the delalloc extent repeatedly and hence drain > > the reservation. > > > > Yep, thanks. I assume you saw the test I posted: > > http://oss.sgi.com/archives/xfs/2014-09/msg00371.html Yup, I did see that later in the day.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From dave@fromorbit.com Thu Sep 25 21:19:21 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B54847FE2 for ; Thu, 25 Sep 2014 21:19:21 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9B221304032 for ; Thu, 25 Sep 2014 19:19:21 -0700 (PDT) X-ASG-Debug-ID: 1411697959-04cb6c50e62bf730001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id V6TrmCnOkGMpe9b4 for ; Thu, 25 Sep 2014 19:19:19 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AsoUAG7MJFR5LHimPGdsb2JhbABggw6BKoc4rngBAQEBAQEGnEoXAQYBAQEBODmEBAEFJy8zCBgxOQMHFBmIPcF6hhKKKYQ1BYYmozeNESsvgkoBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail05.adl6.internode.on.net with ESMTP; 26 Sep 2014 11:49:16 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XXL7q-0000Rk-QE for xfs@oss.sgi.com; Fri, 26 Sep 2014 12:19:14 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XXL7q-0006S3-Pd for xfs@oss.sgi.com; Fri, 26 Sep 2014 12:19:14 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 2/5] xfs: recovery of XLOG_UNMOUNT_TRANS leaks memory Date: Fri, 26 Sep 2014 12:19:09 +1000 X-ASG-Orig-Subj: [PATCH 2/5] xfs: recovery of XLOG_UNMOUNT_TRANS leaks memory Message-Id: <1411697952-24741-3-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411697952-24741-1-git-send-email-david@fromorbit.com> References: <1411697952-24741-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1411697959 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9889 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner The XLOG_UNMOUNT_TRANS case skips the transaction, despite the fact an unmount record is always in a standalone transaction. Hence whenever we come across one of these we need to free the transaction structure associated with it as there is no commit record that follows it. Signed-off-by: Dave Chinner --- fs/xfs/xfs_log_recover.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index b5e081b..685e98b 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -3532,6 +3532,9 @@ out: return error ? error : error2; } +/* + * On error or completion, trans is freed. + */ STATIC int xlog_recovery_process_trans( struct xlog *log, @@ -3541,7 +3544,8 @@ xlog_recovery_process_trans( unsigned int flags, int pass) { - int error = -EIO; + int error = 0; + bool freeit = false; /* mask off ophdr transaction container flags */ flags &= ~XLOG_END_TRANS; @@ -3563,18 +3567,19 @@ xlog_recovery_process_trans( /* unexpected flag values */ case XLOG_UNMOUNT_TRANS: + /* just skip trans */ xfs_warn(log->l_mp, "%s: Unmount LR", __func__); - error = 0; /* just skip trans */ + freeit = true; break; case XLOG_START_TRANS: - xfs_warn(log->l_mp, "%s: bad transaction", __func__); - ASSERT(0); - break; default: xfs_warn(log->l_mp, "%s: bad flag 0x%x", __func__, flags); ASSERT(0); + error = -EIO; break; } + if (error || freeit) + xlog_recover_free_trans(trans); return error; } @@ -3600,8 +3605,10 @@ xlog_recover_ophdr_to_trans( * on this opheader is allocate a new recovery container to hold * the recovery ops that will follow. */ - if (ohead->oh_flags & XLOG_START_TRANS) + if (ohead->oh_flags & XLOG_START_TRANS) { + ASSERT(be32_to_cpu(ohead->oh_len) == 0); xlog_recover_new_tid(rhp, tid, be64_to_cpu(rhead->h_lsn)); + } return NULL; } @@ -3616,7 +3623,6 @@ xlog_recover_process_ophdr( int pass) { struct xlog_recover *trans; - int error; unsigned int len; /* Do we understand who wrote this op? */ @@ -3644,11 +3650,8 @@ xlog_recover_process_ophdr( return 0; } - error = xlog_recovery_process_trans(log, trans, dp, len, - ohead->oh_flags, pass); - if (error) - xlog_recover_free_trans(trans); - return error; + return xlog_recovery_process_trans(log, trans, dp, len, + ohead->oh_flags, pass); } /* -- 2.0.0 From dave@fromorbit.com Thu Sep 25 21:19:24 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id E78E37FEC for ; Thu, 25 Sep 2014 21:19:23 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id AB3CD304053 for ; Thu, 25 Sep 2014 19:19:20 -0700 (PDT) X-ASG-Debug-ID: 1411697957-04bdf003a230c5c0002-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id 0bVgMfoHVFvi8Ui2 for ; Thu, 25 Sep 2014 19:19:18 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AsoUAG7MJFR5LHimPGdsb2JhbABggw6BKoc4rngBAQEBAQEGnEoXAQYBAQEBODmEBAEFJy8zCBgxOQMHFBmIPcF6hhKOXgWGJrBIKy+CSgEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail05.adl6.internode.on.net with ESMTP; 26 Sep 2014 11:49:16 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XXL7q-0000Rn-RW for xfs@oss.sgi.com; Fri, 26 Sep 2014 12:19:14 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XXL7q-0006SI-Qk for xfs@oss.sgi.com; Fri, 26 Sep 2014 12:19:14 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 5/5] xfs: refactor recovery transaction start handling Date: Fri, 26 Sep 2014 12:19:12 +1000 X-ASG-Orig-Subj: [PATCH 5/5] xfs: refactor recovery transaction start handling Message-Id: <1411697952-24741-6-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411697952-24741-1-git-send-email-david@fromorbit.com> References: <1411697952-24741-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1411697958 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9888 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner Rework the transaction lookup and allocation code in xlog_recovery_process_ophdr() to remove fold two related call-once helper functions into a single helper. Then fold in all XLOG_START_TRANS logic to that helper to clean up the remaining logic in xlog_recovery_process_ophdr(). Signed-off-by: Dave Chinner --- fs/xfs/xfs_log_recover.c | 77 +++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 43 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index e4fd4b1..6e861ba 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -3351,38 +3351,6 @@ out: return error ? error : error2; } - -STATIC xlog_recover_t * -xlog_recover_find_tid( - struct hlist_head *head, - xlog_tid_t tid) -{ - xlog_recover_t *trans; - - hlist_for_each_entry(trans, head, r_list) { - if (trans->r_log_tid == tid) - return trans; - } - return NULL; -} - -STATIC void -xlog_recover_new_tid( - struct hlist_head *head, - xlog_tid_t tid, - xfs_lsn_t lsn) -{ - xlog_recover_t *trans; - - trans = kmem_zalloc(sizeof(xlog_recover_t), KM_SLEEP); - trans->r_log_tid = tid; - trans->r_lsn = lsn; - INIT_LIST_HEAD(&trans->r_itemq); - - INIT_HLIST_NODE(&trans->r_list); - hlist_add_head(&trans->r_list, head); -} - STATIC void xlog_recover_add_item( struct list_head *head) @@ -3505,6 +3473,7 @@ xlog_recover_add_to_trans( trace_xfs_log_recover_item_add(log, trans, item, 0); return 0; } + /* * Free up any resources allocated by the transaction * @@ -3587,6 +3556,13 @@ xlog_recovery_process_trans( return error; } +/* + * Lookup the transaction recovery structure associated with the ID in the + * current ophdr. If the transaction doesn't exist and the start flag is set in + * the ophdr, then allocate a new transaction for future ID matches to find. + * Either way, return what we found during the lookup - an existing transaction + * or nothing. + */ STATIC struct xlog_recover * xlog_recover_ophdr_to_trans( struct hlist_head rhash[], @@ -3599,20 +3575,35 @@ xlog_recover_ophdr_to_trans( tid = be32_to_cpu(ohead->oh_tid); rhp = &rhash[XLOG_RHASH(tid)]; - trans = xlog_recover_find_tid(rhp, tid); - if (trans) - return trans; + hlist_for_each_entry(trans, rhp, r_list) { + if (trans->r_log_tid == tid) + return trans; + } /* - * If this is a new transaction, the ophdr only contains the - * start record. In that case, the only processing we need to do - * on this opheader is allocate a new recovery container to hold - * the recovery ops that will follow. + * skip over non-start transaction headers - we could be + * processing slack space before the next transaction starts + */ + if (!(ohead->oh_flags & XLOG_START_TRANS)) + return NULL; + + ASSERT(be32_to_cpu(ohead->oh_len) == 0); + + /* + * This is a new transaction so allocate a new recovery container to + * hold the recovery ops that will follow. + */ + trans = kmem_zalloc(sizeof(struct xlog_recover), KM_SLEEP); + trans->r_log_tid = tid; + trans->r_lsn = be64_to_cpu(rhead->h_lsn); + INIT_LIST_HEAD(&trans->r_itemq); + INIT_HLIST_NODE(&trans->r_list); + hlist_add_head(&trans->r_list, rhp); + + /* + * Nothing more to do for this ophdr. Items to be added to this new + * transaction will be in subsequent ophdr containers. */ - if (ohead->oh_flags & XLOG_START_TRANS) { - ASSERT(be32_to_cpu(ohead->oh_len) == 0); - xlog_recover_new_tid(rhp, tid, be64_to_cpu(rhead->h_lsn)); - } return NULL; } -- 2.0.0 From dave@fromorbit.com Thu Sep 25 21:19:24 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B7D557FEC for ; Thu, 25 Sep 2014 21:19:24 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 97B358F8035 for ; Thu, 25 Sep 2014 19:19:21 -0700 (PDT) X-ASG-Debug-ID: 1411697957-04bdf003a230c5c0003-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id kixLZU78qW3A15Uk for ; Thu, 25 Sep 2014 19:19:20 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AsoUAG7MJFR5LHimPGdsb2JhbABggw6BKoc4rngBAQEBAQEGnEoXAQYBAQEBODmEBAEFJy8zCBgxOQMHFBmIPcF6hhKKKYQ1BaldjRErL4JKAQEB Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail05.adl6.internode.on.net with ESMTP; 26 Sep 2014 11:49:16 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XXL7q-0000Rl-QX for xfs@oss.sgi.com; Fri, 26 Sep 2014 12:19:14 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XXL7q-0006S8-Px for xfs@oss.sgi.com; Fri, 26 Sep 2014 12:19:14 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 3/5] xfs: fix double free in xlog_recover_commit_trans Date: Fri, 26 Sep 2014 12:19:10 +1000 X-ASG-Orig-Subj: [PATCH 3/5] xfs: fix double free in xlog_recover_commit_trans Message-Id: <1411697952-24741-4-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411697952-24741-1-git-send-email-david@fromorbit.com> References: <1411697952-24741-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1411697959 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 2.60 X-Barracuda-Spam-Status: No, SCORE=2.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MV0249, MARKETING_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9888 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 2.00 BSF_SC0_MV0249 Custom rule MV0249 From: Dave Chinner When an error occurs during buffer submission in xlog_recover_commit_trans(), we free the trans structure twice. Fix it by only freeing the structure in the caller regardless of the success or failure of the function. Signed-off-by: Dave Chinner --- fs/xfs/xfs_log_recover.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 685e98b..28eb078 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -3526,8 +3526,6 @@ out: if (!list_empty(&done_list)) list_splice_init(&done_list, &trans->r_itemq); - xlog_recover_free_trans(trans); - error2 = xfs_buf_delwri_submit(&buffer_list); return error ? error : error2; } @@ -3552,6 +3550,10 @@ xlog_recovery_process_trans( if (flags & XLOG_WAS_CONT_TRANS) flags &= ~XLOG_CONTINUE_TRANS; + /* + * Callees must not free the trans structure. We'll decide if we need to + * free it or not based on the operation being done and it's result. + */ switch (flags) { /* expected flag values */ case 0: @@ -3563,6 +3565,8 @@ xlog_recovery_process_trans( break; case XLOG_COMMIT_TRANS: error = xlog_recover_commit_trans(log, trans, pass); + /* success or fail, we are now done with this transaction. */ + freeit = true; break; /* unexpected flag values */ -- 2.0.0 From dave@fromorbit.com Thu Sep 25 21:19:23 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id C543D7FE2 for ; Thu, 25 Sep 2014 21:19:23 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id AA8F330404E for ; Thu, 25 Sep 2014 19:19:23 -0700 (PDT) X-ASG-Debug-ID: 1411697959-04cb6c50e62bf730002-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id l5UCyYnrCwqdwA65 for ; Thu, 25 Sep 2014 19:19:21 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AsoUAG7MJFR5LHimPGdsb2JhbABggw6BKoc4rngBAQEBAQEGnEoXAQYBAQEBODmEBAEFJy8zCBgxOQMHFBmIPcF6hhKOXgWGJq49IIFrKy+CSgEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail05.adl6.internode.on.net with ESMTP; 26 Sep 2014 11:49:16 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XXL7q-0000Rm-R0 for xfs@oss.sgi.com; Fri, 26 Sep 2014 12:19:14 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XXL7q-0006SD-QL for xfs@oss.sgi.com; Fri, 26 Sep 2014 12:19:14 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 4/5] xfs: reorganise transaction recovery item code Date: Fri, 26 Sep 2014 12:19:11 +1000 X-ASG-Orig-Subj: [PATCH 4/5] xfs: reorganise transaction recovery item code Message-Id: <1411697952-24741-5-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411697952-24741-1-git-send-email-david@fromorbit.com> References: <1411697952-24741-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1411697960 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9889 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner The code for managing transactions anf the items for recovery is spread across 3 different locations in the file. Move them all together so that it is easy to read the code without needing to jump long distances in the file. Signed-off-by: Dave Chinner --- fs/xfs/xfs_log_recover.c | 358 +++++++++++++++++++++++------------------------ 1 file changed, 179 insertions(+), 179 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 28eb078..e4fd4b1 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -1443,160 +1443,6 @@ xlog_clear_stale_blocks( ****************************************************************************** */ -STATIC xlog_recover_t * -xlog_recover_find_tid( - struct hlist_head *head, - xlog_tid_t tid) -{ - xlog_recover_t *trans; - - hlist_for_each_entry(trans, head, r_list) { - if (trans->r_log_tid == tid) - return trans; - } - return NULL; -} - -STATIC void -xlog_recover_new_tid( - struct hlist_head *head, - xlog_tid_t tid, - xfs_lsn_t lsn) -{ - xlog_recover_t *trans; - - trans = kmem_zalloc(sizeof(xlog_recover_t), KM_SLEEP); - trans->r_log_tid = tid; - trans->r_lsn = lsn; - INIT_LIST_HEAD(&trans->r_itemq); - - INIT_HLIST_NODE(&trans->r_list); - hlist_add_head(&trans->r_list, head); -} - -STATIC void -xlog_recover_add_item( - struct list_head *head) -{ - xlog_recover_item_t *item; - - item = kmem_zalloc(sizeof(xlog_recover_item_t), KM_SLEEP); - INIT_LIST_HEAD(&item->ri_list); - list_add_tail(&item->ri_list, head); -} - -STATIC int -xlog_recover_add_to_cont_trans( - struct xlog *log, - struct xlog_recover *trans, - xfs_caddr_t dp, - int len) -{ - xlog_recover_item_t *item; - xfs_caddr_t ptr, old_ptr; - int old_len; - - if (list_empty(&trans->r_itemq)) { - /* finish copying rest of trans header */ - xlog_recover_add_item(&trans->r_itemq); - ptr = (xfs_caddr_t) &trans->r_theader + - sizeof(xfs_trans_header_t) - len; - memcpy(ptr, dp, len); /* d, s, l */ - return 0; - } - /* take the tail entry */ - item = list_entry(trans->r_itemq.prev, xlog_recover_item_t, ri_list); - - old_ptr = item->ri_buf[item->ri_cnt-1].i_addr; - old_len = item->ri_buf[item->ri_cnt-1].i_len; - - ptr = kmem_realloc(old_ptr, len+old_len, old_len, KM_SLEEP); - memcpy(&ptr[old_len], dp, len); /* d, s, l */ - item->ri_buf[item->ri_cnt-1].i_len += len; - item->ri_buf[item->ri_cnt-1].i_addr = ptr; - trace_xfs_log_recover_item_add_cont(log, trans, item, 0); - return 0; -} - -/* - * The next region to add is the start of a new region. It could be - * a whole region or it could be the first part of a new region. Because - * of this, the assumption here is that the type and size fields of all - * format structures fit into the first 32 bits of the structure. - * - * This works because all regions must be 32 bit aligned. Therefore, we - * either have both fields or we have neither field. In the case we have - * neither field, the data part of the region is zero length. We only have - * a log_op_header and can throw away the header since a new one will appear - * later. If we have at least 4 bytes, then we can determine how many regions - * will appear in the current log item. - */ -STATIC int -xlog_recover_add_to_trans( - struct xlog *log, - struct xlog_recover *trans, - xfs_caddr_t dp, - int len) -{ - xfs_inode_log_format_t *in_f; /* any will do */ - xlog_recover_item_t *item; - xfs_caddr_t ptr; - - if (!len) - return 0; - if (list_empty(&trans->r_itemq)) { - /* we need to catch log corruptions here */ - if (*(uint *)dp != XFS_TRANS_HEADER_MAGIC) { - xfs_warn(log->l_mp, "%s: bad header magic number", - __func__); - ASSERT(0); - return -EIO; - } - if (len == sizeof(xfs_trans_header_t)) - xlog_recover_add_item(&trans->r_itemq); - memcpy(&trans->r_theader, dp, len); /* d, s, l */ - return 0; - } - - ptr = kmem_alloc(len, KM_SLEEP); - memcpy(ptr, dp, len); - in_f = (xfs_inode_log_format_t *)ptr; - - /* take the tail entry */ - item = list_entry(trans->r_itemq.prev, xlog_recover_item_t, ri_list); - if (item->ri_total != 0 && - item->ri_total == item->ri_cnt) { - /* tail item is in use, get a new one */ - xlog_recover_add_item(&trans->r_itemq); - item = list_entry(trans->r_itemq.prev, - xlog_recover_item_t, ri_list); - } - - if (item->ri_total == 0) { /* first region to be added */ - if (in_f->ilf_size == 0 || - in_f->ilf_size > XLOG_MAX_REGIONS_IN_ITEM) { - xfs_warn(log->l_mp, - "bad number of regions (%d) in inode log format", - in_f->ilf_size); - ASSERT(0); - kmem_free(ptr); - return -EIO; - } - - item->ri_total = in_f->ilf_size; - item->ri_buf = - kmem_zalloc(item->ri_total * sizeof(xfs_log_iovec_t), - KM_SLEEP); - } - ASSERT(item->ri_total > item->ri_cnt); - /* Description region is ri_buf[0] */ - item->ri_buf[item->ri_cnt].i_addr = ptr; - item->ri_buf[item->ri_cnt].i_len = len; - item->ri_cnt++; - trace_xfs_log_recover_item_add(log, trans, item, 0); - return 0; -} - /* * Sort the log items in the transaction. * @@ -3252,31 +3098,6 @@ xlog_recover_do_icreate_pass2( return 0; } -/* - * Free up any resources allocated by the transaction - * - * Remember that EFIs, EFDs, and IUNLINKs are handled later. - */ -STATIC void -xlog_recover_free_trans( - struct xlog_recover *trans) -{ - xlog_recover_item_t *item, *n; - int i; - - list_for_each_entry_safe(item, n, &trans->r_itemq, ri_list) { - /* Free the regions in the item. */ - list_del(&item->ri_list); - for (i = 0; i < item->ri_cnt; i++) - kmem_free(item->ri_buf[i].i_addr); - /* Free the item itself */ - kmem_free(item->ri_buf); - kmem_free(item); - } - /* Free the transaction recover structure */ - kmem_free(trans); -} - STATIC void xlog_recover_buffer_ra_pass2( struct xlog *log, @@ -3530,6 +3351,185 @@ out: return error ? error : error2; } + +STATIC xlog_recover_t * +xlog_recover_find_tid( + struct hlist_head *head, + xlog_tid_t tid) +{ + xlog_recover_t *trans; + + hlist_for_each_entry(trans, head, r_list) { + if (trans->r_log_tid == tid) + return trans; + } + return NULL; +} + +STATIC void +xlog_recover_new_tid( + struct hlist_head *head, + xlog_tid_t tid, + xfs_lsn_t lsn) +{ + xlog_recover_t *trans; + + trans = kmem_zalloc(sizeof(xlog_recover_t), KM_SLEEP); + trans->r_log_tid = tid; + trans->r_lsn = lsn; + INIT_LIST_HEAD(&trans->r_itemq); + + INIT_HLIST_NODE(&trans->r_list); + hlist_add_head(&trans->r_list, head); +} + +STATIC void +xlog_recover_add_item( + struct list_head *head) +{ + xlog_recover_item_t *item; + + item = kmem_zalloc(sizeof(xlog_recover_item_t), KM_SLEEP); + INIT_LIST_HEAD(&item->ri_list); + list_add_tail(&item->ri_list, head); +} + +STATIC int +xlog_recover_add_to_cont_trans( + struct xlog *log, + struct xlog_recover *trans, + xfs_caddr_t dp, + int len) +{ + xlog_recover_item_t *item; + xfs_caddr_t ptr, old_ptr; + int old_len; + + if (list_empty(&trans->r_itemq)) { + /* finish copying rest of trans header */ + xlog_recover_add_item(&trans->r_itemq); + ptr = (xfs_caddr_t) &trans->r_theader + + sizeof(xfs_trans_header_t) - len; + memcpy(ptr, dp, len); + return 0; + } + /* take the tail entry */ + item = list_entry(trans->r_itemq.prev, xlog_recover_item_t, ri_list); + + old_ptr = item->ri_buf[item->ri_cnt-1].i_addr; + old_len = item->ri_buf[item->ri_cnt-1].i_len; + + ptr = kmem_realloc(old_ptr, len+old_len, old_len, KM_SLEEP); + memcpy(&ptr[old_len], dp, len); + item->ri_buf[item->ri_cnt-1].i_len += len; + item->ri_buf[item->ri_cnt-1].i_addr = ptr; + trace_xfs_log_recover_item_add_cont(log, trans, item, 0); + return 0; +} + +/* + * The next region to add is the start of a new region. It could be + * a whole region or it could be the first part of a new region. Because + * of this, the assumption here is that the type and size fields of all + * format structures fit into the first 32 bits of the structure. + * + * This works because all regions must be 32 bit aligned. Therefore, we + * either have both fields or we have neither field. In the case we have + * neither field, the data part of the region is zero length. We only have + * a log_op_header and can throw away the header since a new one will appear + * later. If we have at least 4 bytes, then we can determine how many regions + * will appear in the current log item. + */ +STATIC int +xlog_recover_add_to_trans( + struct xlog *log, + struct xlog_recover *trans, + xfs_caddr_t dp, + int len) +{ + xfs_inode_log_format_t *in_f; /* any will do */ + xlog_recover_item_t *item; + xfs_caddr_t ptr; + + if (!len) + return 0; + if (list_empty(&trans->r_itemq)) { + /* we need to catch log corruptions here */ + if (*(uint *)dp != XFS_TRANS_HEADER_MAGIC) { + xfs_warn(log->l_mp, "%s: bad header magic number", + __func__); + ASSERT(0); + return -EIO; + } + if (len == sizeof(xfs_trans_header_t)) + xlog_recover_add_item(&trans->r_itemq); + memcpy(&trans->r_theader, dp, len); + return 0; + } + + ptr = kmem_alloc(len, KM_SLEEP); + memcpy(ptr, dp, len); + in_f = (xfs_inode_log_format_t *)ptr; + + /* take the tail entry */ + item = list_entry(trans->r_itemq.prev, xlog_recover_item_t, ri_list); + if (item->ri_total != 0 && + item->ri_total == item->ri_cnt) { + /* tail item is in use, get a new one */ + xlog_recover_add_item(&trans->r_itemq); + item = list_entry(trans->r_itemq.prev, + xlog_recover_item_t, ri_list); + } + + if (item->ri_total == 0) { /* first region to be added */ + if (in_f->ilf_size == 0 || + in_f->ilf_size > XLOG_MAX_REGIONS_IN_ITEM) { + xfs_warn(log->l_mp, + "bad number of regions (%d) in inode log format", + in_f->ilf_size); + ASSERT(0); + kmem_free(ptr); + return -EIO; + } + + item->ri_total = in_f->ilf_size; + item->ri_buf = + kmem_zalloc(item->ri_total * sizeof(xfs_log_iovec_t), + KM_SLEEP); + } + ASSERT(item->ri_total > item->ri_cnt); + /* Description region is ri_buf[0] */ + item->ri_buf[item->ri_cnt].i_addr = ptr; + item->ri_buf[item->ri_cnt].i_len = len; + item->ri_cnt++; + trace_xfs_log_recover_item_add(log, trans, item, 0); + return 0; +} +/* + * Free up any resources allocated by the transaction + * + * Remember that EFIs, EFDs, and IUNLINKs are handled later. + */ +STATIC void +xlog_recover_free_trans( + struct xlog_recover *trans) +{ + xlog_recover_item_t *item, *n; + int i; + + list_for_each_entry_safe(item, n, &trans->r_itemq, ri_list) { + /* Free the regions in the item. */ + list_del(&item->ri_list); + for (i = 0; i < item->ri_cnt; i++) + kmem_free(item->ri_buf[i].i_addr); + /* Free the item itself */ + kmem_free(item->ri_buf); + kmem_free(item); + } + /* Free the transaction recover structure */ + kmem_free(trans); +} + /* * On error or completion, trans is freed. */ -- 2.0.0 From dave@fromorbit.com Thu Sep 25 21:19:25 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6B54A7FF7 for ; Thu, 25 Sep 2014 21:19:25 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 17B57AC001 for ; Thu, 25 Sep 2014 19:19:24 -0700 (PDT) X-ASG-Debug-ID: 1411697957-04bdf003a230c5c0001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id cqhKsawIuzmlyazF for ; Thu, 25 Sep 2014 19:19:17 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Avk0AG7MJFR5LHimPGdsb2JhbABggw5TV7YYAgoMAQEBAQEBBnIBhGqOG4hSFwEGAQEBATg5hGA7gQIDB4hqDpwMpWCGEod5gjCENQWWGpNDimMBgi0rLwGCSQEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail05.adl6.internode.on.net with ESMTP; 26 Sep 2014 11:49:16 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XXL7q-0000Ri-PW for xfs@oss.sgi.com; Fri, 26 Sep 2014 12:19:14 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XXL7q-0006Rv-Og for xfs@oss.sgi.com; Fri, 26 Sep 2014 12:19:14 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 0/5 v2] xfs: clean up xlog_recover_process_data Date: Fri, 26 Sep 2014 12:19:07 +1000 X-ASG-Orig-Subj: [PATCH 0/5 v2] xfs: clean up xlog_recover_process_data Message-Id: <1411697952-24741-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1411697957 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9888 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi folks, This is a new version of the log recovery transaction processing cleanup I first posted here: http://oss.sgi.com/archives/xfs/2014-08/msg00367.html It's largely the same, but there's been a couple of but fixes and rework done to it. Version 2 - use sizeof(variable) consistently - reworked transaction lookup factoring to encapsulate start ophdr processing completely. - re-ordered checks for opheader length validity to so we do all the ophdr validity checks before we try to process it. - added patch to re-integrate simple use-once functions to look up and allocate recovery transaction structures. -Dave. From dave@fromorbit.com Thu Sep 25 21:19:27 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1290D7FF3 for ; Thu, 25 Sep 2014 21:19:27 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 843D3AC001 for ; Thu, 25 Sep 2014 19:19:23 -0700 (PDT) X-ASG-Debug-ID: 1411697960-04cb6c50e52bf730001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id fdzNjgzl8Rgrh6wo for ; Thu, 25 Sep 2014 19:19:20 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AsoUAG7MJFR5LHimPGdsb2JhbABggw6BKoc4rngBAQEBAQEGnEoXAQYBAQEBODmEBAEFJy8zCBgxOQMHFBmIPcF6hhKOXgWGJqM3iwgegWsrL4JKAQEB Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail05.adl6.internode.on.net with ESMTP; 26 Sep 2014 11:49:16 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XXL7q-0000Rj-Pr for xfs@oss.sgi.com; Fri, 26 Sep 2014 12:19:14 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XXL7q-0006Ry-PF for xfs@oss.sgi.com; Fri, 26 Sep 2014 12:19:14 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 1/5] xfs: refactor xlog_recover_process_data() Date: Fri, 26 Sep 2014 12:19:08 +1000 X-ASG-Orig-Subj: [PATCH 1/5] xfs: refactor xlog_recover_process_data() Message-Id: <1411697952-24741-2-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1411697952-24741-1-git-send-email-david@fromorbit.com> References: <1411697952-24741-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1411697960 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9889 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner Clean up xlog_recover_process_data() structure in preparation for fixing the allocation and freeing context of the transaction being recovered. Signed-off-by: Dave Chinner --- fs/xfs/xfs_log_recover.c | 200 ++++++++++++++++++++++++++++++----------------- 1 file changed, 127 insertions(+), 73 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index c6427b3..b5e081b 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -3533,12 +3533,122 @@ out: } STATIC int -xlog_recover_unmount_trans( - struct xlog *log) +xlog_recovery_process_trans( + struct xlog *log, + struct xlog_recover *trans, + xfs_caddr_t dp, + unsigned int len, + unsigned int flags, + int pass) { - /* Do nothing now */ - xfs_warn(log->l_mp, "%s: Unmount LR", __func__); - return 0; + int error = -EIO; + + /* mask off ophdr transaction container flags */ + flags &= ~XLOG_END_TRANS; + if (flags & XLOG_WAS_CONT_TRANS) + flags &= ~XLOG_CONTINUE_TRANS; + + switch (flags) { + /* expected flag values */ + case 0: + case XLOG_CONTINUE_TRANS: + error = xlog_recover_add_to_trans(log, trans, dp, len); + break; + case XLOG_WAS_CONT_TRANS: + error = xlog_recover_add_to_cont_trans(log, trans, dp, len); + break; + case XLOG_COMMIT_TRANS: + error = xlog_recover_commit_trans(log, trans, pass); + break; + + /* unexpected flag values */ + case XLOG_UNMOUNT_TRANS: + xfs_warn(log->l_mp, "%s: Unmount LR", __func__); + error = 0; /* just skip trans */ + break; + case XLOG_START_TRANS: + xfs_warn(log->l_mp, "%s: bad transaction", __func__); + ASSERT(0); + break; + default: + xfs_warn(log->l_mp, "%s: bad flag 0x%x", __func__, flags); + ASSERT(0); + break; + } + return error; +} + +STATIC struct xlog_recover * +xlog_recover_ophdr_to_trans( + struct hlist_head rhash[], + struct xlog_rec_header *rhead, + struct xlog_op_header *ohead) +{ + struct xlog_recover *trans; + xlog_tid_t tid; + struct hlist_head *rhp; + + tid = be32_to_cpu(ohead->oh_tid); + rhp = &rhash[XLOG_RHASH(tid)]; + trans = xlog_recover_find_tid(rhp, tid); + if (trans) + return trans; + + /* + * If this is a new transaction, the ophdr only contains the + * start record. In that case, the only processing we need to do + * on this opheader is allocate a new recovery container to hold + * the recovery ops that will follow. + */ + if (ohead->oh_flags & XLOG_START_TRANS) + xlog_recover_new_tid(rhp, tid, be64_to_cpu(rhead->h_lsn)); + return NULL; +} + +STATIC int +xlog_recover_process_ophdr( + struct xlog *log, + struct hlist_head rhash[], + struct xlog_rec_header *rhead, + struct xlog_op_header *ohead, + xfs_caddr_t dp, + xfs_caddr_t lp, + int pass) +{ + struct xlog_recover *trans; + int error; + unsigned int len; + + /* Do we understand who wrote this op? */ + if (ohead->oh_clientid != XFS_TRANSACTION && + ohead->oh_clientid != XFS_LOG) { + xfs_warn(log->l_mp, "%s: bad clientid 0x%x", + __func__, ohead->oh_clientid); + ASSERT(0); + return -EIO; + } + + /* + * Check the ophdr contains all the data it is supposed to contain. + */ + len = be32_to_cpu(ohead->oh_len); + if (dp + len > lp) { + xfs_warn(log->l_mp, "%s: bad length 0x%x", __func__, len); + WARN_ON(1); + return -EIO; + } + + trans = xlog_recover_ophdr_to_trans(rhash, rhead, ohead); + if (!trans) { + /* nothing to do, so skip over this ophdr */ + return 0; + } + + error = xlog_recovery_process_trans(log, trans, dp, len, + ohead->oh_flags, pass); + if (error) + xlog_recover_free_trans(trans); + return error; } /* @@ -3558,14 +3668,10 @@ xlog_recover_process_data( xfs_caddr_t dp, int pass) { + struct xlog_op_header *ohead; xfs_caddr_t lp; int num_logops; - xlog_op_header_t *ohead; - xlog_recover_t *trans; - xlog_tid_t tid; int error; - unsigned long hash; - uint flags; lp = dp + be32_to_cpu(rhead->h_len); num_logops = be32_to_cpu(rhead->h_num_logops); @@ -3575,69 +3681,17 @@ xlog_recover_process_data( return -EIO; while ((dp < lp) && num_logops) { - ASSERT(dp + sizeof(xlog_op_header_t) <= lp); - ohead = (xlog_op_header_t *)dp; - dp += sizeof(xlog_op_header_t); - if (ohead->oh_clientid != XFS_TRANSACTION && - ohead->oh_clientid != XFS_LOG) { - xfs_warn(log->l_mp, "%s: bad clientid 0x%x", - __func__, ohead->oh_clientid); - ASSERT(0); - return -EIO; - } - tid = be32_to_cpu(ohead->oh_tid); - hash = XLOG_RHASH(tid); - trans = xlog_recover_find_tid(&rhash[hash], tid); - if (trans == NULL) { /* not found; add new tid */ - if (ohead->oh_flags & XLOG_START_TRANS) - xlog_recover_new_tid(&rhash[hash], tid, - be64_to_cpu(rhead->h_lsn)); - } else { - if (dp + be32_to_cpu(ohead->oh_len) > lp) { - xfs_warn(log->l_mp, "%s: bad length 0x%x", - __func__, be32_to_cpu(ohead->oh_len)); - WARN_ON(1); - return -EIO; - } - flags = ohead->oh_flags & ~XLOG_END_TRANS; - if (flags & XLOG_WAS_CONT_TRANS) - flags &= ~XLOG_CONTINUE_TRANS; - switch (flags) { - case XLOG_COMMIT_TRANS: - error = xlog_recover_commit_trans(log, - trans, pass); - break; - case XLOG_UNMOUNT_TRANS: - error = xlog_recover_unmount_trans(log); - break; - case XLOG_WAS_CONT_TRANS: - error = xlog_recover_add_to_cont_trans(log, - trans, dp, - be32_to_cpu(ohead->oh_len)); - break; - case XLOG_START_TRANS: - xfs_warn(log->l_mp, "%s: bad transaction", - __func__); - ASSERT(0); - error = -EIO; - break; - case 0: - case XLOG_CONTINUE_TRANS: - error = xlog_recover_add_to_trans(log, trans, - dp, be32_to_cpu(ohead->oh_len)); - break; - default: - xfs_warn(log->l_mp, "%s: bad flag 0x%x", - __func__, flags); - ASSERT(0); - error = -EIO; - break; - } - if (error) { - xlog_recover_free_trans(trans); - return error; - } - } + + ohead = (struct xlog_op_header *)dp; + dp += sizeof(*ohead); + ASSERT(dp <= lp); + + /* errors will abort recovery */ + error = xlog_recover_process_ophdr(log, rhash, rhead, ohead, + dp, lp, pass); + if (error) + return error; + dp += be32_to_cpu(ohead->oh_len); num_logops--; } -- 2.0.0 From pkuelelixi@gmail.com Thu Sep 25 21:45:32 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 805717FEF for ; Thu, 25 Sep 2014 21:45:32 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6CEA58F8033 for ; Thu, 25 Sep 2014 19:45:32 -0700 (PDT) X-ASG-Debug-ID: 1411699530-04cbb073033ae2c0001-NocioJ Received: from mail-ie0-f169.google.com (mail-ie0-f169.google.com [209.85.223.169]) by cuda.sgi.com with ESMTP id 60IfMoEcYWftNhZ5 (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Thu, 25 Sep 2014 19:45:30 -0700 (PDT) X-Barracuda-Envelope-From: pkuelelixi@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.223.169 X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.169] Received: by mail-ie0-f169.google.com with SMTP id rp18so13040113iec.0 for ; Thu, 25 Sep 2014 19:45:30 -0700 (PDT) X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.169] X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.169] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; bh=alsIVr4YV7pnvQ15Bp2BBE5tShpsLmfAq8zS9CfJqOU=; b=hMhHunNRtjelFHaVM/rugVZedqY7dI4zimNgOwcUctCP6XQtGV/8BgfpanlKPXJq6F NNTYvsa6zueWjYMJwIEDM0TBQGFpIqA7PTVbsR9zSMJetgDbx5HdjsiiJf+K7yAIg0so TX5cNxE3yUYg12zvJnp+rPw5svXfHa7xC1HsrTlZJ13bcIawl3OFMY6a1tm2oX2kkRtF HeZT3jQfS/+ohhCQ/zk3xlKTJwyu1K20PHJlqqw+RkO0RZWcFE6oc5CJ6Syy0tJmbXKt AAYMzOrnFvnvGYG2LmUtN8i2rMM2DSxVc6rH5o5L9JV9g+QZejP9yHwLaArgIjtAuwXs VzXw== MIME-Version: 1.0 X-Received: by 10.42.207.131 with SMTP id fy3mr21816878icb.67.1411699530525; Thu, 25 Sep 2014 19:45:30 -0700 (PDT) Received: by 10.42.209.210 with HTTP; Thu, 25 Sep 2014 19:45:30 -0700 (PDT) In-Reply-To: <20140926001049.GK4945@dastard> References: <1411567470-31799-1-git-send-email-lixi@ddn.com> <1411567470-31799-5-git-send-email-lixi@ddn.com> <20140924162507.GC27000@quack.suse.cz> <20140924162634.GA16886@infradead.org> <20140924170105.GE27000@quack.suse.cz> <20140925075912.GG4758@dastard> <20140926001049.GK4945@dastard> Date: Fri, 26 Sep 2014 10:45:30 +0800 Message-ID: Subject: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project From: Li Xi X-ASG-Orig-Subj: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project To: Dave Chinner Cc: Jan Kara , Christoph Hellwig , Andreas Dilger , "linux-api@vger.kernel.org" , xfs@oss.sgi.com, Dmitry Monakhov , "viro@zeniv.linux.org.uk" , "linux-fsdevel@vger.kernel.org" , "Theodore Ts'o" , Ext4 Developers List Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail-ie0-f169.google.com[209.85.223.169] X-Barracuda-Start-Time: 1411699530 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9889 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Fri, Sep 26, 2014 at 8:10 AM, Dave Chinner wrote: > On Thu, Sep 25, 2014 at 07:34:38PM +0800, lixi wrote: >> Hi Dave, >> >> I was mostly working on the semantics of inherit flag on these patches. = And >> I didn=E2=80=99t realized that the interface differences would bother yo= u so much. Sorry >> for that. > > It's not the differences that bother me - it's the fact that I was > repeatedly ignored until someone else raised the same issue.... Sorry about that. Since we are implementing a feature which exsits in XFS for years, your opions are surely very important. They are not ignored. But I think more discussion is necessary before an common agreement is reached. And I am willing to change the interfaces to whatever all people agree on. > >> I agree that we should choose a good interface. It would be good that it= is >> general so that it works well for all file systems. I agree that adding = an >> ext4 specific ioctl() is far from the best choice. I am willing to chang= e it to >> any general interface. A general ioctl() sounds good to me. Extend setat= tr() >> and getattr() for project ID sounds even better, since project ID looks = like >> UID/GID. > > Ah, no, project ID is not a uid/gid. It's a completely independent > construct. > > [ Which brings me to, once again, the issue of being ignored during > reviews: project IDs should not be mapped by user namespaces, nor be > accessible from anything other than the init namespace. > > In XFS we've turned off access to project IDs within namespace > containers because they are used for container space management > (i.e. by the init namespace) to manage the amount of filesystem > space a container or set of containers can use. We do not want > project IDs to be manipulated from within such containers, and > therefore have to prevent access to them from within user > namespaces. ] OK. That is another semantics which needs further discussion whether we need to implement for Ext4. Container space management is one of the project quota use case. I am not sure how widely used it is, but I like features with less limits. > >> And general xattr name is another choice. But it is might be a little >> bit confusing if we use xattr actually, since we are not saving project = ID as >> extended attribute on Ext4. Any choice is fine with me, as long as the >> implementation won't introduce nasty codes or inconsistent design. > > We can easily create another ioctl name if we have to. It just needs > sto be defined to the same value as the XFS ioctl names currently > are. We've done this before when making ioctls that originated in > XFS generic (e.g. with freeze/thaw ioctls).... OK. I am fine with general ioctl to set/get project ID. > >> However, the problem is, I do not quite understand why we should keep >> the interface exactly the same with XFS. It would be good if we can. But >> as far as I can see, it seems hard. XFS uses a lot interfaces which are >> not so standard and used by other file systems. For example, struct >> fsxattr is not used by other file systems at all except XFS. > > Moving a existing structure definitions to a different header file > is too hard? I don't think difficulty is a big problem. I'm wondering whether it is necessary. > >> I am not sure why we should introduce this into Ext4 if there are >> a lot of other better ways. I would be happy to change to XFS >> interfaces, if it is general. However, I don=E2=80=99t think it is >> general enough. > > How is it not general enough? Examples, please, not handwaving: > which bit of the quota interface can't ext4 use because it's XFS > specific? Well, I am not so familar with XFS, so I might be all wrong about XFS. But honestly, a lot of quota interfaces of XFS seems not so standard. For example, all the Q_X* flags used in do_quotactl(). Maybe there are really good reasons why they are there. I don't know. And XFS does not use general codes under fs/quota. That is a big difference with Ext4. > > We already have a perfectly functional interface and a large body of > code that implements and tests it. You're saying "oh, it's too much > work for me to implement an existing interface" and ignoring the > fact that not implementing the existing interface forces a huge > amount of downstream work. e.g. > > - we need completely new test infrastructure to replicate > existing tests. > - we need new tests to ensure the different APIs and > utilities provide the same functionality, and that the > work identically. > - administrators are going to have to learn how ext4 is > different to what they already know and understand. > - administrators that has tools written to manage project > quotas is going to have to rewrite them to support ext4. > > It's an entirely selfish argument that ignores what already existing > out in userspace. i.e. you're saying that existing downstream users of > project quotas simple don't matter to you... > >> I know xfstest is using the existing project quota interfaces of XFS. An= d >> maybe there are some applications which are using them too. But >> keeping the interfaces exactly the same with XFS would cost so much >> effort that I=E2=80=99d like to get enough reasons before start working = on it. Is it >> really necessary? I am not so sure. > > You have to have a stronger argument than that to justify creating a > new incompatible user interface. The XFS interfaces have been > available for more than 10 years and support all the functionality > ext4 requires. If it was any other userspace interface (e.g. > syscalls) or any filesystem other than ext4 there would be people > from all over telling you "use the existing interfaces!" and you'd > need very strong reasons for creating a new one. > > i.e. you need to demonstrate that the existing interfaces are > inadequate for the intended purpose of the new functionality. That's > clearly not the case here so why should we allow you to create an > incompatible userspace API rather than use the existing, fully > functional API? > >> It is so easy to change user space applications comparing to >> changing a weird interfaces. > > The existing generic quota tools (i.e quotactl, repquota, etc) > already implement the XFS quota API to be able to query XFS > filesystems. There's no "changing to wierd interfaces" necessary > for userspace; it's already all there. Hence any work you do to add > project quota awareness to those generic userspace tools will need to > add the support to the XFS queries anyway. > > IOWs, you're not making it any easier for yourself in userspace by > creating a new API for ext4 - it just doubles the amount of work you > have to in userspace to make existing tools project quota aware. I am afraid I have to make existing tools project quota aware. And actually I've done most of the work. I've updated e2fsprogs and quota-tools to support project quota. Unfortunately these updates are inevitable anyway. As Jan Kara said, we can't force system admins to change from quota-tool command to xfs quota tools. Thus, I add '-P $PROJECT' arguments to all the commands. And based on those tools, I made a script which is less than 1K lines for regression test. It is working pretty well. I don't see a good reason why it is necessary to change everything to XFS way. > >> For >> example, I think it won=E2=80=99t cost even more than a day to add xfste= st >> support for new Ext4 project quota. > > A day of whose time? I am always willing to help if you agree. :) > > Ever thought about how much time it will take reviewers to look at > your tests and iterate over them to get it all right? If you're > introducing new userspace infrastructure that xfstests will need to > depend on and test for, then it's a lot more than just writing new > tests. > > Indeed, I'm likely to want new project quota tests to be generic > (i.e. works and passes on any filesystem that supports project > quotas) with the introduction of ext4 project quota support. It's > the same functionality and so it should work the same just like user > and group quotas do across all filesystems. > >> And since project quota is far from >> a widely used feature, > > I don't think you realise quite how widespread it's use is on XFS. > >> I don=E2=80=99t think there is much compatibility problems >> for existing applications. And If the new project interface are general >> enough, there won=E2=80=99t be any compatibility problems for new applic= ations >> at all. > > Again, you are ignoring the compatibility problems with existing > applications that are project quota aware. For them you are > *creating new compatibility problems* by implementing a new > interface. i.e. Existing applications will not work on ext4, and > new applications written to work on ext4 won't work on XFS. > > That's the crux of the issue - we have existing applications using > the existing interface and so introducing a new interface introduces > compatibility problems. You can't just wave this problem away > because you don't think the existing interface matters. > > "It's easier for me to create a new interface" is not a valid reason > for creating a new interface.... Sorry about my ignorance about the existing usage of XFS project quota. I hope it is widely used. But does it really matters for XFS that what kind of Ext4 interfaces is going to use? Existing appplications would run happily on XFS any way using the exisitng XFS interfaces. And if you are concerning about the compatibility between Ext4 and XFS, I am afraid those applications have to be changed any way when been ported to Ext4. Since those applications are using XFS specific feature, i.e. project quota, it is likely they are using other kind of XFS speicific features which probably will never be implemented on Ext4. I don't think there is any easy way to port them from XFS to Ext4 any way. And I really don't think therea are many such kind of applications. So, since we are not implementing interfaces for XFS2 or XFS3, I don't think compatibility problem is so critical. Regards, - Li Xi From bounce@client.emailtech.co.in Fri Sep 26 02:29:11 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: **** X-Spam-Status: No, score=4.8 required=5.0 tests=DATE_IN_PAST_03_06, HTML_IMAGE_RATIO_02,HTML_MESSAGE,NORMAL_HTTP_TO_IP,RCVD_NUMERIC_HELO autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 792337FF1 for ; Fri, 26 Sep 2014 02:29:11 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 239EFAC001 for ; Fri, 26 Sep 2014 00:29:07 -0700 (PDT) X-ASG-Debug-ID: 1411716542-04bdf003a233e6b0001-NocioJ Received: from server.emailtech.co.in (server.emailtech.co.in [23.239.23.80]) by cuda.sgi.com with ESMTP id DTxTEZi2SQQw0oF9 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 00:29:02 -0700 (PDT) X-Barracuda-Envelope-From: bounce@client.emailtech.co.in X-Barracuda-Apparent-Source-IP: 23.239.23.80 Received: from localhost ([::1]:41295 helo=23.239.23.80) by li744-80 with esmtpa (Exim 4.82) (envelope-from ) id 1XXPxd-0007lB-Jf for xfs@oss.sgi.com; Fri, 26 Sep 2014 07:29:01 +0000 To: xfs@oss.sgi.com Subject: Paramount Group Of Companies Cordially Invites You To Golfforeste Carnival Of Colors Message-ID: <339ee24fecbb05c86663b5bf9805f19f@23.239.23.80> X-ASG-Orig-Subj: Paramount Group Of Companies Cordially Invites You To Golfforeste Carnival Of Colors Date: Fri, 26 Sep 2014 03:14:28 +0000 From: "Smriti Ahuja" Reply-To: noreply@client.emailtech.co.in MIME-Version: 1.0 X-Mailer-LID: 4 List-Unsubscribe: X-Mailer-SID: 4 X-Mailer-Sent-By: 2 Content-Type: multipart/alternative; charset="UTF-8"; boundary="b1_4015bff0d2ead51b69303c42c83d7725" Content-Transfer-Encoding: 8bit X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - server.emailtech.co.in X-AntiAbuse: Original Domain - oss.sgi.com X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - client.emailtech.co.in X-Get-Message-Sender-Via: server.emailtech.co.in: authenticated_id: clientem/from_h X-Barracuda-Connect: server.emailtech.co.in[23.239.23.80] X-Barracuda-Start-Time: 1411716542 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.64 X-Barracuda-Spam-Status: No, SCORE=1.64 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DATE_IN_PAST_03_06, DATE_IN_PAST_03_06_2, HTML_IMAGE_RATIO_02, HTML_MESSAGE, NORMAL_HTTP_TO_IP X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9897 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 DATE_IN_PAST_03_06 Date: is 3 to 6 hours before Received: date 0.00 NORMAL_HTTP_TO_IP URI: Uses a dotted-decimal IP address in URL 0.55 HTML_IMAGE_RATIO_02 BODY: HTML has a low ratio of text to image area 0.00 HTML_MESSAGE BODY: HTML included in message 1.08 DATE_IN_PAST_03_06_2 DATE_IN_PAST_03_06_2 --b1_4015bff0d2ead51b69303c42c83d7725 Content-Type: text/plain; format=flowed; charset="UTF-8" Content-Transfer-Encoding: 8bit ********************** DISCLAIMER********************** This e-mail may contain Confidential and/or Legally Privileged Information and is meant for the intended recipient(s) only. If you have received this e-mail in error and are not the intended recipient/s: 1. Delete this e-mail immediately from your system. 2. Do not copy, forward, disclose, or otherwise use it or any part of it in any form whatsoever. Internet Communication cannot be guaranteed to be secure or error-free as information could be delayed, intercepted, corrupted, lost, or can contain viruses. Paramount Group does not accept any liability for any error, omissions, viruses or computer related problems experienced by any recipient as a result of this e-mail. Click this link to unsubscribe: http://23.239.23.80/~clientem/unsubscribe.php?M=868046&C=864702df6ad2b1ae7c53b97a16e77908&L=4&N=4 --b1_4015bff0d2ead51b69303c42c83d7725 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: 8bit

                                                               ********************** DISCLAIMER**********************
This e-mail may contain Confidential and/or Legally Privileged Information and is meant for the intended recipient(s) only. If you have received this e-mail in error and are not the intended recipient/s: 1. Delete this e-mail immediately from your system. 2. Do not copy, forward, disclose, or otherwise use it or any part of it in any form whatsoever.

Internet Communication cannot be guaranteed to be secure or error-free as information could be delayed, intercepted, corrupted, lost, or can contain viruses. Paramount Group does not accept any liability for any error, omissions, viruses or computer related problems experienced by any recipient as a result of this e-mail.

Unsubscribe me from this list

--b1_4015bff0d2ead51b69303c42c83d7725-- From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 04:44:41 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 9A7057FF1 for ; Fri, 26 Sep 2014 04:44:41 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7978530408D for ; Fri, 26 Sep 2014 02:44:38 -0700 (PDT) X-ASG-Debug-ID: 1411724676-04cb6c50e72e7310001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id J6sBCFQpu9HKpARC (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 02:44:37 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXS4q-0003uu-BM; Fri, 26 Sep 2014 09:44:36 +0000 Date: Fri, 26 Sep 2014 02:44:36 -0700 From: Christoph Hellwig To: Dave Chinner Cc: Christoph Hellwig , xfs@oss.sgi.com Subject: Re: [PATCH 1/3] xfs: consider freeze levels in xfs_fs_writable() Message-ID: <20140926094436.GA10692@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 1/3] xfs: consider freeze levels in xfs_fs_writable() References: <1411647632-28240-1-git-send-email-david@fromorbit.com> <1411647632-28240-2-git-send-email-david@fromorbit.com> <20140925161756.GA25798@infradead.org> <20140925210330.GG4945@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140925210330.GG4945@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411724677 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9900 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Fri, Sep 26, 2014 at 07:03:30AM +1000, Dave Chinner wrote: > I can mention it, but it's so trivial I didn't think it was worth > it. It does change behavior, so it should document why that was changed. > The changelog says "Hence allow the caller to pass in the freeze > level it is allowed to write" which is exactly what this code is > doing. The changelog says the you can pass the argument now. It doesn't say that it did change a caller to pass a different argument, and more importanly why. From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 04:45:52 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id AE0D97FF3 for ; Fri, 26 Sep 2014 04:45:52 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9B9C930405F for ; Fri, 26 Sep 2014 02:45:52 -0700 (PDT) X-ASG-Debug-ID: 1411724751-04cbb073023cd960001-NocioJ Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) by cuda.sgi.com with ESMTP id D2t6AM7txRkXDhNr (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 02:45:51 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXS62-0006A1-Tl; Fri, 26 Sep 2014 09:45:50 +0000 Date: Fri, 26 Sep 2014 02:45:50 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/3] xfs: remove bitfield based superblock updates Message-ID: <20140926094550.GB10692@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 2/3] xfs: remove bitfield based superblock updates References: <1411647632-28240-1-git-send-email-david@fromorbit.com> <1411647632-28240-3-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411647632-28240-3-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: bombadil.infradead.org[198.137.202.9] X-Barracuda-Start-Time: 1411724751 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9900 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This breaks generic/230 for me on an x86-64 VM: --- tests/generic/230.out 2013-11-11 10:38:59.000000000 +0000 +++ /root/xfstests/results//generic/230.out.bad 2014-09-26 09:47:37.000000000 +0000 @@ -23,11 +23,8 @@ Write 900k... Rewrite 1001k... Write 1000k... -pwrite64: Disk quota exceeded Write 4096... -pwrite64: Disk quota exceeded Touch 3+4 Touch 5+6 touch: cannot touch 'SCRATCH_MNT/file6': Disk quota exceeded Touch 5 -touch: cannot touch 'SCRATCH_MNT/file5': Disk quota exceeded From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 04:47:53 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 41DC77FF9 for ; Fri, 26 Sep 2014 04:47:53 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 215F08F8037 for ; Fri, 26 Sep 2014 02:47:50 -0700 (PDT) X-ASG-Debug-ID: 1411724868-04cb6c50e42e7470001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id ElE4bcQ9OaTiGFHT (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 02:47:48 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXS7w-00089o-Ft; Fri, 26 Sep 2014 09:47:48 +0000 Date: Fri, 26 Sep 2014 02:47:48 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/4] xfs: fix use of agi_newino in finobt lookup Message-ID: <20140926094748.GC10692@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 1/4] xfs: fix use of agi_newino in finobt lookup References: <1411601863-19594-1-git-send-email-david@fromorbit.com> <1411601863-19594-2-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411601863-19594-2-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411724868 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9901 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Thu, Sep 25, 2014 at 09:37:40AM +1000, Dave Chinner wrote: > Sparse warns that we are passing the big-endian valueo f agi_newino > to the initial btree lookup function when trying to find a new > inode. This is wrong - we need to pass the host order value, not the > disk order value. This will adversely affect the next inode > allocated, but given that the free inode btree is usually much > smaller than the allocated inode btree it is much less likely to be > a performance issue if we start the search in the wrong place. Looks good. I'm rather surprised this wasn't noticed earlier. Reviewed-by: Christoph Hellwig From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 04:48:02 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 788A28002 for ; Fri, 26 Sep 2014 04:48:02 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1035CAC003 for ; Fri, 26 Sep 2014 02:48:01 -0700 (PDT) X-ASG-Debug-ID: 1411724881-04bdf003a134b2f0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id cKWcRb0V8MGHCJDt (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 02:48:01 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXS89-0008NA-9O; Fri, 26 Sep 2014 09:48:01 +0000 Date: Fri, 26 Sep 2014 02:48:01 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/4] xfs: xfs_qm_dquot_isolate needs locking annotations for sparse Message-ID: <20140926094801.GD10692@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 2/4] xfs: xfs_qm_dquot_isolate needs locking annotations for sparse References: <1411601863-19594-1-git-send-email-david@fromorbit.com> <1411601863-19594-3-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411601863-19594-3-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411724881 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9900 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Thu, Sep 25, 2014 at 09:37:41AM +1000, Dave Chinner wrote: > From: Dave Chinner > > To remove noise from the build. > > Signed-off-by: Dave Chinner Looks good, Reviewed-by: Christoph Hellwig From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 04:48:24 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 329E77FFB for ; Fri, 26 Sep 2014 04:48:24 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id C3268AC01B for ; Fri, 26 Sep 2014 02:48:23 -0700 (PDT) X-ASG-Debug-ID: 1411724901-04cb6c50e42e74d0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id YMY02j5Sr2CxcUJY (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 02:48:21 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXS8T-0000ET-Ec; Fri, 26 Sep 2014 09:48:21 +0000 Date: Fri, 26 Sep 2014 02:48:21 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 3/4] xfs: xfs_kset should be static Message-ID: <20140926094821.GE10692@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 3/4] xfs: xfs_kset should be static References: <1411601863-19594-1-git-send-email-david@fromorbit.com> <1411601863-19594-4-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411601863-19594-4-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411724901 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9901 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Thu, Sep 25, 2014 at 09:37:42AM +1000, Dave Chinner wrote: > From: Dave Chinner > > As it is accessed through the struct xfs_mount and can be set up > entirely from fs/xfs/xfs_super.c > > Signed-off-by: Dave Chinner Looks good, Reviewed-by: Christoph Hellwig From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 04:59:29 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 5CEB78000 for ; Fri, 26 Sep 2014 04:59:29 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 3404930405F for ; Fri, 26 Sep 2014 02:59:29 -0700 (PDT) X-ASG-Debug-ID: 1411725568-04cbb073013cdfa0001-NocioJ Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) by cuda.sgi.com with ESMTP id 0i9Z4WbDz14puRFN (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 02:59:28 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXSJD-0007xd-Mn; Fri, 26 Sep 2014 09:59:27 +0000 Date: Fri, 26 Sep 2014 02:59:27 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 4/4] xfs: annotate user variables passed as void Message-ID: <20140926095927.GF10692@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 4/4] xfs: annotate user variables passed as void References: <1411601863-19594-1-git-send-email-david@fromorbit.com> <1411601863-19594-5-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411601863-19594-5-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: bombadil.infradead.org[198.137.202.9] X-Barracuda-Start-Time: 1411725568 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9901 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 25, 2014 at 09:37:43AM +1000, Dave Chinner wrote: > From: Dave Chinner > > Some argument callbacks can contain user buffers, and sparse warns > about passing them as void pointers. Cast appropriately to remove > the sparse warnings. Looks okay. I don't really like the games we're playing there, but this isn't the time to fix them up.. Reviewed-by: Christoph Hellwig From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 05:00:28 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 6DFF28000 for ; Fri, 26 Sep 2014 05:00:28 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4AB388F8035 for ; Fri, 26 Sep 2014 03:00:28 -0700 (PDT) X-ASG-Debug-ID: 1411725627-04bdf0039f34b8d0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id 4EU5sDQ7g6JCqDve (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 03:00:27 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXSKB-0001F9-BY; Fri, 26 Sep 2014 10:00:27 +0000 Date: Fri, 26 Sep 2014 03:00:27 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/3] xfs: remove bitfield based superblock updates Message-ID: <20140926100027.GG10692@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 2/3] xfs: remove bitfield based superblock updates References: <1411647632-28240-1-git-send-email-david@fromorbit.com> <1411647632-28240-3-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411647632-28240-3-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411725627 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9901 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS > + to->sb_uquotino = cpu_to_be64(from->sb_uquotino); > + if (xfs_sb_version_has_pquotino(from)) { > + to->sb_qflags = be16_to_cpu(from->sb_qflags); > + to->sb_gquotino = cpu_to_be64(from->sb_gquotino); > + to->sb_pquotino = cpu_to_be64(from->sb_pquotino); > + return; > + } sparse complains that the be16_to_cpu should be a cpu_to_be16 for sb_qflags.. From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 05:11:36 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A49548000 for ; Fri, 26 Sep 2014 05:11:36 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 933DA304051 for ; Fri, 26 Sep 2014 03:11:33 -0700 (PDT) X-ASG-Debug-ID: 1411726291-04cbb073023ce580001-NocioJ Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) by cuda.sgi.com with ESMTP id XrfKhdn1qu0Uokfx (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 03:11:32 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXSUt-0007Wo-GF; Fri, 26 Sep 2014 10:11:31 +0000 Date: Fri, 26 Sep 2014 03:11:31 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 03/11] xfs: synchronous buffer IO needs a reference Message-ID: <20140926101131.GA22194@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 03/11] xfs: synchronous buffer IO needs a reference References: <1411648461-29003-1-git-send-email-david@fromorbit.com> <1411648461-29003-4-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411648461-29003-4-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: bombadil.infradead.org[198.137.202.9] X-Barracuda-Start-Time: 1411726292 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9901 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Looks good, Reviewed-by: Christoph Hellwig From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 05:14:42 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 5209A8000 for ; Fri, 26 Sep 2014 05:14:42 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id D2E79AC008 for ; Fri, 26 Sep 2014 03:14:38 -0700 (PDT) X-ASG-Debug-ID: 1411726477-04cb6c50e62e7e00001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id rOfxprehJM5VDeb7 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 03:14:37 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXSXt-0000lz-9W; Fri, 26 Sep 2014 10:14:37 +0000 Date: Fri, 26 Sep 2014 03:14:37 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 04/11] xfs: xfs_buf_ioend and xfs_buf_iodone_work duplicate functionality Message-ID: <20140926101436.GB22194@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 04/11] xfs: xfs_buf_ioend and xfs_buf_iodone_work duplicate functionality References: <1411648461-29003-1-git-send-email-david@fromorbit.com> <1411648461-29003-5-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411648461-29003-5-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411726477 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9901 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS Looks good, Reviewed-by: Christoph Hellwig From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 05:15:46 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 3E0108001 for ; Fri, 26 Sep 2014 05:15:46 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2AA5B304059 for ; Fri, 26 Sep 2014 03:15:46 -0700 (PDT) X-ASG-Debug-ID: 1411726544-04cbb073033ce760001-NocioJ Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) by cuda.sgi.com with ESMTP id Fu5u6D3SMbRdNdGV (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 03:15:45 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXSYy-0002dk-Pe; Fri, 26 Sep 2014 10:15:44 +0000 Date: Fri, 26 Sep 2014 03:15:44 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 05/11] xfs: rework xfs_buf_bio_endio error handling Message-ID: <20140926101544.GC22194@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 05/11] xfs: rework xfs_buf_bio_endio error handling References: <1411648461-29003-1-git-send-email-david@fromorbit.com> <1411648461-29003-6-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411648461-29003-6-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: bombadil.infradead.org[198.137.202.9] X-Barracuda-Start-Time: 1411726545 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9901 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- I still don't understand why we even need b_error on the submission side, we should be able to just pass the error on the stack. But we can sort this out later, and the change looks ok, so: Reviewed-by: Christoph Hellwig From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 05:16:49 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E41D97F89 for ; Fri, 26 Sep 2014 05:16:49 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id D231B8F8037 for ; Fri, 26 Sep 2014 03:16:46 -0700 (PDT) X-ASG-Debug-ID: 1411726605-04cb6c50e42e7ee0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id HrvgiILcCjVmJFWY (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 03:16:46 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXSZx-0002u8-ER; Fri, 26 Sep 2014 10:16:45 +0000 Date: Fri, 26 Sep 2014 03:16:45 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 07/11] xfs: xfs_bioerror can die. Message-ID: <20140926101645.GD22194@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 07/11] xfs: xfs_bioerror can die. References: <1411648461-29003-1-git-send-email-david@fromorbit.com> <1411648461-29003-8-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411648461-29003-8-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411726605 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9901 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS Looks good, Reviewed-by: Christoph Hellwig From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 05:18:11 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 3C0597FC4 for ; Fri, 26 Sep 2014 05:18:11 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 16BD5304062 for ; Fri, 26 Sep 2014 03:18:11 -0700 (PDT) X-ASG-Debug-ID: 1411726689-04bdf003a234bfe0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id W1QvxMeB92sbuNsc (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 03:18:10 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXSbJ-0003RP-U5; Fri, 26 Sep 2014 10:18:09 +0000 Date: Fri, 26 Sep 2014 03:18:09 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 08/11] xfs: kill xfs_bioerror_relse Message-ID: <20140926101809.GE22194@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 08/11] xfs: kill xfs_bioerror_relse References: <1411648461-29003-1-git-send-email-david@fromorbit.com> <1411648461-29003-9-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411648461-29003-9-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411726690 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9901 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS Looks good, Reviewed-by: Christoph Hellwig From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 05:21:50 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 693A28001 for ; Fri, 26 Sep 2014 05:21:50 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4712D304053 for ; Fri, 26 Sep 2014 03:21:50 -0700 (PDT) X-ASG-Debug-ID: 1411726908-04cb6c50e42e8070001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id K4bSL9vDALgjImOx (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 03:21:49 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXSeq-0006DL-Jy; Fri, 26 Sep 2014 10:21:48 +0000 Date: Fri, 26 Sep 2014 03:21:48 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 10/11] xfs: check xfs_buf_read_uncached returns correctly Message-ID: <20140926102148.GF22194@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 10/11] xfs: check xfs_buf_read_uncached returns correctly References: <1411648461-29003-1-git-send-email-david@fromorbit.com> <1411648461-29003-11-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411648461-29003-11-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411726909 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9901 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Thu, Sep 25, 2014 at 10:34:20PM +1000, Dave Chinner wrote: > From: Dave Chinner > > xfs_buf_read_uncached() has two failure modes. If can either return > NULL or bp->b_error != 0 depending on the type of failure, and not > all callers check for both. Fix it up. This changelog still seems to be for your previous version and needs an update now tha xfs_buf_read_uncached always returns the error directly. > - return NULL; > + return ENOMEM; Should be -ENOMEM these days, shouldn't it? > release_buf: > - xfs_buf_relse(bp); > + if (bp) > + xfs_buf_relse(bp); Shouldn't bp always be valid at this point? From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 05:22:08 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_FRT_FOLLOW2 autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2A0878001 for ; Fri, 26 Sep 2014 05:22:08 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 07CE98F8039 for ; Fri, 26 Sep 2014 03:22:08 -0700 (PDT) X-ASG-Debug-ID: 1411726926-04cbb073013cea10001-NocioJ Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) by cuda.sgi.com with ESMTP id BrWRAXoZ28N2LP2i (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 03:22:07 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXSf8-0006I4-SJ; Fri, 26 Sep 2014 10:22:06 +0000 Date: Fri, 26 Sep 2014 03:22:06 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 11/11] xfs: simplify xfs_zero_remaining_bytes Message-ID: <20140926102206.GG22194@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 11/11] xfs: simplify xfs_zero_remaining_bytes References: <1411648461-29003-1-git-send-email-david@fromorbit.com> <1411648461-29003-12-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411648461-29003-12-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: bombadil.infradead.org[198.137.202.9] X-Barracuda-Start-Time: 1411726927 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9902 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 25, 2014 at 10:34:21PM +1000, Dave Chinner wrote: > From: Christoph Hellwig > > xfs_zero_remaining_bytes() open codes a log of buffer manupulations > to do a read forllowed by a write. It can simply be replaced by an > uncached read followed by a xfs_bwrite() call. > > [Christoph, can I get your sign-off for this?] Sure, Signed-off-by: Christoph Hellwig From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 05:37:26 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 6FE238011 for ; Fri, 26 Sep 2014 05:37:26 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4D9088F8040 for ; Fri, 26 Sep 2014 03:37:26 -0700 (PDT) X-ASG-Debug-ID: 1411727844-04cbb073043cf020001-NocioJ Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) by cuda.sgi.com with ESMTP id CUEqX7e2qX48ZRn3 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 03:37:25 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXStw-0007r9-K4; Fri, 26 Sep 2014 10:37:24 +0000 Date: Fri, 26 Sep 2014 03:37:24 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 01/11] xfs: force the log before shutting down Message-ID: <20140926103724.GA24436@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 01/11] xfs: force the log before shutting down References: <1411648461-29003-1-git-send-email-david@fromorbit.com> <1411648461-29003-2-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411648461-29003-2-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: bombadil.infradead.org[198.137.202.9] X-Barracuda-Start-Time: 1411727845 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9902 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Sep 25, 2014 at 10:34:11PM +1000, Dave Chinner wrote: > From: Dave Chinner > > When we have marked the filesystem for shutdown, we want to prevent > any further buffer IO from being submitted. However, we currently > force the log after marking the filesystem as shut down, hence > allowing IO to the log *after* we have marked both the filesystem > and the log as in an error state. > > Clean this up by forcing the log before we mark the filesytem with > an error. This replaces the pure CIL flush that we currently have > which works around this same issue (i.e the CIL can't be flushed > once the shutdown flags are set) and hence enables us to clean up > the logic substantially. > > Signed-off-by: Dave Chinner Looks good, Reviewed-by: Christoph Hellwig A couple nitpicks: > diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c > index b1131fe..a598955 100644 > --- a/fs/xfs/xfs_log.c > +++ b/fs/xfs/xfs_log.c > @@ -3924,13 +3924,14 @@ xfs_log_force_umount( The top of the function comment speaks about the delaylog case, given that this is the only option now it might be worth to clean that up. > retval = 0; This assignment can be removed now that the xlog_state_ioerror call below is unconditional. From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 06:42:43 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C3BE57FEE for ; Fri, 26 Sep 2014 06:42:43 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id A347B8F8035 for ; Fri, 26 Sep 2014 04:42:40 -0700 (PDT) X-ASG-Debug-ID: 1411731759-04cb6c50e62ea250001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id OIxeoqsaAkSJ1Q40 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 04:42:39 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXTv4-0007z7-UD; Fri, 26 Sep 2014 11:42:38 +0000 Date: Fri, 26 Sep 2014 04:42:38 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/5] xfs: refactor xlog_recover_process_data() Message-ID: <20140926114238.GA16576@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 1/5] xfs: refactor xlog_recover_process_data() References: <1411697952-24741-1-git-send-email-david@fromorbit.com> <1411697952-24741-2-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411697952-24741-2-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411731759 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9903 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Fri, Sep 26, 2014 at 12:19:08PM +1000, Dave Chinner wrote: > From: Dave Chinner > > Clean up xlog_recover_process_data() structure in preparation for > fixing the allocation and freeing context of the transaction being > recovered. > > Signed-off-by: Dave Chinner Looks good. The only behavior change I could spot was that we now validate the length of an ophdr even when starting a new transaction, which seems sensible. Nipick: maybe the lp argument to xlog_recover_process_ophdr should be called end to make it more obvious? Reviewed-by: Christoph Hellwig From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 07:01:09 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CAADA29E02 for ; Fri, 26 Sep 2014 07:01:09 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 58EC7AC003 for ; Fri, 26 Sep 2014 05:01:06 -0700 (PDT) X-ASG-Debug-ID: 1411732864-04cb6c50e72ea9d0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id 7pL9FBMYUrcBTapf (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 05:01:05 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXUCu-0003kv-E2; Fri, 26 Sep 2014 12:01:04 +0000 Date: Fri, 26 Sep 2014 05:01:04 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/5] xfs: recovery of XLOG_UNMOUNT_TRANS leaks memory Message-ID: <20140926120104.GA10574@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 2/5] xfs: recovery of XLOG_UNMOUNT_TRANS leaks memory References: <1411697952-24741-1-git-send-email-david@fromorbit.com> <1411697952-24741-3-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411697952-24741-3-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411732864 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9904 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Fri, Sep 26, 2014 at 12:19:09PM +1000, Dave Chinner wrote: > From: Dave Chinner > > The XLOG_UNMOUNT_TRANS case skips the transaction, despite the fact > an unmount record is always in a standalone transaction. Hence > whenever we come across one of these we need to free the transaction > structure associated with it as there is no commit record that > follows it. > > Signed-off-by: Dave Chinner Looks good, Reviewed-by: Christoph Hellwig > @@ -3600,8 +3605,10 @@ xlog_recover_ophdr_to_trans( > * on this opheader is allocate a new recovery container to hold > * the recovery ops that will follow. > */ > - if (ohead->oh_flags & XLOG_START_TRANS) > + if (ohead->oh_flags & XLOG_START_TRANS) { > + ASSERT(be32_to_cpu(ohead->oh_len) == 0); > xlog_recover_new_tid(rhp, tid, be64_to_cpu(rhead->h_lsn)); > + } > return NULL; .. but I suspect this hunk fits better into the previous patch. Also shouldn't we handle any sort of on disk corruption more gracefully? From talonx@gmail.com Fri Sep 26 07:02:44 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE, T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 4ADF77FF6 for ; Fri, 26 Sep 2014 07:02:44 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id CC36FAC004 for ; Fri, 26 Sep 2014 05:02:43 -0700 (PDT) X-ASG-Debug-ID: 1411732962-04cbb073033d1d60001-NocioJ Received: from mail-ig0-f177.google.com (mail-ig0-f177.google.com [209.85.213.177]) by cuda.sgi.com with ESMTP id L5qOgypTuwvFJdII (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Fri, 26 Sep 2014 05:02:42 -0700 (PDT) X-Barracuda-Envelope-From: talonx@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.213.177 X-Barracuda-IPDD: Level1 [gmail.com/209.85.213.177] Received: by mail-ig0-f177.google.com with SMTP id h3so10124316igd.4 for ; Fri, 26 Sep 2014 05:02:42 -0700 (PDT) X-Barracuda-IPDD: Level1 [gmail.com/209.85.213.177] X-Barracuda-IPDD: Level1 [gmail.com/209.85.213.177] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=skFCW1dblq8q3Pvj7Bh8KGEBfseQ0Tyt0QPxhf/qLBk=; b=WRsS0eVln4IRaPZ6zUdjbKp181Z9jAHPkYnpzQr4dpDs/dXR/eUjr80b2GCuk67+fM cu1Mt3kekegID4CntrB6nMpvTjkAOTeJyR8lZJAyOKn3mtXMFr661cAIL9QyHPsZxT8X UjdNtQFUxvewr4w/P5Ya2UMhVTF5oByEcwaujTY0EQGVJSl+srNYy/V9i2+tBm2tfs46 2YyP3n+2CA5IC2LKgZvqMHFwcZ+OBwYPNEii5rlj5Ihnnknf0LOQczjROFo+8c75//tC qk0RrWWNqKtQ6GZxhdUsnIfP0xEBqoP4eXn7J+Dc37uFAjx1XmrLNPJvRvlkKY71PYjD 07RQ== X-Received: by 10.50.72.73 with SMTP id b9mr5314945igv.0.1411732962059; Fri, 26 Sep 2014 05:02:42 -0700 (PDT) MIME-Version: 1.0 Received: by 10.64.0.37 with HTTP; Fri, 26 Sep 2014 05:02:01 -0700 (PDT) In-Reply-To: <20140925071852.GE4758@dastard> References: <20140716124757.GC36312@bfoster.bfoster> <20140925071852.GE4758@dastard> From: Hrishikesh Barua Date: Fri, 26 Sep 2014 17:32:01 +0530 Message-ID: Subject: Re: Occassional problems with unfreeze To: Dave Chinner X-ASG-Orig-Subj: Re: Occassional problems with unfreeze Cc: Brian Foster , xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=047d7bdc1178b8af110503f6b1b3 X-Barracuda-Connect: mail-ig0-f177.google.com[209.85.213.177] X-Barracuda-Start-Time: 1411732962 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9904 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message --047d7bdc1178b8af110503f6b1b3 Content-Type: text/plain; charset=UTF-8 > Indeed, you are running an old kern (3.2.0-54) which means it won't > have this fix: > > 3948659 xfs: Account log unmount transaction correctly > > And that's likely to be the source of all your freeze/unfreeze > problems because it will eventually hang the log when it's leaked > all it's space in the ether.... > We did get a few pointers earlier that 3948659 might be the cause of the freeze/unfreeze problems but now that you have confirmed it we'll upgrade the kernel. Thanks. - Hrish --047d7bdc1178b8af110503f6b1b3 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable

=
Indeed, you are running an old kern (3.2.0-54) which means it won't
have this fix:

3948659 xfs: Account log unmount transaction correctly

And that's likely to be the source of all your freeze/unfreeze
problems because it will eventually hang the log when it's leaked
all it's space in the ether....

We did get a f= ew pointers earlier that 3948659 might be the cause of the freeze/unfreeze = problems but now that you have confirmed it we'll upgrade the kernel. T= hanks.

- Hrish
--047d7bdc1178b8af110503f6b1b3-- From tytso@thunk.org Fri Sep 26 07:03:52 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 1F0037FF9 for ; Fri, 26 Sep 2014 07:03:52 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id F2CA4304053 for ; Fri, 26 Sep 2014 05:03:48 -0700 (PDT) X-ASG-Debug-ID: 1411733026-04cb6c50e42eaaf0001-NocioJ Received: from imap.thunk.org (imap.thunk.org [74.207.234.97]) by cuda.sgi.com with ESMTP id iPIY87Wcw8F2KFfZ (version=TLSv1 cipher=AES128-SHA bits=128 verify=NO) for ; Fri, 26 Sep 2014 05:03:47 -0700 (PDT) X-Barracuda-Envelope-From: tytso@thunk.org X-Barracuda-Apparent-Source-IP: 74.207.234.97 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=thunk.org; s=ef5046eb; h=In-Reply-To:Content-Type:MIME-Version:References:Message-ID:Subject:Cc:To:From:Date; bh=d6UODWVTTwdo1B9PKkz9+eHdAWTjZvUzEllh6/HA3XA=; b=auNG7dqfwVZtTbNtSs/zuGgR4MVaOaO/vGXhpTxZTRlkYbWB7zzUu6Xc49ON8V+Tc6WW5M+R8ME88l8UnOmkqC/e6KYAGYqEuWy9h9ZdmPLzLVGj6eJ2N1jfatv4VIcDMONv7XAZ8hxDhVMIJMCuR60wQ4xmdQ8H7dRlFL/ZNH0=; Received: from root (helo=closure.thunk.org) by imap.thunk.org with local-esmtp (Exim 4.80) (envelope-from ) id 1XXUDJ-0001dA-IX; Fri, 26 Sep 2014 12:01:29 +0000 Received: by closure.thunk.org (Postfix, from userid 15806) id B153A58028B; Fri, 26 Sep 2014 08:01:28 -0400 (EDT) Date: Fri, 26 Sep 2014 08:01:28 -0400 From: Theodore Ts'o To: Dave Chinner Cc: Jan Kara , Christoph Hellwig , adilger@dilger.ca, linux-api@vger.kernel.org, xfs@oss.sgi.com, dmonakhov@openvz.org, viro@zeniv.linux.org.uk, Li Xi , linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org Subject: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project Message-ID: <20140926120128.GA21376@thunk.org> X-ASG-Orig-Subj: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project References: <1411567470-31799-1-git-send-email-lixi@ddn.com> <1411567470-31799-5-git-send-email-lixi@ddn.com> <20140924162507.GC27000@quack.suse.cz> <20140924162634.GA16886@infradead.org> <20140924170105.GE27000@quack.suse.cz> <20140925075912.GG4758@dastard> <20140925135213.GB15352@quack.suse.cz> <20140925224225.GJ4945@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140925224225.GJ4945@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: tytso@thunk.org X-SA-Exim-Scanned: No (on imap.thunk.org); SAEximRunCond expanded to false X-Barracuda-Connect: imap.thunk.org[74.207.234.97] X-Barracuda-Start-Time: 1411733027 X-Barracuda-Encrypted: AES128-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9904 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Fri, Sep 26, 2014 at 08:42:25AM +1000, Dave Chinner wrote: > Look, I have no problems with extending the existing quota > interfaces to support project quotas, but that should be a > *secondary* improvement as userspace tools are updated. The > primary goal needs to be "works identically to XFS" and so it needs > to implement the interfaces that are currently used for management > so that we can actually test that it does work identically. I think we're getting a bit too hung up on which is the "primary" and which is the "secondary" interfaces. The reality is that we should make both interfaces work. An example of this is how we handle the xfs-specific ioctls that are also exposed via the fallocate(2) system call. It's not particularly important to me which is the "primary" interface just because it's been around for 10 years. Which should implement *both* so that users are used to using xfs_io(8) or fallocate(1) can do what they want. Similarly, if some users are more used to the quotatools interface (which has been around for quite a long time, BTW, if we're trying to count primacy by years of availability to Linux users), and some users that are used to using xfs_quota, both should work. Cheers, - Ted From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 07:06:11 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 3F2577FFB for ; Fri, 26 Sep 2014 07:06:11 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 0DB65304059 for ; Fri, 26 Sep 2014 05:06:10 -0700 (PDT) X-ASG-Debug-ID: 1411733169-04bdf0039f34f2f0001-NocioJ Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) by cuda.sgi.com with ESMTP id ntZShAyZXtULi2Gt (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 05:06:09 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXUHc-0006ke-0w; Fri, 26 Sep 2014 12:05:56 +0000 Date: Fri, 26 Sep 2014 05:05:56 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 4/5] xfs: reorganise transaction recovery item code Message-ID: <20140926120556.GC10574@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 4/5] xfs: reorganise transaction recovery item code References: <1411697952-24741-1-git-send-email-david@fromorbit.com> <1411697952-24741-5-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411697952-24741-5-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: bombadil.infradead.org[198.137.202.9] X-Barracuda-Start-Time: 1411733169 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9904 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 26, 2014 at 12:19:11PM +1000, Dave Chinner wrote: > From: Dave Chinner > > The code for managing transactions anf the items for recovery is > spread across 3 different locations in the file. Move them all > together so that it is easy to read the code without needing to jump > long distances in the file. > > Signed-off-by: Dave Chinner Looks good, Reviewed-by: Christoph Hellwig From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 07:08:36 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 8F5938012 for ; Fri, 26 Sep 2014 07:08:36 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 26308AC004 for ; Fri, 26 Sep 2014 05:08:36 -0700 (PDT) X-ASG-Debug-ID: 1411733314-04cbb073023d1fc0001-NocioJ Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) by cuda.sgi.com with ESMTP id AT0tBNg39JAPY5jb (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 05:08:34 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXUKA-000852-4v; Fri, 26 Sep 2014 12:08:34 +0000 Date: Fri, 26 Sep 2014 05:08:34 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 5/5] xfs: refactor recovery transaction start handling Message-ID: <20140926120834.GD10574@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 5/5] xfs: refactor recovery transaction start handling References: <1411697952-24741-1-git-send-email-david@fromorbit.com> <1411697952-24741-6-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411697952-24741-6-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: bombadil.infradead.org[198.137.202.9] X-Barracuda-Start-Time: 1411733314 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9904 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 26, 2014 at 12:19:12PM +1000, Dave Chinner wrote: > From: Dave Chinner > > Rework the transaction lookup and allocation code in > xlog_recovery_process_ophdr() to remove fold two related call-once s/remove // > helper functions into a single helper. Then fold in all > XLOG_START_TRANS logic to that helper to clean up the remaining > logic in xlog_recovery_process_ophdr(). > > Signed-off-by: Dave Chinner Looks good, Reviewed-by: Christoph Hellwig From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 07:33:41 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 2AC497FAF for ; Fri, 26 Sep 2014 07:33:41 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1634F304039 for ; Fri, 26 Sep 2014 05:33:41 -0700 (PDT) X-ASG-Debug-ID: 1411734819-04cbb073023d2cf0001-NocioJ Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) by cuda.sgi.com with ESMTP id CJpQOQ1vEBB8Gg4f (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 05:33:39 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXUiQ-000546-N4; Fri, 26 Sep 2014 12:33:38 +0000 Date: Fri, 26 Sep 2014 05:33:38 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 09/11] xfs: introduce xfs_buf_submit[_wait] Message-ID: <20140926123338.GA18558@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 09/11] xfs: introduce xfs_buf_submit[_wait] References: <1411648461-29003-1-git-send-email-david@fromorbit.com> <1411648461-29003-10-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411648461-29003-10-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: bombadil.infradead.org[198.137.202.9] X-Barracuda-Start-Time: 1411734819 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9905 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Looks good, although I still think this would benefit from a helper like the one below (patch lightly tested). Reviewed-by: Christoph Hellwig diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 0ac54a0..081ccf3 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1287,28 +1287,18 @@ _xfs_buf_ioapply( blk_finish_plug(&plug); } -/* - * Asynchronous IO submission path. This transfers the buffer lock ownership and - * the current reference to the IO. It is not safe to reference the buffer after - * a call to this function unless the caller holds an additional reference - * itself. - */ -void -xfs_buf_submit( +static int +__xfs_buf_submit( struct xfs_buf *bp) { - trace_xfs_buf_submit(bp, _RET_IP_); - ASSERT(!(bp->b_flags & _XBF_DELWRI_Q)); - ASSERT(bp->b_flags & XBF_ASYNC); /* on shutdown we stale and complete the buffer immediately */ if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { xfs_buf_ioerror(bp, -EIO); bp->b_flags &= ~XBF_DONE; xfs_buf_stale(bp); - xfs_buf_ioend(bp); - return; + return -EIO; } if (bp->b_flags & XBF_WRITE) @@ -1318,12 +1308,8 @@ xfs_buf_submit( bp->b_io_error = 0; /* - * The caller's reference is released during I/O completion. - * This occurs some time after the last b_io_remaining reference is - * released, so after we drop our Io reference we have to have some - * other reference to ensure the buffer doesn't go away from underneath - * us. Take a direct reference to ensure we have safe access to the - * buffer until we are finished with it. + * Take a reference to ensure we have safe access to the buffer until + * we are finished with it. */ xfs_buf_hold(bp); @@ -1341,64 +1327,56 @@ xfs_buf_submit( * that we don't return to the caller with completion still pending. */ if (atomic_dec_and_test(&bp->b_io_remaining) == 1) { - if (bp->b_error) - xfs_buf_ioend(bp); - else + if ((bp->b_flags & XBF_ASYNC) && !bp->b_error) xfs_buf_ioend_async(bp); + else + xfs_buf_ioend(bp); } - xfs_buf_rele(bp); - /* Note: it is not safe to reference bp now we've dropped our ref */ + return 0; } /* - * Synchronous buffer IO submission path, read or write. + * Asynchronous IO submission path. This transfers the buffer lock ownership and + * the current reference to the IO. It is not safe to reference the buffer after + * a call to this function unless the caller holds an additional reference + * itself. */ -int -xfs_buf_submit_wait( +void +xfs_buf_submit( struct xfs_buf *bp) { int error; - trace_xfs_buf_submit_wait(bp, _RET_IP_); + trace_xfs_buf_submit(bp, _RET_IP_); - ASSERT(!(bp->b_flags & (_XBF_DELWRI_Q | XBF_ASYNC))); + ASSERT(bp->b_flags & XBF_ASYNC); - if (XFS_FORCED_SHUTDOWN(bp->b_target->bt_mount)) { - xfs_buf_ioerror(bp, -EIO); - xfs_buf_stale(bp); - bp->b_flags &= ~XBF_DONE; - return -EIO; - } + error = __xfs_buf_submit(bp); + if (error) + xfs_buf_ioend(bp); + else + xfs_buf_rele(bp); - if (bp->b_flags & XBF_WRITE) - xfs_buf_wait_unpin(bp); + /* Note: it is not safe to reference bp now we've dropped our ref */ +} - /* clear the internal error state to avoid spurious errors */ - bp->b_io_error = 0; +/* + * Synchronous buffer IO submission path, read or write. + */ +int +xfs_buf_submit_wait( + struct xfs_buf *bp) +{ + int error; - /* - * For synchronous IO, the IO does not inherit the submitters reference - * count, nor the buffer lock. Hence we cannot release the reference we - * are about to take until we've waited for all IO completion to occur, - * including any xfs_buf_ioend_async() work that may be pending. - */ - xfs_buf_hold(bp); + trace_xfs_buf_submit_wait(bp, _RET_IP_); - /* - * Set the count to 1 initially, this will stop an I/O completion - * callout which happens before we have started all the I/O from calling - * xfs_buf_ioend too early. - */ - atomic_set(&bp->b_io_remaining, 1); - _xfs_buf_ioapply(bp); + ASSERT(!(bp->b_flags & XBF_ASYNC)); - /* - * make sure we run completion synchronously if it raced with us and is - * already complete. - */ - if (atomic_dec_and_test(&bp->b_io_remaining) == 1) - xfs_buf_ioend(bp); + error = __xfs_buf_submit(bp); + if (error) + return error; /* wait for completion before gathering the error from the buffer */ trace_xfs_buf_iowait(bp, _RET_IP_); From olaf@sgi.com Fri Sep 26 09:06:28 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D82CC7FBC for ; Fri, 26 Sep 2014 09:06:28 -0500 (CDT) Received: from xmail.sgi.com (pv-excas3-dc21.corp.sgi.com [137.38.106.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id AD3FE8F8037; Fri, 26 Sep 2014 07:06:25 -0700 (PDT) Received: from [144.253.208.63] (144.253.208.63) by xmail.sgi.com (137.38.106.6) with Microsoft SMTP Server (TLS) id 14.3.195.1; Fri, 26 Sep 2014 09:06:25 -0500 Message-ID: <542572DE.6070106@sgi.com> Date: Fri, 26 Sep 2014 16:06:22 +0200 From: Olaf Weber Organization: SGI User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.2 MIME-Version: 1.0 To: Andi Kleen CC: Ben Myers , , , Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <87lhpbhfgg.fsf@tassilo.jf.intel.com> <20140922184145.GH4482@sgi.com> <20140922192958.GJ4120@two.firstfloor.org> <54219C17.3090104@sgi.com> <20140923201540.GB15923@two.firstfloor.org> <5422A5F8.5040703@sgi.com> In-Reply-To: <5422A5F8.5040703@sgi.com> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [144.253.208.63] On 24-09-14 13:07, Olaf Weber wrote: > On 23-09-14 22:15, Andi Kleen wrote: > >>> A big part of the table does decompositions for Korean: eliminating >>> the Hangul decompositions removes 156320 bytes, leaving 89936 bytes. >> >> Are there regular ranges or other redundancies in the Korean encoding >> that could be used to compress paths? > > Yes, though at the expense of more complicated code and interfaces. in > particular, lookups that want a normalized string would need to provide a > 10-byte buffer to store it in. I spent some time working on this, and the effect on the lookup code isn't as bad as I'd thought. The updated code should be posted early next week. With this change, the table size for the full trie becomes 89952 bytes. Of this, 66400 bytes are spent on the NFKD + Ignorables, an additional 20992 bytes on NFDK + Ignorables + Case Fold. The remainder, 2560 bytes, are additional info for older unicode versions. Note that the NFDK + Ignorables + Case Fold trie forwards to the NFKD + Ignorables where they overlap. A stand-alone version would be 71750 bytes. As noted before these tables also contain the Canonical Combining Class and unicode version information for the code points. The latter allows for supporting multiple unicode versions using a single combined table. Olaf -- Olaf Weber SGI Phone: +31(0)30-6696796 Veldzigt 2b Fax: +31(0)30-6696799 Technical Lead 3454 PW de Meern Vnet: 955-6796 Storage Software The Netherlands Email: olaf@sgi.com From olaf@sgi.com Fri Sep 26 09:50:46 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 306B08018 for ; Fri, 26 Sep 2014 09:50:46 -0500 (CDT) Received: from xmail.sgi.com (pv-excas3-dc21.corp.sgi.com [137.38.106.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id DF6BD304048; Fri, 26 Sep 2014 07:50:42 -0700 (PDT) Received: from [144.253.208.63] (144.253.208.63) by xmail.sgi.com (137.38.106.6) with Microsoft SMTP Server (TLS) id 14.3.195.1; Fri, 26 Sep 2014 09:50:42 -0500 Message-ID: <54257D3F.70302@sgi.com> Date: Fri, 26 Sep 2014 16:50:39 +0200 From: Olaf Weber Organization: SGI User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.2 MIME-Version: 1.0 To: Dave Chinner CC: Ben Myers , , , Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <20140922222611.GZ4322@dastard> <5422C540.1060007@sgi.com> <20140924231024.GA4758@dastard> In-Reply-To: <20140924231024.GA4758@dastard> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [144.253.208.63] On 25-09-14 01:10, Dave Chinner wrote: > On Wed, Sep 24, 2014 at 03:21:04PM +0200, Olaf Weber wrote: >> On 23-09-14 00:26, Dave Chinner wrote: >>> On Thu, Sep 18, 2014 at 02:56:50PM -0500, Ben Myers wrote: >> >> [...] >> >>>> TODO: Store the unicode version number of the filesystem on disk in the >>>> super block. >>> >>> So, if the filesystem has to store the specific unicode version it >>> was created with so that we know what version to put in trie >>> lookups, again I'll ask: why are we loading the trie as a generic >>> kernel module and not as metadata in the filesystem that is demand >>> paged and cached? >> >> This way the trie can be shared, and the code using it is not >> entangled with the XFS code. > > The trie parsing code can still be common - just the location and > contents of the data is determined by the end-user. I'm not sure how common the parsing code can be if needs to be capable of retrieving data from a filesystem. Note given your and Andi Kleen's feedback on the trie size I've switched to doing algorithmic decomposition for Hangul. This reduces the size of the trie to 89952 bytes. In addition, if you store the trie in the filesystem, then the only part that needs storing is the version for that particular filesystem, e.g no compatibility info for different unicode versions would be required. This would reduce the trie size to about 50kB for case-sensitive filesystems, and about 55kB on case-folding filesystems. [...] >>> [...] Why should we let filesystems say "we fully >>> understand and support utf8" and then allow them to accept and >>> propagate invalid utf8 sequences and leave everyone else to have to >>> clean up the mess? >> >> Because the alternative amounts in my opinion to a demand that every >> bit of userspace that may be involved in generating filenames >> generate only clean UTF-8. I do not believe that this is a realistic >> demand at this point in time. > > It's a chicken and egg situation. I'd much prefer we enforce clean > utf8 from the start, because if we don't we'll never be able to do > that. And other filesystems (e.g. ZFS) allow you to do reject > anything that is not clean utf8.... As I understand it, this is optional in ZFS. I wonder what people's experiences are with this. [...] >>> Yet normalised strings are only stable and hence comparable >>> if there are no unassigned code points in them. What happens when >>> userspace is not using the same version of unicode as the >>> filesystem and is using newer code points in it's strings? >>> Normalisation fails, right? >> >> For the newer code points, yes. This is not treated as a failure to >> normalize the string as a whole, as there are clear guidelines in >> unicode on how unassigned code points interact with normalization: >> they have canonical combining class 0 and no decomposition. > > And so effectively are not stable. Which is something we absolutely > have to avoid for information stored on disk. i.e. you're using the > normalised form to build the hash values in the lookup index in the > directory structure, and so having unstable normalisation forms is > just wrong. Hence we'd need to reject anything with unassigned code > points.... On a particular filesystem, the calculated normalization would be stable. >>> And as an extension of using normalisation for case-folded >>> comparisons, how do we make case folding work with blobs that can't >>> be normalised? It seems to me that this just leads to the nasty >>> situation where some filenames are case sensitive and some aren't >>> based on what the filesystem thinks is valid utf-8. The worst part >>> is that userspace has no idea that the filesystem is making such >>> distinctions and so behaviour is not at all predictable or expected. >> >> Making case-folding work on a blob that cannot be normalized is (in >> my opinion) akin to doing an ASCII-based casefold on a Shift-JIS >> string: the result is neither pretty nor useful. > > Yes, that's exactly my point. But apparently we draw different conclusions from it. >>> This is another point in favour of rejecting invalid utf-8 strings >>> and for keeping the translation tables stable within the >>> filesystem... >> >> Bear in mind that this means not just rejecting invalid UTF-8 >> strings, but also rejecting valid UTF-8 strings that encode >> unassigned code points. > > And that's precisely what I'm suggesting: If we can't normalise the > filename to a stable form then it cannot be used for hashing or case > folding. That means it needs to be rejected, not treated as an > opaque blob. > > The moment we start parsing filenames they are no longer opaque > blobs and so all existing "filename are opaque blobs" handling rules > go out the window. They are now either valid so we can use them, or > they are invalid and need to be rejected to avoid unpredictable > and/or undesirable behaviour. At this point I'd really like other people to weigh in on this and get a sense of how sentiment is spread on the question. - Forbid non-UTF-8 filenames - Allow non-UTF-8 filenames - Make it a mount option - Make it a mkfs option [...] >>>> The most contentious part is (should be) ignoring the codepoints with >>>> the Default_Ignorable_Code_Point property. I've included the list >>>> below. My argument, such as it is, is that these code points either >>>> have no visible rendering, or in cases like the soft hyphen, are only >>>> conditionally visible. The problem with these (as I see it) is that on >>>> seeing a filename that might contain them you cannot tell whether they >>>> are present. So I propose to ignore them for the purpose of comparing >>>> filenames for equality. >>> >>> Which introduces a non-standard "visibility criterial" for >>> determining what should be or shouldn't be part of the normalised >>> string for comparison. I don't see any real justification for >>> stepping outside the standard unicode normalisation here - just >>> because the user cannot see a character in a specific context does >>> not mean that it is not significant to the application that created >>> it. >> >> I agree these characters may be significant to the application. I'm >> just not convinced that they should be significant in a file name. > > They are significant to the case folding result, right? And > therefore would be significant in a filename... Case Folding doesn't affect the ignorables, so in that sense at least they're not significant to the case folding result, even if you do not ignore them. [...] > Hence my comments about NLS integration. The NLS subsystem already > has utf8 support with language dependent case folding tables. All the > current filesystems that deal with unicode (including case folding) > use the NLS subsystem for conversions. Looking at the NLS subsystem I see support for translating a number of different encodings ("code pages") to unicode and back. There is support for uppercase/lowercase translation for a number of those encodings. Which is not the same as language dependent case folding. As for a unicode case fold, I see no support at all. In nls_utf8.c the uppercase/lowercase mappings are set to the identity maps. I see no support for unicode normalization forms either. > Hmmm - looking at all the NLS code that does different utf format > conversions first: what happens if an application is using UTF16 or > UTF32 for it's filename encoding rather than utf8? Since UTF-16 and UTF-32 strings contain embedded 0 bytes, those encodings cannot be used to pass a filename across the kernel/userspace interface. >>>> * XFS-specific design notes. >>> ... >>>> If the borgbit (the bit enabling legacy ASCII-based CI in XFS) is set >>>> in the superblock, then case folding is added into the mix. This is >>>> the nfkdicf normalization form mentioned above. It allows for the >>>> creation of case-insensitive filesystems with UTF-8 support. >>> >>> Please don't overload existing superblock feature bits with multiple >>> meanings. ASCII-CI is a stand-alone feature and is not in any way >>> compatible with Unicode: Unicode-CI is a superset of Unicode >>> support. So it really needs two new feature bits for Unicode and >>> Unicode-CI, not just one for unicode. >> >> It seemed an obvious extension of the meaning of that bit. > > Feature bits refer to a specific on disk format feature. If that bit > is set, then that feature is present. In this case, it means the > filesystem is using ascii-ci. If that bit is passed out to > userspace via the geometry ioctl, then *existing applications* > expect it to mean ascii-ci behaviour from the filesystem. If an > existing utility reads the flag field from disk (e.g. repair, > metadump, db, etc) they all expect it to mean ascii-ci, and will do > stuff based on that specific meaning. We cannot redefine the meaning > of a feature bit after the fact - we have lots of feature bits so > there's no need to overload an existing one for this. Good point. > Hmmm - another interesting question just popped into my head about > metadump: file name obfuscation. What does unicode and utf8 mean > for the hash collision calculation algorithm? Good question. Olaf -- Olaf Weber SGI Phone: +31(0)30-6696796 Veldzigt 2b Fax: +31(0)30-6696799 Technical Lead 3454 PW de Meern Vnet: 955-6796 Storage Software The Netherlands Email: olaf@sgi.com From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 11:56:08 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id BA6867FB3 for ; Fri, 26 Sep 2014 11:56:08 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 95E878F8049 for ; Fri, 26 Sep 2014 09:56:08 -0700 (PDT) X-ASG-Debug-ID: 1411750566-04cbb073033de640001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id lwFzjDljgHXZo75U (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO); Fri, 26 Sep 2014 09:56:06 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXYoP-0001Ki-O9; Fri, 26 Sep 2014 16:56:05 +0000 Date: Fri, 26 Sep 2014 09:56:05 -0700 From: Christoph Hellwig To: Olaf Weber Cc: Dave Chinner , Ben Myers , linux-fsdevel@vger.kernel.org, tinguely@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140926165605.GA25274@infradead.org> X-ASG-Orig-Subj: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <20140922222611.GZ4322@dastard> <5422C540.1060007@sgi.com> <20140924231024.GA4758@dastard> <54257D3F.70302@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <54257D3F.70302@sgi.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411750566 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9912 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Fri, Sep 26, 2014 at 04:50:39PM +0200, Olaf Weber wrote: > I'm not sure how common the parsing code can be if needs to be capable of > retrieving data from a filesystem. > > Note given your and Andi Kleen's feedback on the trie size I've switched to > doing algorithmic decomposition for Hangul. This reduces the size of the > trie to 89952 bytes. > > In addition, if you store the trie in the filesystem, then the only part > that needs storing is the version for that particular filesystem, e.g no > compatibility info for different unicode versions would be required. This > would reduce the trie size to about 50kB for case-sensitive filesystems, and > about 55kB on case-folding filesystems. Honestly I wouldn't worry about demand loading it too much. This is a fairly special case code for NAS servers, and should not affect normal uses now that we use symbol_get. Let's get back to the fundamentals. > >It's a chicken and egg situation. I'd much prefer we enforce clean > >utf8 from the start, because if we don't we'll never be able to do > >that. And other filesystems (e.g. ZFS) allow you to do reject > >anything that is not clean utf8.... > > As I understand it, this is optional in ZFS. I wonder what people's > experiences are with this. It is as optional as your utf8 support for XFS is. But they do enforce valid utf8 if they use utf8 normalization for file name comparisms, be that case sensitive or insensitive. Take a look at the zfs(8) man page. > - Forbid non-UTF-8 filenames > - Allow non-UTF-8 filenames > - Make it a mount option > - Make it a mkfs option My take on this is: - I think we'll have to prevent non-utf8 file names for any cases where we use utf8 normalization. If you do not use utf8 normalization it's plain old Unix everything is allowed. - I think utf8 normalization vs not should be mkfs option, to make sure everyone including kernel and repair knows what sort of filesystem deal with. - case insensitive matching for utf8 normalized filesystems should be a runtime decision. mount time for now, but Samba people would be extremly happy to allow per-operation or per-process CI matching. But that is another totally different discusion I'd like to keep separate, I just want to make sure the disk format allows for it for now. From jra@samba.org Fri Sep 26 12:04:15 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 011B87F56 for ; Fri, 26 Sep 2014 12:04:15 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id E447E8F8040 for ; Fri, 26 Sep 2014 10:04:11 -0700 (PDT) X-ASG-Debug-ID: 1411751049-04cb6c50e62f8170001-NocioJ Received: from mail.samba.org (fn.samba.org [216.83.154.106]) by cuda.sgi.com with ESMTP id GG9OBJeEH9eoH7l8 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 10:04:10 -0700 (PDT) X-Barracuda-Envelope-From: jra@samba.org X-Barracuda-Apparent-Source-IP: 216.83.154.106 Received: from mail.samba.org (localhost [127.0.0.1]) by mail.samba.org (Postfix) with ESMTP id 9793FACF0B; Fri, 26 Sep 2014 11:04:09 -0600 (MDT) Received: by mail.samba.org (Postfix, from userid 549) id 8E223ACF30; Fri, 26 Sep 2014 11:04:09 -0600 (MDT) Date: Fri, 26 Sep 2014 10:04:07 -0700 From: Jeremy Allison To: Christoph Hellwig Cc: Olaf Weber , Dave Chinner , Ben Myers , linux-fsdevel@vger.kernel.org, tinguely@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140926170407.GB6012@samba2> X-ASG-Orig-Subj: Re: [RFC v2] Unicode/UTF-8 support for XFS Reply-To: Jeremy Allison References: <20140918195650.GI19952@sgi.com> <20140922222611.GZ4322@dastard> <5422C540.1060007@sgi.com> <20140924231024.GA4758@dastard> <54257D3F.70302@sgi.com> <20140926165605.GA25274@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140926165605.GA25274@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: fn.samba.org[216.83.154.106] X-Barracuda-Start-Time: 1411751050 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9912 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 26, 2014 at 09:56:05AM -0700, Christoph Hellwig wrote: > > My take on this is: > > - I think we'll have to prevent non-utf8 file names for any cases where > we use utf8 normalization. If you do not use utf8 normalization > it's plain old Unix everything is allowed. > > - I think utf8 normalization vs not should be mkfs option, to make sure > everyone including kernel and repair knows what sort of filesystem > deal with. > > - case insensitive matching for utf8 normalized filesystems should be > a runtime decision. mount time for now, but Samba people would be > extremly happy to allow per-operation or per-process CI matching. > But that is another totally different discusion I'd like to keep > separate, I just want to make sure the disk format allows for it for > now. Actually, I'm so eager for case-insensitive matching I'd take "at format time", as with ZFS :-) :-). Having CI matching can speed up Samba operations by a factor of 10 on large directories (warning, number made up, depending on the number of entries per dir :-). Jeremy. From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 12:06:09 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A99E47FE2 for ; Fri, 26 Sep 2014 12:06:09 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 47D10AC001 for ; Fri, 26 Sep 2014 10:06:06 -0700 (PDT) X-ASG-Debug-ID: 1411751165-04bdf0039f35c010001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id ulubtvfW8RX3Ecwn (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO); Fri, 26 Sep 2014 10:06:05 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXYy4-00070T-Tu; Fri, 26 Sep 2014 17:06:04 +0000 Date: Fri, 26 Sep 2014 10:06:04 -0700 From: Christoph Hellwig To: Jeremy Allison Cc: Olaf Weber , Dave Chinner , Ben Myers , linux-fsdevel@vger.kernel.org, tinguely@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140926170604.GA21287@infradead.org> X-ASG-Orig-Subj: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <20140922222611.GZ4322@dastard> <5422C540.1060007@sgi.com> <20140924231024.GA4758@dastard> <54257D3F.70302@sgi.com> <20140926165605.GA25274@infradead.org> <20140926170407.GB6012@samba2> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140926170407.GB6012@samba2> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411751165 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9912 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Fri, Sep 26, 2014 at 10:04:07AM -0700, Jeremy Allison wrote: > Actually, I'm so eager for case-insensitive matching I'd > take "at format time", as with ZFS :-) :-). You already get this with XFS as long as you limit yourself to 7-bit ASCII :) And utf-8 with Olaf's patches as-is. Maybe time to give them some testing? From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 12:09:44 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id CA4A27FEF for ; Fri, 26 Sep 2014 12:09:44 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 994F18F8050 for ; Fri, 26 Sep 2014 10:09:44 -0700 (PDT) X-ASG-Debug-ID: 1411751383-04bdf003a235c300001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id SRupiNM6JYHK1Yom (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO); Fri, 26 Sep 2014 10:09:43 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXZ1b-0007qg-GZ; Fri, 26 Sep 2014 17:09:43 +0000 Date: Fri, 26 Sep 2014 10:09:43 -0700 From: Christoph Hellwig To: Dave Chinner Cc: Ben Myers , linux-fsdevel@vger.kernel.org, tinguely@sgi.com, olaf@sgi.com, xfs@oss.sgi.com Subject: Re: [PATCH 06/10] xfs: add unicode character database files Message-ID: <20140926170943.GA28044@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 06/10] xfs: add unicode character database files References: <20140918195650.GI19952@sgi.com> <20140918201440.GI4482@sgi.com> <20140922205438.GM4267@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140922205438.GM4267@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411751383 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9912 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Tue, Sep 23, 2014 at 06:54:38AM +1000, Dave Chinner wrote: > This probably needs to live somewhere under lib/. There's nothing > XFS specific in it and the translations should be the same for > anything that wants to parse unicode. Agreed. From BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org Fri Sep 26 12:10:15 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id C15687FEF for ; Fri, 26 Sep 2014 12:10:15 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id B0430304053 for ; Fri, 26 Sep 2014 10:10:15 -0700 (PDT) X-ASG-Debug-ID: 1411751410-04cb6c50e72f8650001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id DKote9dUJIIWfr5c (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO); Fri, 26 Sep 2014 10:10:11 -0700 (PDT) X-Barracuda-Envelope-From: BATV+e511363bc4c2fd8a5f74+4051+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XXZ22-0000oT-Qh; Fri, 26 Sep 2014 17:10:10 +0000 Date: Fri, 26 Sep 2014 10:10:10 -0700 From: Christoph Hellwig To: Ben Myers Cc: Dave Chinner , linux-fsdevel@vger.kernel.org, tinguely@sgi.com, olaf@sgi.com, xfs@oss.sgi.com Subject: Re: [PATCH 07/10] xfs: add trie generator and supporting code for UTF-8. Message-ID: <20140926171010.GB28044@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 07/10] xfs: add trie generator and supporting code for UTF-8. References: <20140918195650.GI19952@sgi.com> <20140918201518.GJ4482@sgi.com> <20140922205714.GN4267@dastard> <20140923185721.GV19952@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140923185721.GV19952@sgi.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411751411 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9912 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Tue, Sep 23, 2014 at 01:57:21PM -0500, Ben Myers wrote: > I'll get this moved to lib/ as you suggested elsewhere in the > thread. Given that this is a host side tool it should be under scripts/ From jra@samba.org Fri Sep 26 12:13:40 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BB7737FF3 for ; Fri, 26 Sep 2014 12:13:40 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5532FAC004 for ; Fri, 26 Sep 2014 10:13:40 -0700 (PDT) X-ASG-Debug-ID: 1411751618-04cb6c50e52f8830001-NocioJ Received: from mail.samba.org (fn.samba.org [216.83.154.106]) by cuda.sgi.com with ESMTP id WLghTvkb8MWkV7ku (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 10:13:39 -0700 (PDT) X-Barracuda-Envelope-From: jra@samba.org X-Barracuda-Apparent-Source-IP: 216.83.154.106 Received: from mail.samba.org (localhost [127.0.0.1]) by mail.samba.org (Postfix) with ESMTP id 9C737ACEFB; Fri, 26 Sep 2014 11:13:38 -0600 (MDT) Received: by mail.samba.org (Postfix, from userid 549) id 929DAACF0B; Fri, 26 Sep 2014 11:13:38 -0600 (MDT) Date: Fri, 26 Sep 2014 10:13:36 -0700 From: Jeremy Allison To: Christoph Hellwig Cc: Jeremy Allison , Olaf Weber , Dave Chinner , Ben Myers , linux-fsdevel@vger.kernel.org, tinguely@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140926171336.GC6012@samba2> X-ASG-Orig-Subj: Re: [RFC v2] Unicode/UTF-8 support for XFS Reply-To: Jeremy Allison References: <20140918195650.GI19952@sgi.com> <20140922222611.GZ4322@dastard> <5422C540.1060007@sgi.com> <20140924231024.GA4758@dastard> <54257D3F.70302@sgi.com> <20140926165605.GA25274@infradead.org> <20140926170407.GB6012@samba2> <20140926170604.GA21287@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140926170604.GA21287@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: fn.samba.org[216.83.154.106] X-Barracuda-Start-Time: 1411751619 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9912 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 26, 2014 at 10:06:04AM -0700, Christoph Hellwig wrote: > On Fri, Sep 26, 2014 at 10:04:07AM -0700, Jeremy Allison wrote: > > Actually, I'm so eager for case-insensitive matching I'd > > take "at format time", as with ZFS :-) :-). > > You already get this with XFS as long as you limit yourself to > 7-bit ASCII :) Thankyou for playing, here's a $10 gift token... No, that won't do I'm afraid :-). > And utf-8 with Olaf's patches as-is. > > Maybe time to give them some testing? I might do that, once I've finished rebuilding my home server (remember kids, RAID5 is *NOT* a backup :-) :-). From bpm@sgi.com Fri Sep 26 12:30:15 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 5D3017F52 for ; Fri, 26 Sep 2014 12:30:15 -0500 (CDT) Received: from whiskey.americas.sgi.com (whiskey.americas.sgi.com [128.162.233.19]) by relay1.corp.sgi.com (Postfix) with ESMTP id 32FE98F8037; Fri, 26 Sep 2014 10:30:14 -0700 (PDT) Received: by whiskey.americas.sgi.com (Postfix, from userid 4600) id 7DC254266DC; Fri, 26 Sep 2014 12:30:14 -0500 (CDT) Date: Fri, 26 Sep 2014 12:30:14 -0500 From: Ben Myers To: Christoph Hellwig Cc: Olaf Weber , Dave Chinner , linux-fsdevel@vger.kernel.org, tinguely@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140926173014.GK19952@sgi.com> References: <20140918195650.GI19952@sgi.com> <20140922222611.GZ4322@dastard> <5422C540.1060007@sgi.com> <20140924231024.GA4758@dastard> <54257D3F.70302@sgi.com> <20140926165605.GA25274@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140926165605.GA25274@infradead.org> User-Agent: Mutt/1.5.20 (2009-06-14) Hey Christoph, On Fri, Sep 26, 2014 at 09:56:05AM -0700, Christoph Hellwig wrote: > On Fri, Sep 26, 2014 at 04:50:39PM +0200, Olaf Weber wrote: > > >It's a chicken and egg situation. I'd much prefer we enforce clean > > >utf8 from the start, because if we don't we'll never be able to do > > >that. And other filesystems (e.g. ZFS) allow you to do reject > > >anything that is not clean utf8.... > > > > As I understand it, this is optional in ZFS. I wonder what people's > > experiences are with this. > > It is as optional as your utf8 support for XFS is. But they do > enforce valid utf8 if they use utf8 normalization for file name > comparisms, be that case sensitive or insensitive. Take a look at the > zfs(8) man page. The way I'm reading that man page, it seems like with ZFS you have one option to choose whether to use normalization: 'nomalization = "none|FormD|FormKCf"' And a separate option to choose whether to accept non-utf8 filenames: 'utf8only = "on|off". The default setting appears to be that ZFS does allow non-utf8 filenames. Whereas with Olaf's series you have one option that turns normalization on or off, and he is not giving you a choice of whether non-utf8 filenames will be accepted (they will be accepted). So IIUC there is a distinction: The utf8 support for ZFS is "more optional" than the utf8 support for XFS. Regards, Ben From bfoster@redhat.com Fri Sep 26 13:32:36 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id CE7388021 for ; Fri, 26 Sep 2014 13:32:36 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id BDB2E304053 for ; Fri, 26 Sep 2014 11:32:33 -0700 (PDT) X-ASG-Debug-ID: 1411756351-04cb6c50e42fc830001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id KZAPmhHoy4CEpRtE (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 11:32:32 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8QIWV6X014591 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 26 Sep 2014 14:32:31 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8QIWVxZ004944; Fri, 26 Sep 2014 14:32:31 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id E8B90120064; Fri, 26 Sep 2014 14:32:29 -0400 (EDT) From: Brian Foster To: fstests@vger.kernel.org Cc: xfs@oss.sgi.com Subject: [PATCH] xfs/053: test for stale data exposure via falloc/writeback interaction Date: Fri, 26 Sep 2014 14:32:29 -0400 X-ASG-Orig-Subj: [PATCH] xfs/053: test for stale data exposure via falloc/writeback interaction Message-Id: <1411756349-4537-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411756352 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 XFS buffered I/O writeback has a subtle race condition that leads to stale data exposure if the filesystem happens to crash after delayed allocation blocks are converted on disk and before data is written back to said blocks. Use file allocation commands to attempt to reproduce a related, but slightly different variant of this problem. The associated falloc commands can lead to partial writeback that converts an extent larger than the range affected by falloc. If the filesystem crashes after the extent conversion but before all other cached data is written to the extent, stale data can be exposed. Signed-off-by: Brian Foster --- This fell out of a combination of a conversation with Dave about XFS writeback and buffer/cache coherency and some hacking I'm doing on the XFS zero range implementation. Note that fpunch currently fails the test. Also, this test is XFS specific primarily due to the use of godown. Brian tests/xfs/053 | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/xfs/053.out | 10 ++++++ tests/xfs/group | 1 + 3 files changed, 112 insertions(+) create mode 100755 tests/xfs/053 create mode 100644 tests/xfs/053.out diff --git a/tests/xfs/053 b/tests/xfs/053 new file mode 100755 index 0000000..4fba127 --- /dev/null +++ b/tests/xfs/053 @@ -0,0 +1,101 @@ +#! /bin/bash +# FS QA Test No. 053 +# +# Test stale data exposure via writeback using various file allocation +# modification commands. The presumption is that such commands result in partial +# writeback and can convert a delayed allocation extent, that might be larger +# than the ranged affected by fallocate, to a normal extent. If the fs happens +# to crash sometime between when the extent modification is logged and writeback +# occurs for dirty pages within the extent but outside of the fallocated range, +# stale data exposure can occur. +# +#----------------------------------------------------------------------- +# Copyright (c) 2014 Red Hat, Inc. All Rights Reserved. +# +# This program 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. +# +# This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -f $tmp.* +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/punch + +# real QA test starts here +rm -f $seqres.full + +_crashtest() +{ + cmd=$1 + img=$SCRATCH_MNT/$seq.img + mnt=$SCRATCH_MNT/$seq.mnt + file=$mnt/file + + # Create an fs on a small, initialized image. The pattern is written to + # the image to detect stale data exposure. + $XFS_IO_PROG -f -c "truncate 0" -c "pwrite 0 25M" $img \ + >> $seqres.full 2>&1 + $MKFS_XFS_PROG $MKFS_OPTIONS $img >> $seqres.full 2>&1 + + mkdir -p $mnt + mount $img $mnt + + echo $cmd + + # write, run the test command and shutdown the fs + $XFS_IO_PROG -f -c "pwrite -S 1 0 64k" -c "$cmd 60k 4k" $file | \ + _filter_xfs_io + ./src/godown -f $mnt + + umount $mnt + mount $img $mnt + + # we generally expect a zero-sized file (this should be silent) + hexdump $file + + umount $mnt +} + +# Modify as appropriate. +_supported_fs xfs +_supported_os Linux +_require_scratch +_require_xfs_io_command "falloc" +_require_xfs_io_command "fpunch" +_require_xfs_io_command "fzero" + +_scratch_mkfs >/dev/null 2>&1 +_scratch_mount + +_crashtest "falloc -k" +_crashtest "fpunch" +_crashtest "fzero -k" + +status=0 +exit diff --git a/tests/xfs/053.out b/tests/xfs/053.out new file mode 100644 index 0000000..c777fe2 --- /dev/null +++ b/tests/xfs/053.out @@ -0,0 +1,10 @@ +QA output created by 053 +falloc -k +wrote 65536/65536 bytes at offset 0 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +fpunch +wrote 65536/65536 bytes at offset 0 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +fzero -k +wrote 65536/65536 bytes at offset 0 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) diff --git a/tests/xfs/group b/tests/xfs/group index 09bce15..408e617 100644 --- a/tests/xfs/group +++ b/tests/xfs/group @@ -49,6 +49,7 @@ 050 quota auto quick 051 auto log metadata 052 quota db auto quick +053 auto quick rw 054 quota auto quick 055 dump ioctl remote tape 056 dump ioctl auto quick -- 1.8.3.1 From olaf@sgi.com Fri Sep 26 14:37:18 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 5FC7829E01 for ; Fri, 26 Sep 2014 14:37:18 -0500 (CDT) Received: from xmail.sgi.com (pv-excas3-dc21.corp.sgi.com [137.38.106.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2F075304048; Fri, 26 Sep 2014 12:37:15 -0700 (PDT) Received: from [134.15.1.42] (134.15.1.42) by xmail.sgi.com (137.38.106.6) with Microsoft SMTP Server (TLS) id 14.3.195.1; Fri, 26 Sep 2014 14:37:14 -0500 Message-ID: <5425C067.7080904@sgi.com> Date: Fri, 26 Sep 2014 21:37:11 +0200 From: Olaf Weber Organization: SGI User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.2 MIME-Version: 1.0 To: Jeremy Allison , Christoph Hellwig CC: Dave Chinner , Ben Myers , , , Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <20140922222611.GZ4322@dastard> <5422C540.1060007@sgi.com> <20140924231024.GA4758@dastard> <54257D3F.70302@sgi.com> <20140926165605.GA25274@infradead.org> <20140926170407.GB6012@samba2> In-Reply-To: <20140926170407.GB6012@samba2> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [134.15.1.42] On 26-09-14 19:04, Jeremy Allison wrote: > On Fri, Sep 26, 2014 at 09:56:05AM -0700, Christoph Hellwig wrote: >> >> My take on this is: >> >> - I think we'll have to prevent non-utf8 file names for any cases where >> we use utf8 normalization. If you do not use utf8 normalization >> it's plain old Unix everything is allowed. >> >> - I think utf8 normalization vs not should be mkfs option, to make sure >> everyone including kernel and repair knows what sort of filesystem >> deal with. >> >> - case insensitive matching for utf8 normalized filesystems should be >> a runtime decision. mount time for now, but Samba people would be >> extremly happy to allow per-operation or per-process CI matching. >> But that is another totally different discusion I'd like to keep >> separate, I just want to make sure the disk format allows for it for >> now. > > Actually, I'm so eager for case-insensitive matching I'd > take "at format time", as with ZFS :-) :-). My argument against "mount time case-insensitivity" and for "mkfs time case-insensitivity" is related to switching from the case-sensitive domain to the case-insensitive one. For case-sensitive, from "README" to "readme" there are 64 different possible filenames. Let's say you create 63 out of these 64. Now remount the filesystem case-insensitive, and try to open by the 64th version of "readme". It is not an exact match for any of the 63 candidate files, and a case-insensitive match to all 63 candidate files. Which of these 63 files should be opened, and why that one in particular? > Having CI matching can speed up Samba operations by a > factor of 10 on large directories (warning, number made > up, depending on the number of entries per dir :-). I really want that to be true, but the proof of the pudding... Olaf -- Olaf Weber SGI Phone: +31(0)30-6696796 Veldzigt 2b Fax: +31(0)30-6696799 Technical Lead 3454 PW de Meern Vnet: 955-6796 Storage Software The Netherlands Email: olaf@sgi.com From jra@samba.org Fri Sep 26 14:47:01 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 9D86F7F62 for ; Fri, 26 Sep 2014 14:47:01 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6DA5E304048 for ; Fri, 26 Sep 2014 12:47:01 -0700 (PDT) X-ASG-Debug-ID: 1411760820-04bdf003a0363250001-NocioJ Received: from mail.samba.org (fn.samba.org [216.83.154.106]) by cuda.sgi.com with ESMTP id Npvp5e3FRROqNC4X (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 26 Sep 2014 12:47:00 -0700 (PDT) X-Barracuda-Envelope-From: jra@samba.org X-Barracuda-Apparent-Source-IP: 216.83.154.106 Received: from mail.samba.org (localhost [127.0.0.1]) by mail.samba.org (Postfix) with ESMTP id 0342EACF30; Fri, 26 Sep 2014 13:47:00 -0600 (MDT) Received: by mail.samba.org (Postfix, from userid 549) id EB392ACF32; Fri, 26 Sep 2014 13:46:59 -0600 (MDT) Date: Fri, 26 Sep 2014 12:46:56 -0700 From: Jeremy Allison To: Olaf Weber Cc: Jeremy Allison , Christoph Hellwig , Dave Chinner , Ben Myers , linux-fsdevel@vger.kernel.org, tinguely@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140926194656.GC13066@samba2> X-ASG-Orig-Subj: Re: [RFC v2] Unicode/UTF-8 support for XFS Reply-To: Jeremy Allison References: <20140918195650.GI19952@sgi.com> <20140922222611.GZ4322@dastard> <5422C540.1060007@sgi.com> <20140924231024.GA4758@dastard> <54257D3F.70302@sgi.com> <20140926165605.GA25274@infradead.org> <20140926170407.GB6012@samba2> <5425C067.7080904@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5425C067.7080904@sgi.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: fn.samba.org[216.83.154.106] X-Barracuda-Start-Time: 1411760820 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9916 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 26, 2014 at 09:37:11PM +0200, Olaf Weber wrote: > > My argument against "mount time case-insensitivity" and for "mkfs > time case-insensitivity" is related to switching from the > case-sensitive domain to the case-insensitive one. > > For case-sensitive, from "README" to "readme" there are 64 different > possible filenames. Let's say you create 63 out of these 64. Now > remount the filesystem case-insensitive, and try to open by the 64th > version of "readme". It is not an exact match for any of the 63 > candidate files, and a case-insensitive match to all 63 candidate > files. Which of these 63 files should be opened, and why that one in > particular? I'm ok with "mkfs time case-insensitivity" - really ! Most of my OEMs would set that and claim victory (few of them care much about NFS semantics :-). > >Having CI matching can speed up Samba operations by a > >factor of 10 on large directories (warning, number made > >up, depending on the number of entries per dir :-). > > I really want that to be true, but the proof of the pudding... No it really *is* true. The reason I can't give exact numbers is it depends on the number of entries. Remember, for every cache *miss*, we have to scan the entire directory. So a user asks for README, and we attempt that and it fails. So now we have to enumerate the entire directory to see if READMe (or any other case varient) exists. Now do that in a directory with 10, 100, 1000, .... 10000000 existing files (don't laugh, I've seen an application for Music files that did *exactly* that). On a case insensitive filesystem you just request README and you're done. Certain vendors who shall remain nameless :-) created test cases of just this example to show how much storage on Linux sucks. Not a happy camper about that - and telling them to use ZFS on FreeBSD or Solaris just doesn't feel right :-). Jeremy. From olaf@sgi.com Fri Sep 26 15:03:58 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 8422B7F9A for ; Fri, 26 Sep 2014 15:03:58 -0500 (CDT) Received: from xmail.sgi.com (pv-excas3-dc21.corp.sgi.com [137.38.106.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 456A28F8040; Fri, 26 Sep 2014 13:03:55 -0700 (PDT) Received: from [134.15.1.42] (134.15.1.42) by xmail.sgi.com (137.38.106.6) with Microsoft SMTP Server (TLS) id 14.3.195.1; Fri, 26 Sep 2014 15:03:54 -0500 Message-ID: <5425C6A6.3060003@sgi.com> Date: Fri, 26 Sep 2014 22:03:50 +0200 From: Olaf Weber Organization: SGI User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.2 MIME-Version: 1.0 To: Jeremy Allison CC: Christoph Hellwig , Dave Chinner , Ben Myers , , , Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <20140922222611.GZ4322@dastard> <5422C540.1060007@sgi.com> <20140924231024.GA4758@dastard> <54257D3F.70302@sgi.com> <20140926165605.GA25274@infradead.org> <20140926170407.GB6012@samba2> <5425C067.7080904@sgi.com> <20140926194656.GC13066@samba2> In-Reply-To: <20140926194656.GC13066@samba2> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [134.15.1.42] On 26-09-14 21:46, Jeremy Allison wrote: > On Fri, Sep 26, 2014 at 09:37:11PM +0200, Olaf Weber wrote: >> >> My argument against "mount time case-insensitivity" and for "mkfs >> time case-insensitivity" is related to switching from the >> case-sensitive domain to the case-insensitive one. >> >> For case-sensitive, from "README" to "readme" there are 64 different >> possible filenames. Let's say you create 63 out of these 64. Now >> remount the filesystem case-insensitive, and try to open by the 64th >> version of "readme". It is not an exact match for any of the 63 >> candidate files, and a case-insensitive match to all 63 candidate >> files. Which of these 63 files should be opened, and why that one in >> particular? > > I'm ok with "mkfs time case-insensitivity" - really ! > Most of my OEMs would set that and claim victory (few > of them care much about NFS semantics :-). I'd say you can have CIFS-style case-insensitive semantics or NFS-style case-sensitive semantics, but not both. And in particular, that a customer should not actually want to have both. >>> Having CI matching can speed up Samba operations by a >>> factor of 10 on large directories (warning, number made >>> up, depending on the number of entries per dir :-). >> >> I really want that to be true, but the proof of the pudding... > > No it really *is* true. The reason I can't give > exact numbers is it depends on the number of entries. > > Remember, for every cache *miss*, we have to scan > the entire directory. > > So a user asks for README, and we attempt that > and it fails. So now we have to enumerate the > entire directory to see if READMe (or any other > case varient) exists. > > Now do that in a directory with 10, 100, 1000, > .... 10000000 existing files (don't laugh, I've > seen an application for Music files that did > *exactly* that). On a case insensitive filesystem > you just request README and you're done. > > Certain vendors who shall remain nameless :-) > created test cases of just this example to > show how much storage on Linux sucks. Not > a happy camper about that - and telling them > to use ZFS on FreeBSD or Solaris just doesn't > feel right :-). Here's the thing to bear in mind: what I did is a straightforward extension of the existing XFS ASCII-based case-insensitive code. If that gets you the desired performance improvement, then my code should extend that to more general usage. If it doesn't, then there are places in XFS that I haven't touched that need modification to have these cases work well. Olaf -- Olaf Weber SGI Phone: +31(0)30-6696796 Veldzigt 2b Fax: +31(0)30-6696799 Technical Lead 3454 PW de Meern Vnet: 955-6796 Storage Software The Netherlands Email: olaf@sgi.com From david@fromorbit.com Fri Sep 26 18:01:16 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A0168801F for ; Fri, 26 Sep 2014 18:01:16 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2DD6DAC007 for ; Fri, 26 Sep 2014 16:01:13 -0700 (PDT) X-ASG-Debug-ID: 1411772469-04cb6c50e6306b40001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id zBBNDChkALGE4IJZ for ; Fri, 26 Sep 2014 16:01:10 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AnQlALXvJVR5LHimPGdsb2JhbABfgw6BKoIxhQevDAEBAQEBAQaVWIVrBAICgQYXAQYBAQEBODmEBAEBBDocIxAIAw4KCSUPBSUDBxoTiD2/MhgYhXqJKxRNB4RLBZ0lmVIrL4EHgUMBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail06.adl2.internode.on.net with ESMTP; 27 Sep 2014 08:31:07 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XXeVe-0003mM-Fh; Sat, 27 Sep 2014 09:01:06 +1000 Date: Sat, 27 Sep 2014 09:01:06 +1000 From: Dave Chinner To: Christoph Hellwig Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/3] xfs: remove bitfield based superblock updates Message-ID: <20140926230106.GO4945@dastard> X-ASG-Orig-Subj: Re: [PATCH 2/3] xfs: remove bitfield based superblock updates References: <1411647632-28240-1-git-send-email-david@fromorbit.com> <1411647632-28240-3-git-send-email-david@fromorbit.com> <20140926094550.GB10692@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140926094550.GB10692@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1411772470 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9921 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 26, 2014 at 02:45:50AM -0700, Christoph Hellwig wrote: > This breaks generic/230 for me on an x86-64 VM: > > --- tests/generic/230.out 2013-11-11 10:38:59.000000000 +0000 > +++ /root/xfstests/results//generic/230.out.bad 2014-09-26 09:47:37.000000000 +0000 > @@ -23,11 +23,8 @@ > Write 900k... > Rewrite 1001k... > Write 1000k... > -pwrite64: Disk quota exceeded > Write 4096... > -pwrite64: Disk quota exceeded > Touch 3+4 > Touch 5+6 > touch: cannot touch 'SCRATCH_MNT/file6': Disk quota exceeded > Touch 5 > -touch: cannot touch 'SCRATCH_MNT/file5': Disk quota exceeded Curious, I haven't seen any change in quota behaviour on any test as a result of these changes. What's the config of your VM and xfstests run? Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Fri Sep 26 18:02:57 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 5577D801F for ; Fri, 26 Sep 2014 18:02:57 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 43BD48F8037 for ; Fri, 26 Sep 2014 16:02:54 -0700 (PDT) X-ASG-Debug-ID: 1411772572-04cb6c50e4306bd0001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id D10TWyfyjjbrwWGP for ; Fri, 26 Sep 2014 16:02:52 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AnUlALXvJVR5LHimPGdsb2JhbABfgw6BKoIxhQevDAEBAQEBAQaVWIVrBAICgQYXAQYBAQEBODmEBAEBBCcTHCMQCAMOCgklDwUlAwcaE4g9v0oYhXqKDAeESwEEnSWZUisvgkoBAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail06.adl2.internode.on.net with ESMTP; 27 Sep 2014 08:32:36 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XXeX5-0003mi-WC; Sat, 27 Sep 2014 09:02:36 +1000 Date: Sat, 27 Sep 2014 09:02:35 +1000 From: Dave Chinner To: Christoph Hellwig Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/3] xfs: remove bitfield based superblock updates Message-ID: <20140926230235.GP4945@dastard> X-ASG-Orig-Subj: Re: [PATCH 2/3] xfs: remove bitfield based superblock updates References: <1411647632-28240-1-git-send-email-david@fromorbit.com> <1411647632-28240-3-git-send-email-david@fromorbit.com> <20140926100027.GG10692@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140926100027.GG10692@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1411772572 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9921 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 26, 2014 at 03:00:27AM -0700, Christoph Hellwig wrote: > > + to->sb_uquotino = cpu_to_be64(from->sb_uquotino); > > + if (xfs_sb_version_has_pquotino(from)) { > > + to->sb_qflags = be16_to_cpu(from->sb_qflags); > > + to->sb_gquotino = cpu_to_be64(from->sb_gquotino); > > + to->sb_pquotino = cpu_to_be64(from->sb_pquotino); > > + return; > > + } > > sparse complains that the be16_to_cpu should be a cpu_to_be16 for > sb_qflags.. Good catch. Fixed. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Fri Sep 26 18:20:24 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 8BF62802D for ; Fri, 26 Sep 2014 18:20:24 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 28DF5AC00B for ; Fri, 26 Sep 2014 16:20:23 -0700 (PDT) X-ASG-Debug-ID: 1411773618-04bdf003a236a920001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id gkbXxeby00eyBZwf for ; Fri, 26 Sep 2014 16:20:18 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: As4+ADn0JVR5LHimPGdsb2JhbABXCIMOgSqCMYUHrwwBAQEBAQEGlViFawICAQECgQYXAQYBAQEBODmEAwEBBAEnExwjEAgRBwMJJQ8FJQMHGhOINge/IxgYhXqJNlYHhEsFhiiJI41ajECNEisvgQYCHgQCgR4BAQE Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail06.adl2.internode.on.net with ESMTP; 27 Sep 2014 08:50:14 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XXeo9-0003pG-1p; Sat, 27 Sep 2014 09:20:13 +1000 Date: Sat, 27 Sep 2014 09:20:13 +1000 From: Dave Chinner To: Christoph Hellwig Cc: xfs@oss.sgi.com Subject: [PATCH 10/11 v2] xfs: check xfs_buf_read_uncached returns correctly Message-ID: <20140926232012.GQ4945@dastard> X-ASG-Orig-Subj: [PATCH 10/11 v2] xfs: check xfs_buf_read_uncached returns correctly References: <1411648461-29003-1-git-send-email-david@fromorbit.com> <1411648461-29003-11-git-send-email-david@fromorbit.com> <20140926102148.GF22194@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140926102148.GF22194@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1411773618 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9922 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 26, 2014 at 03:21:48AM -0700, Christoph Hellwig wrote: > On Thu, Sep 25, 2014 at 10:34:20PM +1000, Dave Chinner wrote: > > From: Dave Chinner > > > > xfs_buf_read_uncached() has two failure modes. If can either return > > NULL or bp->b_error != 0 depending on the type of failure, and not > > all callers check for both. Fix it up. > > This changelog still seems to be for your previous version and needs > an update now tha xfs_buf_read_uncached always returns the error > directly. Fixed. > > > - return NULL; > > + return ENOMEM; > > Should be -ENOMEM these days, shouldn't it? Yes, good catch. > > release_buf: > > - xfs_buf_relse(bp); > > + if (bp) > > + xfs_buf_relse(bp); > > Shouldn't bp always be valid at this point? It is. Fixed. Updated patch below. Cheers, Dave. -- Dave Chinner david@fromorbit.com xfs: check xfs_buf_read_uncached returns correctly From: Dave Chinner xfs_buf_read_uncached() has two failure modes. If can either return NULL or bp->b_error != 0 depending on the type of failure, and not all callers check for both. Fix it so that xfs_buf_read_uncached() always returns the error status, and the buffer is returned as a function parameter. The buffer will only be returned on success. Signed-off-by: Dave Chinner --- fs/xfs/xfs_buf.c | 18 +++++++++++++---- fs/xfs/xfs_buf.h | 6 +++--- fs/xfs/xfs_fsops.c | 11 +++-------- fs/xfs/xfs_mount.c | 55 +++++++++++++++++++++++++--------------------------- fs/xfs/xfs_rtalloc.c | 30 ++++++++++++---------------- 5 files changed, 58 insertions(+), 62 deletions(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index d1d3fe6..017b6af 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -688,29 +688,39 @@ xfs_buf_readahead_map( * Read an uncached buffer from disk. Allocates and returns a locked * buffer containing the disk contents or nothing. */ -struct xfs_buf * +int xfs_buf_read_uncached( struct xfs_buftarg *target, xfs_daddr_t daddr, size_t numblks, int flags, + struct xfs_buf **bpp, const struct xfs_buf_ops *ops) { struct xfs_buf *bp; + *bpp = NULL; + bp = xfs_buf_get_uncached(target, numblks, flags); if (!bp) - return NULL; + return -ENOMEM; /* set up the buffer for a read IO */ ASSERT(bp->b_map_count == 1); - bp->b_bn = daddr; + bp->b_bn = XFS_BUF_DADDR_NULL; /* always null for uncached buffers */ bp->b_maps[0].bm_bn = daddr; bp->b_flags |= XBF_READ; bp->b_ops = ops; xfs_buf_submit_wait(bp); - return bp; + if (bp->b_error) { + int error = bp->b_error; + xfs_buf_relse(bp); + return error; + } + + *bpp = bp; + return 0; } /* diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 0acfc30..82002c0 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -269,9 +269,9 @@ int xfs_buf_associate_memory(struct xfs_buf *bp, void *mem, size_t length); struct xfs_buf *xfs_buf_get_uncached(struct xfs_buftarg *target, size_t numblks, int flags); -struct xfs_buf *xfs_buf_read_uncached(struct xfs_buftarg *target, - xfs_daddr_t daddr, size_t numblks, int flags, - const struct xfs_buf_ops *ops); +int xfs_buf_read_uncached(struct xfs_buftarg *target, xfs_daddr_t daddr, + size_t numblks, int flags, struct xfs_buf **bpp, + const struct xfs_buf_ops *ops); void xfs_buf_hold(struct xfs_buf *bp); /* Releasing Buffers */ diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 126b4b3..ece69c2 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -172,16 +172,11 @@ xfs_growfs_data_private( if ((error = xfs_sb_validate_fsb_count(&mp->m_sb, nb))) return error; dpct = pct - mp->m_sb.sb_imax_pct; - bp = xfs_buf_read_uncached(mp->m_ddev_targp, + error = xfs_buf_read_uncached(mp->m_ddev_targp, XFS_FSB_TO_BB(mp, nb) - XFS_FSS_TO_BB(mp, 1), - XFS_FSS_TO_BB(mp, 1), 0, NULL); - if (!bp) - return -EIO; - if (bp->b_error) { - error = bp->b_error; - xfs_buf_relse(bp); + XFS_FSS_TO_BB(mp, 1), 0, &bp, NULL); + if (error) return error; - } xfs_buf_relse(bp); new = nb; /* use new as a temporary here */ diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 78a2799..d731035 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -300,21 +300,15 @@ xfs_readsb( * access to the superblock. */ reread: - bp = xfs_buf_read_uncached(mp->m_ddev_targp, XFS_SB_DADDR, - BTOBB(sector_size), 0, buf_ops); - if (!bp) { - if (loud) - xfs_warn(mp, "SB buffer read failed"); - return -EIO; - } - if (bp->b_error) { - error = bp->b_error; + error = xfs_buf_read_uncached(mp->m_ddev_targp, XFS_SB_DADDR, + BTOBB(sector_size), 0, &bp, buf_ops); + if (error) { if (loud) xfs_warn(mp, "SB validate failed with error %d.", error); /* bad CRC means corrupted metadata */ if (error == -EFSBADCRC) error = -EFSCORRUPTED; - goto release_buf; + return error; } /* @@ -544,40 +538,43 @@ xfs_set_inoalignment(xfs_mount_t *mp) * Check that the data (and log if separate) is an ok size. */ STATIC int -xfs_check_sizes(xfs_mount_t *mp) +xfs_check_sizes( + struct xfs_mount *mp) { - xfs_buf_t *bp; + struct xfs_buf *bp; xfs_daddr_t d; + int error; d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks); if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) { xfs_warn(mp, "filesystem size mismatch detected"); return -EFBIG; } - bp = xfs_buf_read_uncached(mp->m_ddev_targp, + error = xfs_buf_read_uncached(mp->m_ddev_targp, d - XFS_FSS_TO_BB(mp, 1), - XFS_FSS_TO_BB(mp, 1), 0, NULL); - if (!bp) { + XFS_FSS_TO_BB(mp, 1), 0, &bp, NULL); + if (error) { xfs_warn(mp, "last sector read failed"); - return -EIO; + return error; } xfs_buf_relse(bp); - if (mp->m_logdev_targp != mp->m_ddev_targp) { - d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); - if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) { - xfs_warn(mp, "log size mismatch detected"); - return -EFBIG; - } - bp = xfs_buf_read_uncached(mp->m_logdev_targp, + if (mp->m_logdev_targp == mp->m_ddev_targp) + return 0; + + d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); + if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) { + xfs_warn(mp, "log size mismatch detected"); + return -EFBIG; + } + error = xfs_buf_read_uncached(mp->m_logdev_targp, d - XFS_FSB_TO_BB(mp, 1), - XFS_FSB_TO_BB(mp, 1), 0, NULL); - if (!bp) { - xfs_warn(mp, "log device read failed"); - return -EIO; - } - xfs_buf_relse(bp); + XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL); + if (error) { + xfs_warn(mp, "log device read failed"); + return error; } + xfs_buf_relse(bp); return 0; } diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index d45aebe..e1175ea 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -921,16 +921,11 @@ xfs_growfs_rt( /* * Read in the last block of the device, make sure it exists. */ - bp = xfs_buf_read_uncached(mp->m_rtdev_targp, + error = xfs_buf_read_uncached(mp->m_rtdev_targp, XFS_FSB_TO_BB(mp, nrblocks - 1), - XFS_FSB_TO_BB(mp, 1), 0, NULL); - if (!bp) - return -EIO; - if (bp->b_error) { - error = bp->b_error; - xfs_buf_relse(bp); + XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL); + if (error) return error; - } xfs_buf_relse(bp); /* @@ -1184,11 +1179,12 @@ xfs_rtallocate_extent( */ int /* error */ xfs_rtmount_init( - xfs_mount_t *mp) /* file system mount structure */ + struct xfs_mount *mp) /* file system mount structure */ { - xfs_buf_t *bp; /* buffer for last block of subvolume */ - xfs_daddr_t d; /* address of last block of subvolume */ - xfs_sb_t *sbp; /* filesystem superblock copy in mount */ + struct xfs_buf *bp; /* buffer for last block of subvolume */ + struct xfs_sb *sbp; /* filesystem superblock copy in mount */ + xfs_daddr_t d; /* address of last block of subvolume */ + int error; sbp = &mp->m_sb; if (sbp->sb_rblocks == 0) @@ -1214,14 +1210,12 @@ xfs_rtmount_init( (unsigned long long) mp->m_sb.sb_rblocks); return -EFBIG; } - bp = xfs_buf_read_uncached(mp->m_rtdev_targp, + error = xfs_buf_read_uncached(mp->m_rtdev_targp, d - XFS_FSB_TO_BB(mp, 1), - XFS_FSB_TO_BB(mp, 1), 0, NULL); - if (!bp || bp->b_error) { + XFS_FSB_TO_BB(mp, 1), 0, &bp, NULL); + if (error) { xfs_warn(mp, "realtime device size check failed"); - if (bp) - xfs_buf_relse(bp); - return -EIO; + return error; } xfs_buf_relse(bp); return 0; From david@fromorbit.com Fri Sep 26 18:22:05 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E852F802E for ; Fri, 26 Sep 2014 18:22:04 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 83E3CAC008 for ; Fri, 26 Sep 2014 16:22:04 -0700 (PDT) X-ASG-Debug-ID: 1411773722-04cb6c50e53073a0001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id fkMQBN9DODy0Rmkp for ; Fri, 26 Sep 2014 16:22:02 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: As8+ADn0JVR5LHimPGdsb2JhbABfgw6BKoIxhQevDAEBAQEBAQaVWIVrAgIBAQKBBhcBBgEBAQE4OYQDAQEBAwE6HCMFCwgDDgcDCSUPBSUDBxoTiDYHvzsYhXqKDAeESwEEj0uNWoxAjRIrL4EIJIEeAQEB Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail06.adl2.internode.on.net with ESMTP; 27 Sep 2014 08:52:02 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XXept-0003pU-63; Sat, 27 Sep 2014 09:22:01 +1000 Date: Sat, 27 Sep 2014 09:22:01 +1000 From: Dave Chinner To: Christoph Hellwig Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/5] xfs: refactor xlog_recover_process_data() Message-ID: <20140926232201.GR4945@dastard> X-ASG-Orig-Subj: Re: [PATCH 1/5] xfs: refactor xlog_recover_process_data() References: <1411697952-24741-1-git-send-email-david@fromorbit.com> <1411697952-24741-2-git-send-email-david@fromorbit.com> <20140926114238.GA16576@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140926114238.GA16576@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1411773722 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9922 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 26, 2014 at 04:42:38AM -0700, Christoph Hellwig wrote: > On Fri, Sep 26, 2014 at 12:19:08PM +1000, Dave Chinner wrote: > > From: Dave Chinner > > > > Clean up xlog_recover_process_data() structure in preparation for > > fixing the allocation and freeing context of the transaction being > > recovered. > > > > Signed-off-by: Dave Chinner > > Looks good. The only behavior change I could spot was that we now > validate the length of an ophdr even when starting a new transaction, > which seems sensible. > > Nipick: maybe the lp argument to xlog_recover_process_ophdr should > be called end to make it more obvious? Yes, I had that thought too. I'll change it. > Reviewed-by: Christoph Hellwig Thanks! -- Dave Chinner david@fromorbit.com From david@fromorbit.com Fri Sep 26 18:27:50 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B405229E09 for ; Fri, 26 Sep 2014 18:27:50 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4F5BEAC004 for ; Fri, 26 Sep 2014 16:27:50 -0700 (PDT) X-ASG-Debug-ID: 1411774067-04cbb073013ec140001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id HpGC862z82gMxK7F for ; Fri, 26 Sep 2014 16:27:48 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtA+AJr1JVR5LHimPGdsb2JhbABfgw6BKoIxhQevDAEBAQEBAQaVWIVrAgIBAQKBBhcBBgEBAQE4OYQDAQEBAwEnExwjBQsIAw4HAwklDwUlAwcaE4g2B78iGBiFeooMB4RLBY9LjVqMQI0SKy+CSgEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail06.adl2.internode.on.net with ESMTP; 27 Sep 2014 08:57:46 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XXevR-0003qQ-Ur; Sat, 27 Sep 2014 09:27:45 +1000 Date: Sat, 27 Sep 2014 09:27:45 +1000 From: Dave Chinner To: Christoph Hellwig Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/5] xfs: recovery of XLOG_UNMOUNT_TRANS leaks memory Message-ID: <20140926232745.GS4945@dastard> X-ASG-Orig-Subj: Re: [PATCH 2/5] xfs: recovery of XLOG_UNMOUNT_TRANS leaks memory References: <1411697952-24741-1-git-send-email-david@fromorbit.com> <1411697952-24741-3-git-send-email-david@fromorbit.com> <20140926120104.GA10574@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140926120104.GA10574@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1411774067 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9922 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 26, 2014 at 05:01:04AM -0700, Christoph Hellwig wrote: > On Fri, Sep 26, 2014 at 12:19:09PM +1000, Dave Chinner wrote: > > From: Dave Chinner > > > > The XLOG_UNMOUNT_TRANS case skips the transaction, despite the fact > > an unmount record is always in a standalone transaction. Hence > > whenever we come across one of these we need to free the transaction > > structure associated with it as there is no commit record that > > follows it. > > > > Signed-off-by: Dave Chinner > > Looks good, > > Reviewed-by: Christoph Hellwig > > > @@ -3600,8 +3605,10 @@ xlog_recover_ophdr_to_trans( > > * on this opheader is allocate a new recovery container to hold > > * the recovery ops that will follow. > > */ > > - if (ohead->oh_flags & XLOG_START_TRANS) > > + if (ohead->oh_flags & XLOG_START_TRANS) { > > + ASSERT(be32_to_cpu(ohead->oh_len) == 0); > > xlog_recover_new_tid(rhp, tid, be64_to_cpu(rhead->h_lsn)); > > + } > > return NULL; > > .. but I suspect this hunk fits better into the previous patch. Folded it into the first patch. > Also shouldn't we handle any sort of on disk corruption more gracefully? Yes, we should. However, the recovery code is so full of this sort of ASSERT() checking that graceful handling of errors is fairly significant piece of work. It's already on my "cleanup work for a rainy day" list. ;) Cheers, Dave. -- Dave Chinner david@fromorbit.com From gsushma@gmail.com Sat Sep 27 02:32:26 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE, T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id EAEEC7FC4 for ; Sat, 27 Sep 2014 02:32:25 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id D88DC304039 for ; Sat, 27 Sep 2014 00:32:22 -0700 (PDT) X-ASG-Debug-ID: 1411803141-04cbb073023f7b20001-NocioJ Received: from mail-ie0-f172.google.com (mail-ie0-f172.google.com [209.85.223.172]) by cuda.sgi.com with ESMTP id fDcJeXgmlEfAbzZq (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Sat, 27 Sep 2014 00:32:21 -0700 (PDT) X-Barracuda-Envelope-From: gsushma@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.223.172 X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.172] Received: by mail-ie0-f172.google.com with SMTP id rp18so14999976iec.17 for ; Sat, 27 Sep 2014 00:32:21 -0700 (PDT) X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.172] X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.172] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=Xxb0OtVQCfiNhArb/N5ZlDEq4duLF487+crdOIP9s5M=; b=MvwcCnwqa8ylrCY/GzP70rwrhQrxDWOtq7oueWSi3wmYX4KekLM0QZgfCRZfWXjuus X3By2LK8IoCi9xBgsFmI6C7rkKoco1od1z7vHOe6K+cygjZ5ejSo+mvkYuq0D1htukZi 7ohkveDF2KZQ9uLmKGf4GLKxhcXMqtUTMynPnGY2ONLkJekcyz4gTdkUs96ZEBnrcNM1 QRDRA0pI04Mcj5BAjYM8e0e3t2zRQ8dVelfg62i01vtlHJtYa/0cCCLetM4j5wfrEcRk Hw6QxGF/wfcnLpwk8uzpuFu3NbBNQLJvT+fDfKLZ3UWFzbjvvSsmgm5f3aZ5WjypXtbb YI+A== MIME-Version: 1.0 X-Received: by 10.42.216.17 with SMTP id hg17mr32326901icb.69.1411803141221; Sat, 27 Sep 2014 00:32:21 -0700 (PDT) Received: by 10.64.84.38 with HTTP; Sat, 27 Sep 2014 00:32:21 -0700 (PDT) Date: Sat, 27 Sep 2014 00:32:21 -0700 Message-ID: Subject: blktrace and xfs_db block offset mismatch From: Sushma R X-ASG-Orig-Subj: blktrace and xfs_db block offset mismatch To: xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=f46d04089005b9b55c050407087a X-Barracuda-Connect: mail-ie0-f172.google.com[209.85.223.172] X-Barracuda-Start-Time: 1411803141 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9936 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message --f46d04089005b9b55c050407087a Content-Type: text/plain; charset=UTF-8 Hi, I ran blktrace while reading a file on XFS partition and here's it's output. 8,17 3 1 22.065944956 5489 D R 20973896 + 8 [cat] Using xfs_db, I dumped the inode for the same file and it shows the following as its data extents. u.bmx[0] = [startoff,startblock,blockcount,extentflag] 0:[0,2621481,1,0] I understand that blktrace reports in 512-byte sectors while xfs_db in filesystem block size (which is the default 4KB on my setup). Converting blktrace offset to fs block = 2621737 which is close to the data extent startblock (2621481), but still off by 256 fs blocks. Could someone please help understand the reason for this mismatch? Thanks, Sushma --f46d04089005b9b55c050407087a Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi,

I ran blktrace while reading a file= on XFS partition and here's it's output.

= 8,17 =C2=A0 3 =C2=A0 =C2=A0 =C2=A0 =C2=A01 =C2=A0 =C2=A022.065944956 =C2=A0= 5489 =C2=A0D =C2=A0 R 20973896 + 8 [cat]

Using= xfs_db, I dumped the inode for the same file and it shows the following as= its data extents.

u.bmx[0] =3D [startoff,startblo= ck,blockcount,extentflag] 0:[0,2621481,1,0]

I = understand that blktrace reports in 512-byte sectors while xfs_db in filesy= stem block size (which is the default 4KB on my setup).
Convertin= g blktrace offset to fs block =3D=C2=A02621737 which is close to the data e= xtent startblock (2621481), but still off by 256 fs blocks.

<= /div>
Could someone please help understand the reason for this mismatch= ?

Thanks,
Sushma
--f46d04089005b9b55c050407087a-- From bfoster@redhat.com Sat Sep 27 09:39:07 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 4448E7F9A for ; Sat, 27 Sep 2014 09:39:07 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 315E9304039 for ; Sat, 27 Sep 2014 07:39:06 -0700 (PDT) X-ASG-Debug-ID: 1411828742-04cb6c50e7331790001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id drD2J6Aom4VO7tA0 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Sat, 27 Sep 2014 07:39:02 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8REd0JE023671 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Sat, 27 Sep 2014 10:39:01 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8REd00M022898; Sat, 27 Sep 2014 10:39:00 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 5EFFF120064; Sat, 27 Sep 2014 10:38:59 -0400 (EDT) Date: Sat, 27 Sep 2014 10:38:59 -0400 From: Brian Foster To: Sushma R Cc: xfs@oss.sgi.com Subject: Re: blktrace and xfs_db block offset mismatch Message-ID: <20140927143859.GA60739@bfoster.bfoster> X-ASG-Orig-Subj: Re: blktrace and xfs_db block offset mismatch References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411828742 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Sat, Sep 27, 2014 at 12:32:21AM -0700, Sushma R wrote: > Hi, > > I ran blktrace while reading a file on XFS partition and here's it's output. > > 8,17 3 1 22.065944956 5489 D R 20973896 + 8 [cat] > > Using xfs_db, I dumped the inode for the same file and it shows the > following as its data extents. > > u.bmx[0] = [startoff,startblock,blockcount,extentflag] 0:[0,2621481,1,0] > > I understand that blktrace reports in 512-byte sectors while xfs_db in > filesystem block size (which is the default 4KB on my setup). > Converting blktrace offset to fs block = 2621737 which is close to the data > extent startblock (2621481), but still off by 256 fs blocks. > > Could someone please help understand the reason for this mismatch? > I believe you are comparing a raw read of a device to an internal XFS fsb, the latter of which is encoded to account for the internal structure of XFS (e.g., allocation groups). You might want to take a look at xfs_bmap on the file to see the actual disk blocks. The fsb to daddr conversion depends on the geometry of the fs, but you can get the various values with xfs_db as well. E.g.: convert fsb 2621481 agno # ag number convert fsb 2621481 agbno # relative ag block nr convert fsb 2621481 daddr # disk address Also, I'm not familiar enough with blktrace output off the top of my head so perhaps not an issue, but it's not clear to me whether the output above could have been converted/adjusted to a raw address based on a device partition. You might also want to verify you're looking at the actual file read vs. a directory/inode lookup or block mapping lookup or something else. I see you're running cat, a direct I/O read via dd might ensure you aren't just pulling file data from cache. Brian > Thanks, > Sushma > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From gsushma@gmail.com Sat Sep 27 10:48:49 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE, T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 412CB7F93 for ; Sat, 27 Sep 2014 10:48:49 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id F23608F804C for ; Sat, 27 Sep 2014 08:48:45 -0700 (PDT) X-ASG-Debug-ID: 1411832923-04bdf0039f3bbea0001-NocioJ Received: from mail-ie0-f170.google.com (mail-ie0-f170.google.com [209.85.223.170]) by cuda.sgi.com with ESMTP id htEv86O4y1FMEdBc (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Sat, 27 Sep 2014 08:48:43 -0700 (PDT) X-Barracuda-Envelope-From: gsushma@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.223.170 X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.170] Received: by mail-ie0-f170.google.com with SMTP id x19so14633915ier.29 for ; Sat, 27 Sep 2014 08:48:43 -0700 (PDT) X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.170] X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.170] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=ya6ua6l5B0JS9T65tDgMoqWwKRg7pw/5u9sf5RSPFJY=; b=YyI5DZ6WR4ZOs0IPQbc3pIfS2uMRocE+Ti2e1/S/kbztzzVGZfeW4xBWLjNIYKY++V saQbLgTnQ0qe32iUoHWxhpgFxDqJ508vnf8c91F7SpxXUQ7pO5LuL7S8L7zw4x/kAjeb ExUYBCDrPS3akJuE8vC0KLMCFjv6hThtMJF+up4v3cxsQ41ryFaCgnFIH1OfEKVCNFEl EF74SUt+NoZNxZ4SC6D9G0SSTgRDyzJExdoD39cj+tYJkWtAOL2Zmnly06X+93elmLc3 zT1KPDDsC5gaqAz+t3eu5wBIFuZdzvx8KtTbSCJIo/h0RDdsUjE2gWz2AH/tUlepdgJj k4zA== MIME-Version: 1.0 X-Received: by 10.42.180.5 with SMTP id bs5mr34863643icb.70.1411832429751; Sat, 27 Sep 2014 08:40:29 -0700 (PDT) Received: by 10.64.84.38 with HTTP; Sat, 27 Sep 2014 08:40:29 -0700 (PDT) In-Reply-To: <20140927143859.GA60739@bfoster.bfoster> References: <20140927143859.GA60739@bfoster.bfoster> Date: Sat, 27 Sep 2014 08:40:29 -0700 Message-ID: Subject: Re: blktrace and xfs_db block offset mismatch From: Sushma R X-ASG-Orig-Subj: Re: blktrace and xfs_db block offset mismatch To: Brian Foster Cc: xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=90e6ba6e866a7558ba05040ddaf9 X-Barracuda-Connect: mail-ie0-f170.google.com[209.85.223.170] X-Barracuda-Start-Time: 1411832923 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9949 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message --90e6ba6e866a7558ba05040ddaf9 Content-Type: text/plain; charset=UTF-8 Thanks Brian. I'm trying to understand how the internal XFS structures affect this mapping (http://oss.sgi.com/projects/xfs/papers/xfs_filesystem_structure.pdf ) xfs_bmap on the file matches that reported by extents in the file inode using xfs_db. Other conversions under xfs_db xfs_db> convert fsb 2621481 agno 0x0 (0) xfs_db> convert fsb 2621481 agbno 0x280029 (2621481) xfs_db> convert fsb 2621481 daddr 0x1400148 (20971848) I tried dd command with directio option and still blktrace reports the same raw block number as earlier. 8,17 3 1 0.000000000 6999 D R 20973896 + 1 [dd] I'm using xfs_db with the partition i.e. "xfs_db -r /dev/sdb1" However, if I use it on the whole disk "xfs_db -r /dev/sdb", it gives the following error xfs_db: cannot init perag data (117) Does this suggest something? Thanks, Sushma On Sat, Sep 27, 2014 at 7:38 AM, Brian Foster wrote: > On Sat, Sep 27, 2014 at 12:32:21AM -0700, Sushma R wrote: > > Hi, > > > > I ran blktrace while reading a file on XFS partition and here's it's > output. > > > > 8,17 3 1 22.065944956 5489 D R 20973896 + 8 [cat] > > > > Using xfs_db, I dumped the inode for the same file and it shows the > > following as its data extents. > > > > u.bmx[0] = [startoff,startblock,blockcount,extentflag] 0:[0,2621481,1,0] > > > > I understand that blktrace reports in 512-byte sectors while xfs_db in > > filesystem block size (which is the default 4KB on my setup). > > Converting blktrace offset to fs block = 2621737 which is close to the > data > > extent startblock (2621481), but still off by 256 fs blocks. > > > > Could someone please help understand the reason for this mismatch? > > > > I believe you are comparing a raw read of a device to an internal XFS > fsb, the latter of which is encoded to account for the internal > structure of XFS (e.g., allocation groups). You might want to take a > look at xfs_bmap on the file to see the actual disk blocks. > > The fsb to daddr conversion depends on the geometry of the fs, but you > can get the various values with xfs_db as well. E.g.: > > convert fsb 2621481 agno # ag number > convert fsb 2621481 agbno # relative ag block nr > convert fsb 2621481 daddr # disk address > > Also, I'm not familiar enough with blktrace output off the top of my > head so perhaps not an issue, but it's not clear to me whether the > output above could have been converted/adjusted to a raw address based > on a device partition. > > You might also want to verify you're looking at the actual file read vs. > a directory/inode lookup or block mapping lookup or something else. I > see you're running cat, a direct I/O read via dd might ensure you aren't > just pulling file data from cache. > > Brian > > > Thanks, > > Sushma > > > _______________________________________________ > > xfs mailing list > > xfs@oss.sgi.com > > http://oss.sgi.com/mailman/listinfo/xfs > > --90e6ba6e866a7558ba05040ddaf9 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Thanks Brian.

I'm trying to understand how the internal XFS structures= affect this mapping (http://oss.sgi.com/projects/xf= s/papers/xfs_filesystem_structure.pdf)

xfs_bma= p on the file matches that reported by extents in the file inode using xfs_= db.

Other conversions under xfs_db
= xfs_db> convert fsb 2621481 agno
0x0 (0)
xf= s_db> convert fsb 2621481 agbno
0x280029 (2621481)
x= fs_db> convert fsb 2621481 daddr
0x1400148 (20971848)

I tried dd command with directio option and still blktrace re= ports the same raw block number as earlier.
8,17 =C2=A0 3 =C2=A0 =C2=A0 =C2=A0 =C2=A01= =C2=A0 =C2=A0 0.000000000 =C2=A06999 =C2=A0D =C2=A0 R 20973896 + 1 [dd]

I'm using x= fs_db with the partition i.e. "xfs_db -r /dev/sdb1"
However, if I use it on = the whole disk "xfs_db -r /dev/sdb", it gives the following error=
xfs_db: ca= nnot init perag data (117)

Does this suggest something?

Thanks,
Sushma

On Sat, Sep 27, 2014 at 7:38 AM, Brian Foster <bf= oster@redhat.com> wrote:
On Sat, Sep 27, 2014 at 12:32:21AM -0= 700, Sushma R wrote:
> Hi,
>
> I ran blktrace while reading a file on XFS partition and here's it= 's output.
>
> 8,17=C2=A0 =C2=A03=C2=A0 =C2=A0 =C2=A0 =C2=A0 1=C2=A0 =C2=A0 22.065944= 956=C2=A0 5489=C2=A0 D=C2=A0 =C2=A0R 20973896 + 8 [cat]
>
> Using xfs_db, I dumped the inode for the same file and it shows the > following as its data extents.
>
> u.bmx[0] =3D [startoff,startblock,blockcount,extentflag] 0:[0,2621481,= 1,0]
>
> I understand that blktrace reports in 512-byte sectors while xfs_db in=
> filesystem block size (which is the default 4KB on my setup).
> Converting blktrace offset to fs block =3D 2621737 which is close to t= he data
> extent startblock (2621481), but still off by 256 fs blocks.
>
> Could someone please help understand the reason for this mismatch?
>

I believe you are comparing a raw read of a device to an intern= al XFS
fsb, the latter of which is encoded to account for the internal
structure of XFS (e.g., allocation groups). You might want to take a
look at xfs_bmap on the file to see the actual disk blocks.

The fsb to daddr conversion depends on the geometry of the fs, but you
can get the various values with xfs_db as well. E.g.:

convert fsb 2621481 agno=C2=A0 =C2=A0 =C2=A0 =C2=A0 # ag number
convert fsb 2621481 agbno=C2=A0 =C2=A0 =C2=A0 =C2=A0# relative ag block nr<= br> convert fsb 2621481 daddr=C2=A0 =C2=A0 =C2=A0 =C2=A0# disk address

Also, I'm not familiar enough with blktrace output off the top of my head so perhaps not an issue, but it's not clear to me whether the
output above could have been converted/adjusted to a raw address based
on a device partition.

You might also want to verify you're looking at the actual file read vs= .
a directory/inode lookup or block mapping lookup or something else. I
see you're running cat, a direct I/O read via dd might ensure you aren&= #39;t
just pulling file data from cache.

Brian

> Thanks,
> Sushma

> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> = http://oss.sgi.com/mailman/listinfo/xfs


--90e6ba6e866a7558ba05040ddaf9-- From infokokodeadls@gmail.com Sat Sep 27 11:12:37 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 3F6C37FA3 for ; Sat, 27 Sep 2014 11:12:37 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2C343304032 for ; Sat, 27 Sep 2014 09:12:34 -0700 (PDT) X-ASG-Debug-ID: 1411834351-04cb6c50e533dea0001-NocioJ Received: from smtp5.clear.net.nz (smtp5.clear.net.nz [203.97.33.68]) by cuda.sgi.com with ESMTP id IeSGc8orXey8ZoJ5 for ; Sat, 27 Sep 2014 09:12:32 -0700 (PDT) X-Barracuda-Envelope-From: infokokodeadls@gmail.com X-Barracuda-Apparent-Source-IP: 203.97.33.68 Received: from mxin2-orange.clear.net.nz (lb2-srcnat.clear.net.nz [203.97.32.237]) by smtp5.clear.net.nz (CLEAR Net Mail) with ESMTP id <0NCK0080VICA6730@smtp5.clear.net.nz> for xfs@oss.sgi.com; Sun, 28 Sep 2014 05:12:31 +1300 (NZDT) Received: from 121-73-72-50.cable.telstraclear.net (HELO rca.net.nz) ([121.73.72.50]) by smtpin2.clear.net.nz with ESMTP; Sun, 28 Sep 2014 05:12:29 +1300 Received: from KAY-PC ([109.144.191.175]) by rca.net.nz with Microsoft SMTPSVC(6.0.3790.4675); Sun, 28 Sep 2014 04:44:59 +1300 Date: Sat, 27 Sep 2014 16:42:54 +0100 From: Mr Felix Koloma Subject: BOOKING======== To: xfs@oss.sgi.com X-ASG-Orig-Subj: BOOKING======== Reply-To: infokokodeadls@gmail.com Message-id: <761214520552719147@121.73.72.50> MIME-version: 1.0 Content-type: multipart/alternative; charset=ISO-8859-1; boundary="mxAib4f33vIpwHqDppCC6j=_6e6LkqHwih0" X-OriginalArrivalTime: 27 Sep 2014 15:45:00.0281 (UTC) FILETIME=[FF11C690:01CFDA69] X-Barracuda-Connect: smtp5.clear.net.nz[203.97.33.68] X-Barracuda-Start-Time: 1411834352 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9950 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message This is a multi-part message in MIME format --mxAib4f33vIpwHqDppCC6j=_6e6LkqHwih0 Content-Type: text/plain ; charset="ISO-8859-1" Content-Transfer-Encoding: quoted-printable Good Day, Wanting to confirm a space for myself and family at your hotel anytime soon. Arrival Date:10 October 2014 Departure Date: 31 October 2014 One double rooms=20 Two single rooms. Number of Gust : 4 Adult Kindly reply back with the total cost for the own stay at the hotel and let me know if credit card prepayment is weclome. Mr Felix Koloma --mxAib4f33vIpwHqDppCC6j=_6e6LkqHwih0 Content-Type: text/html ; charset="ISO-8859-1" Content-Transfer-Encoding: quoted-printable Good Day,
 Wanting to confirm a space for myself and fam= ily at your
 hotel anytime soon.
 Arrival Date:10 Octo= ber  2014
 Departure Date: 31 October  2014
 = ;One double rooms
Two single rooms.
 Number of Gust : 4 Ad= ult
 Kindly reply back with the total cost for the own stay at= the
 hotel and let me know if credit card prepayment is weclo= me.
 Mr Felix Koloma --mxAib4f33vIpwHqDppCC6j=_6e6LkqHwih0-- From gsushma@gmail.com Sat Sep 27 12:24:13 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE, T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 551D17F81 for ; Sat, 27 Sep 2014 12:24:13 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 326158F804C for ; Sat, 27 Sep 2014 10:24:10 -0700 (PDT) X-ASG-Debug-ID: 1411838648-04cbb07303432360001-NocioJ Received: from mail-ie0-f182.google.com (mail-ie0-f182.google.com [209.85.223.182]) by cuda.sgi.com with ESMTP id 6yHROG7qGC1qw2eb (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Sat, 27 Sep 2014 10:24:08 -0700 (PDT) X-Barracuda-Envelope-From: gsushma@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.223.182 X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.182] Received: by mail-ie0-f182.google.com with SMTP id tp5so12189423ieb.27 for ; Sat, 27 Sep 2014 10:24:08 -0700 (PDT) X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.182] X-Barracuda-IPDD: Level1 [gmail.com/209.85.223.182] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=igvZpVjlPK0tbxyWzTQBKqsjmYaX1QwDPAW4g9d0oyY=; b=Zo9pZ82S0FyjZndvRp015fo5r++DFQwMAUlXW2B/N8rvqvQPt8KlesUv+HGL3aOujI n2emmiwng1PTwSck2Zr9jc+mFRbh+UE/QAOct4cDgFKSbaFgbCXawA6iR2G75VU4ooIu DDJy8LjQGdzQHecDLnaktw7YVbycw5xdVuS5r1KsDUr+Yg4M+ujOUNLL0+vtXjdRLQ6a 57Z6nmt/ggboKDDWsqoPAytw/3rHsPJG0Gag75Lc0iAwtO8Gs4TgzuDkh3dJgs/AtECi s82kxB3DnI+V8EQKLKpc8dSKhnkGlBh96sU72CqjdZmIVsHv9Ws5d+GrrrAsMI2Zq7Gn mKjQ== MIME-Version: 1.0 X-Received: by 10.50.85.38 with SMTP id e6mr22139465igz.5.1411836805286; Sat, 27 Sep 2014 09:53:25 -0700 (PDT) Received: by 10.64.84.38 with HTTP; Sat, 27 Sep 2014 09:53:25 -0700 (PDT) In-Reply-To: References: <20140927143859.GA60739@bfoster.bfoster> Date: Sat, 27 Sep 2014 09:53:25 -0700 Message-ID: Subject: Re: blktrace and xfs_db block offset mismatch From: Sushma R X-ASG-Orig-Subj: Re: blktrace and xfs_db block offset mismatch To: Brian Foster Cc: xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=089e0149c67a42aae705040edf99 X-Barracuda-Connect: mail-ie0-f182.google.com[209.85.223.182] X-Barracuda-Start-Time: 1411838648 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9952 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message --089e0149c67a42aae705040edf99 Content-Type: text/plain; charset=UTF-8 Please ignore my last comment. It doesn't make sense since file system is mounted on a disk partition. >>Also, I'm not familiar enough with blktrace output off the top of my >>head so perhaps not an issue, but it's not clear to me whether the >>output above could have been converted/adjusted to a raw address based >>on a device partition. Yes, it appears that blktrace adds device partition offset. Thanks!! On Sat, Sep 27, 2014 at 8:40 AM, Sushma R wrote: > Thanks Brian. > > I'm trying to understand how the internal XFS structures affect this > mapping ( > http://oss.sgi.com/projects/xfs/papers/xfs_filesystem_structure.pdf) > > xfs_bmap on the file matches that reported by extents in the file inode > using xfs_db. > > Other conversions under xfs_db > xfs_db> convert fsb 2621481 agno > 0x0 (0) > xfs_db> convert fsb 2621481 agbno > 0x280029 (2621481) > xfs_db> convert fsb 2621481 daddr > 0x1400148 (20971848) > > I tried dd command with directio option and still blktrace reports the > same raw block number as earlier. > 8,17 3 1 0.000000000 6999 D R 20973896 + 1 [dd] > > I'm using xfs_db with the partition i.e. "xfs_db -r /dev/sdb1" > However, if I use it on the whole disk "xfs_db -r /dev/sdb", it gives the > following error > xfs_db: cannot init perag data (117) > > Does this suggest something? > > Thanks, > Sushma > > On Sat, Sep 27, 2014 at 7:38 AM, Brian Foster wrote: > >> On Sat, Sep 27, 2014 at 12:32:21AM -0700, Sushma R wrote: >> > Hi, >> > >> > I ran blktrace while reading a file on XFS partition and here's it's >> output. >> > >> > 8,17 3 1 22.065944956 5489 D R 20973896 + 8 [cat] >> > >> > Using xfs_db, I dumped the inode for the same file and it shows the >> > following as its data extents. >> > >> > u.bmx[0] = [startoff,startblock,blockcount,extentflag] 0:[0,2621481,1,0] >> > >> > I understand that blktrace reports in 512-byte sectors while xfs_db in >> > filesystem block size (which is the default 4KB on my setup). >> > Converting blktrace offset to fs block = 2621737 which is close to the >> data >> > extent startblock (2621481), but still off by 256 fs blocks. >> > >> > Could someone please help understand the reason for this mismatch? >> > >> >> I believe you are comparing a raw read of a device to an internal XFS >> fsb, the latter of which is encoded to account for the internal >> structure of XFS (e.g., allocation groups). You might want to take a >> look at xfs_bmap on the file to see the actual disk blocks. >> >> The fsb to daddr conversion depends on the geometry of the fs, but you >> can get the various values with xfs_db as well. E.g.: >> >> convert fsb 2621481 agno # ag number >> convert fsb 2621481 agbno # relative ag block nr >> convert fsb 2621481 daddr # disk address >> >> Also, I'm not familiar enough with blktrace output off the top of my >> head so perhaps not an issue, but it's not clear to me whether the >> output above could have been converted/adjusted to a raw address based >> on a device partition. >> >> You might also want to verify you're looking at the actual file read vs. >> a directory/inode lookup or block mapping lookup or something else. I >> see you're running cat, a direct I/O read via dd might ensure you aren't >> just pulling file data from cache. >> >> Brian >> >> > Thanks, >> > Sushma >> >> > _______________________________________________ >> > xfs mailing list >> > xfs@oss.sgi.com >> > http://oss.sgi.com/mailman/listinfo/xfs >> >> > --089e0149c67a42aae705040edf99 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Please ignore my last comment. It doesn't make sense s= ince file system is mounted on a disk partition.

>= ;>Also, I'm not familiar enough with blktrace output off the top of = my
>>head so perhaps not an issue, but it's not clear= to me whether the
>>output above could have been convert= ed/adjusted to a raw address based
>>on a device partitio= n.

Yes, it appears that blktrace adds device partiti= on offset.


=
On Sat, Sep 27, 2014 at 8:40 AM, Sushma R <gsus= hma@gmail.com> wrote:
Thanks Brian.

I'm trying to understand how the internal XF= S structures affect this mapping (http://oss.sgi.com= /projects/xfs/papers/xfs_filesystem_structure.pdf)

=
xfs_bmap on the file matches that reported by extents in the file inod= e using xfs_db.

Other conversions under xfs_db
xfs_db> convert fsb 2621481 agno
0x0 (0)<= /div>
xfs_db> convert fsb 2621481 agbno
0x280029 (2621481)=
xfs_db> convert fsb 2621481 daddr
0x1400148 (209718= 48)

I tried dd command with directio option and still= blktrace reports the same raw block number as earlier.
8,17 =C2=A0 3 =C2=A0 =C2=A0 = =C2=A0 =C2=A01 =C2=A0 =C2=A0 0.000000000 =C2=A06999 =C2=A0D =C2=A0 R 209738= 96 + 1 [dd]

I= 'm using xfs_db with the partition i.e. "xfs_db -r /dev/sdb1"=
However, i= f I use it on the whole disk "xfs_db -r /dev/sdb", it gives the f= ollowing error
xfs_db: cannot init perag data (117)

Does this suggest something?

Thanks,
Sushma

On Sat, Sep 2= 7, 2014 at 7:38 AM, Brian Foster <bfoster@redhat.com> wrote= :
On Sat, Sep 27, 2014 at 12:32:21AM -0700, Sushma R wrote:
> Hi,
>
> I ran blktrace while reading a file on XFS partition and here's it= 's output.
>
> 8,17=C2=A0 =C2=A03=C2=A0 =C2=A0 =C2=A0 =C2=A0 1=C2=A0 =C2=A0 22.065944= 956=C2=A0 5489=C2=A0 D=C2=A0 =C2=A0R 20973896 + 8 [cat]
>
> Using xfs_db, I dumped the inode for the same file and it shows the > following as its data extents.
>
> u.bmx[0] =3D [startoff,startblock,blockcount,extentflag] 0:[0,2621481,= 1,0]
>
> I understand that blktrace reports in 512-byte sectors while xfs_db in=
> filesystem block size (which is the default 4KB on my setup).
> Converting blktrace offset to fs block =3D 2621737 which is close to t= he data
> extent startblock (2621481), but still off by 256 fs blocks.
>
> Could someone please help understand the reason for this mismatch?
>

I believe you are comparing a raw read of a device to an intern= al XFS
fsb, the latter of which is encoded to account for the internal
structure of XFS (e.g., allocation groups). You might want to take a
look at xfs_bmap on the file to see the actual disk blocks.

The fsb to daddr conversion depends on the geometry of the fs, but you
can get the various values with xfs_db as well. E.g.:

convert fsb 2621481 agno=C2=A0 =C2=A0 =C2=A0 =C2=A0 # ag number
convert fsb 2621481 agbno=C2=A0 =C2=A0 =C2=A0 =C2=A0# relative ag block nr<= br> convert fsb 2621481 daddr=C2=A0 =C2=A0 =C2=A0 =C2=A0# disk address

Also, I'm not familiar enough with blktrace output off the top of my head so perhaps not an issue, but it's not clear to me whether the
output above could have been converted/adjusted to a raw address based
on a device partition.

You might also want to verify you're looking at the actual file read vs= .
a directory/inode lookup or block mapping lookup or something else. I
see you're running cat, a direct I/O read via dd might ensure you aren&= #39;t
just pulling file data from cache.

Brian

> Thanks,
> Sushma

> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
>
= http://oss.sgi.com/mailman/listinfo/xfs



--089e0149c67a42aae705040edf99-- From MAILER-DAEMON Sat Sep 27 22:23:39 2014 Return-Path: <> X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id AEE777F86 for ; Sat, 27 Sep 2014 22:23:39 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9D7378F804C for ; Sat, 27 Sep 2014 20:23:39 -0700 (PDT) X-ASG-Debug-ID: 1411874613-04cbb073014a9c80001-NocioJ Received: from roukyou.gr.jp (aa2011100065d305ae72.userreverse.dion.ne.jp [211.5.174.114]) by cuda.sgi.com with SMTP id Zf2YMJsoIfpV5YjR for ; Sat, 27 Sep 2014 20:23:34 -0700 (PDT) X-Barracuda-Envelope-From: X-Barracuda-Apparent-Source-IP: 211.5.174.114 Received: (qmail 5612 invoked for bounce); 28 Sep 2014 12:21:20 +0900 Date: 28 Sep 2014 12:21:20 +0900 From: MAILER-DAEMON@roukyou.gr.jp To: xfs@oss.sgi.com Subject: failure notice X-Barracuda-Connect: aa2011100065d305ae72.userreverse.dion.ne.jp[211.5.174.114] X-Barracuda-Start-Time: 1411874613 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-ASG-Orig-Subj: failure notice X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 2.24 X-Barracuda-Spam-Status: No, SCORE=2.24 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=ANY_BOUNCE_MESSAGE, BOUNCE_MESSAGE, BSF_SC0_SA042a, EMPTY_ENV_FROM, MISSING_MID, NO_REAL_NAME X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9968 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.14 MISSING_MID Missing Message-Id: header 0.00 EMPTY_ENV_FROM Empty Envelope From Address 0.00 NO_REAL_NAME From: does not include a real name 2.10 BSF_SC0_SA042a Custom Rule SA042a 0.00 BOUNCE_MESSAGE MTA bounce message 0.00 ANY_BOUNCE_MESSAGE Message is some kind of bounce message Message-Id: <20140928032339.81FB71B8003@cuda.sgi.com> Hi. This is the qmail-send program at roukyou.gr.jp. I'm afraid I wasn't able to deliver your message to the following addresses. This is a permanent error; I've given up. Sorry it didn't work out. : 192.48.176.16 does not like recipient. Remote host said: 550 rejecting spoofed message Giving up on 192.48.176.16. --- Below this line is a copy of the message. Return-Path: Received: (qmail 32110 invoked by uid 0); 28 Sep 2014 12:19:39 +0900 Received: from unknown (HELO rku-sv01) (127.0.0.1) by localhost with SMTP; 28 Sep 2014 12:19:39 +0900 Received: from 91.143.41.148 (91.143.41.148) by rku-sv01 (F-Secure/virusgw_smtp/410/rku-sv01); Sun, 28 Sep 2014 12:05:15 +0900 (JST) X-Virus-Status: clean(F-Secure/virusgw_smtp/410/rku-sv01) Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="windows-1251" From: To: Subject: =?utf-8?B?0JrQu3XQtdC9bdGB0LrQuGUg0LHQsNC30Ysg0YJl0LsgKzc5SdCXMzls0Jc40Lc3?= Êëuåímñêèe áàçû òeë +79IÇ39lÇ8ç7 From root@krios.tbi.univie.ac.at Sat Sep 27 23:25:11 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 98AA57F88 for ; Sat, 27 Sep 2014 23:25:11 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 43F88AC001 for ; Sat, 27 Sep 2014 21:25:07 -0700 (PDT) X-ASG-Debug-ID: 1411878305-04bdf003a2453f30001-NocioJ Received: from krios.tbi.univie.ac.at (krios.tbi.univie.ac.at [131.130.44.60]) by cuda.sgi.com with ESMTP id akyc3pXSF5KL2lDP for ; Sat, 27 Sep 2014 21:25:06 -0700 (PDT) X-Barracuda-Envelope-From: root@krios.tbi.univie.ac.at X-Barracuda-Apparent-Source-IP: 131.130.44.60 Received: by krios.tbi.univie.ac.at (Postfix) id 10E205F1DD; Sun, 28 Sep 2014 06:25:03 +0200 (CEST) Delivered-To: root@krios.tbi.univie.ac.at Received: by krios.tbi.univie.ac.at (Postfix, from userid 0) id 01DE05F20A; Sun, 28 Sep 2014 06:25:02 +0200 (CEST) From: root@krios.tbi.univie.ac.at (Cron Daemon) To: root@krios.tbi.univie.ac.at Subject: Cron test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) Content-Type: text/plain; charset=UTF-8 X-ASG-Orig-Subj: Cron test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) X-Cron-Env: X-Cron-Env: X-Cron-Env: X-Cron-Env: Message-Id: <20140928042503.01DE05F20A@krios.tbi.univie.ac.at> Date: Sun, 28 Sep 2014 06:25:02 +0200 (CEST) X-Barracuda-Connect: krios.tbi.univie.ac.at[131.130.44.60] X-Barracuda-Start-Time: 1411878305 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.70 X-Barracuda-Spam-Status: No, SCORE=0.70 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, BSF_SC0_SA_TO_FROM_ADDR_MATCH, PR0N_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.9970 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.20 PR0N_SUBJECT Subject has letters around special characters (pr0n) 0.50 BSF_SC0_SA_TO_FROM_ADDR_MATCH Sender Address Matches Recipient Address /etc/cron.daily/logrotate: error: error opening /home/git/gitlab/log/application.log: Permission denied error: error opening /home/git/gitlab/log/githost.log: Permission denied error: error opening /home/git/gitlab/log/production.log: Permission denied error: error opening /home/git/gitlab/log/satellites.log: Permission denied error: error opening /home/git/gitlab/log/sidekiq.log: Permission denied error: error opening /home/git/gitlab/log/unicorn.stderr.log: Permission denied error: error opening /home/git/gitlab/log/unicorn.stdout.log: Permission denied error: error opening /home/git/gitlab-shell/gitlab-shell.log: Permission denied run-parts: /etc/cron.daily/logrotate exited with return code 1 From dgc@oss.sgi.com Sun Sep 28 19:02:59 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=NO_RELAYS autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: by oss.sgi.com (Postfix, from userid 10266) id 150717F84; Sun, 28 Sep 2014 19:02:59 -0500 (CDT) From: xfs@oss.sgi.com To: xfs@oss.sgi.com Subject: [XFS updates] XFS development tree branch, xfs-trans-recover-cleanup, created. v3.16-11801-gb818cca X-Git-Refname: refs/heads/xfs-trans-recover-cleanup X-Git-Reftype: branch X-Git-Oldrev: 0000000000000000000000000000000000000000 X-Git-Newrev: b818cca1976d1a01754033ac08724e05d07cce8f Message-Id: <20140929000259.150717F84@oss.sgi.com> Date: Sun, 28 Sep 2014 19:02:57 -0500 (CDT) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "XFS development tree". The branch, xfs-trans-recover-cleanup has been created at b818cca1976d1a01754033ac08724e05d07cce8f (commit) - Log ----------------------------------------------------------------- commit b818cca1976d1a01754033ac08724e05d07cce8f Author: Dave Chinner Date: Mon Sep 29 09:45:54 2014 +1000 xfs: refactor recovery transaction start handling Rework the transaction lookup and allocation code in xlog_recovery_process_ophdr() to fold two related call-once helper functions into a single helper. Then fold in all the XLOG_START_TRANS logic to that helper to clean up the remaining logic in xlog_recovery_process_ophdr(). Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit 76560669868d3b4d650d91d9bf467a8d81171766 Author: Dave Chinner Date: Mon Sep 29 09:45:42 2014 +1000 xfs: reorganise transaction recovery item code The code for managing transactions anf the items for recovery is spread across 3 different locations in the file. Move them all together so that it is easy to read the code without needing to jump long distances in the file. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit 88b863db97a18a04c90ebd57d84e1b7863114dcb Author: Dave Chinner Date: Mon Sep 29 09:45:32 2014 +1000 xfs: fix double free in xlog_recover_commit_trans When an error occurs during buffer submission in xlog_recover_commit_trans(), we free the trans structure twice. Fix it by only freeing the structure in the caller regardless of the success or failure of the function. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit e9131e50f9d0a632e3011d73f283ba69be0cc682 Author: Dave Chinner Date: Mon Sep 29 09:45:18 2014 +1000 xfs: recovery of XLOG_UNMOUNT_TRANS leaks memory The XLOG_UNMOUNT_TRANS case skips the transaction, despite the fact an unmount record is always in a standalone transaction. Hence whenever we come across one of these we need to free the transaction structure associated with it as there is no commit record that follows it. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit eeb1168810d8a140f6834f8c4975f7bb3277d790 Author: Dave Chinner Date: Mon Sep 29 09:45:03 2014 +1000 xfs: refactor xlog_recover_process_data() Clean up xlog_recover_process_data() structure in preparation for fixing the allocation and freeing context of the transaction being recovered. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner ----------------------------------------------------------------------- hooks/post-receive -- XFS development tree From dgc@oss.sgi.com Sun Sep 28 19:03:14 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=NO_RELAYS autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: by oss.sgi.com (Postfix, from userid 10266) id 2D6447F92; Sun, 28 Sep 2014 19:03:14 -0500 (CDT) From: xfs@oss.sgi.com To: xfs@oss.sgi.com Subject: [XFS updates] XFS development tree branch, for-next, updated. xfs-for-linus-3.17-rc3-33-g2f43bbd X-Git-Refname: refs/heads/for-next X-Git-Reftype: branch X-Git-Oldrev: 33044dc408e6e6bb7f270c0a2e12598ef5592987 X-Git-Newrev: 2f43bbd96e43d0b85803f5092be94bbb92d8eac9 Message-Id: <20140929000314.2D6447F92@oss.sgi.com> Date: Sun, 28 Sep 2014 19:03:13 -0500 (CDT) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "XFS development tree". The branch, for-next has been updated 2f43bbd Merge branch 'xfs-trans-recover-cleanup' into for-next b818cca xfs: refactor recovery transaction start handling 7656066 xfs: reorganise transaction recovery item code 88b863d xfs: fix double free in xlog_recover_commit_trans e9131e5 xfs: recovery of XLOG_UNMOUNT_TRANS leaks memory eeb1168 xfs: refactor xlog_recover_process_data() from 33044dc408e6e6bb7f270c0a2e12598ef5592987 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2f43bbd96e43d0b85803f5092be94bbb92d8eac9 Merge: 33044dc b818cca Author: Dave Chinner Date: Mon Sep 29 10:00:24 2014 +1000 Merge branch 'xfs-trans-recover-cleanup' into for-next ----------------------------------------------------------------------- Summary of changes: fs/xfs/xfs_log_recover.c | 564 ++++++++++++++++++++++++++--------------------- 1 file changed, 308 insertions(+), 256 deletions(-) hooks/post-receive -- XFS development tree From dgc@oss.sgi.com Sun Sep 28 20:01:15 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=NO_RELAYS autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: by oss.sgi.com (Postfix, from userid 10266) id 084977FA7; Sun, 28 Sep 2014 20:01:15 -0500 (CDT) From: xfs@oss.sgi.com To: xfs@oss.sgi.com Subject: [XFS updates] XFS development tree branch, xfs-sparse-fixes, created. v3.16-11811-gb972d07 X-Git-Refname: refs/heads/xfs-sparse-fixes X-Git-Reftype: branch X-Git-Oldrev: 0000000000000000000000000000000000000000 X-Git-Newrev: b972d0797180d8414351d9dc8ff65071c692d058 Message-Id: <20140929010115.084977FA7@oss.sgi.com> Date: Sun, 28 Sep 2014 20:01:14 -0500 (CDT) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "XFS development tree". The branch, xfs-sparse-fixes has been created at b972d0797180d8414351d9dc8ff65071c692d058 (commit) - Log ----------------------------------------------------------------- commit b972d0797180d8414351d9dc8ff65071c692d058 Author: Dave Chinner Date: Mon Sep 29 10:46:22 2014 +1000 xfs: annotate user variables passed as void Some argument callbacks can contain user buffers, and sparse warns about passing them as void pointers. Cast appropriately to remove the sparse warnings. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit e3aed1a08190c038c4ea41b73ea6f07bc0e3290c Author: Dave Chinner Date: Mon Sep 29 10:46:08 2014 +1000 xfs: xfs_kset should be static As it is accessed through the struct xfs_mount and can be set up entirely from fs/xfs/xfs_super.c Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit bf1ed3833078e3bb0ba8cd03468090b9359d0912 Author: Dave Chinner Date: Mon Sep 29 10:43:40 2014 +1000 xfs: xfs_qm_dquot_isolate needs locking annotations for sparse To remove noise from the build. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner commit e68ed77521f695d165cbae070f6dda8a4778438f Author: Dave Chinner Date: Mon Sep 29 10:43:15 2014 +1000 xfs: fix use of agi_newino in finobt lookup Sparse warns that we are passing the big-endian valueo f agi_newino to the initial btree lookup function when trying to find a new inode. This is wrong - we need to pass the host order value, not the disk order value. This will adversely affect the next inode allocated, but given that the free inode btree is usually much smaller than the allocated inode btree it is much less likely to be a performance issue if we start the search in the wrong place. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner ----------------------------------------------------------------------- hooks/post-receive -- XFS development tree From dgc@oss.sgi.com Sun Sep 28 20:01:35 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=NO_RELAYS autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: by oss.sgi.com (Postfix, from userid 10266) id 7497C7FB0; Sun, 28 Sep 2014 20:01:35 -0500 (CDT) From: xfs@oss.sgi.com To: xfs@oss.sgi.com Subject: [XFS updates] XFS development tree branch, for-next, updated. xfs-for-linus-3.17-rc3-38-gbd438f8 X-Git-Refname: refs/heads/for-next X-Git-Reftype: branch X-Git-Oldrev: 2f43bbd96e43d0b85803f5092be94bbb92d8eac9 X-Git-Newrev: bd438f825f7badafe56d117ed906488c8541f95f Message-Id: <20140929010135.7497C7FB0@oss.sgi.com> Date: Sun, 28 Sep 2014 20:01:35 -0500 (CDT) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "XFS development tree". The branch, for-next has been updated bd438f8 Merge branch 'xfs-sparse-fixes' into for-next b972d07 xfs: annotate user variables passed as void e3aed1a xfs: xfs_kset should be static bf1ed38 xfs: xfs_qm_dquot_isolate needs locking annotations for sparse e68ed77 xfs: fix use of agi_newino in finobt lookup from 2f43bbd96e43d0b85803f5092be94bbb92d8eac9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bd438f825f7badafe56d117ed906488c8541f95f Merge: 2f43bbd b972d07 Author: Dave Chinner Date: Mon Sep 29 10:52:44 2014 +1000 Merge branch 'xfs-sparse-fixes' into for-next ----------------------------------------------------------------------- Summary of changes: fs/xfs/libxfs/xfs_ialloc.c | 5 ++--- fs/xfs/xfs_ioctl.c | 8 ++++---- fs/xfs/xfs_mount.c | 3 --- fs/xfs/xfs_qm.c | 1 + fs/xfs/xfs_super.c | 3 ++- 5 files changed, 9 insertions(+), 11 deletions(-) hooks/post-receive -- XFS development tree From dave@fromorbit.com Sun Sep 28 20:41:47 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 88B427FBA for ; Sun, 28 Sep 2014 20:41:45 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 77259304032 for ; Sun, 28 Sep 2014 18:41:42 -0700 (PDT) X-ASG-Debug-ID: 1411954896-04cb6c50e54981c0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id nECE9PsMhVGk9Fgg for ; Sun, 28 Sep 2014 18:41:37 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtIWAMW3KFR5LHimPGdsb2JhbABggw6IYq5+BpxJFwEGAQEBATg5hDEvOxhqAwctiD2aKqUMhhKJKIEBhDUFqWiLByCBaysvgQaBRAEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 29 Sep 2014 11:11:27 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XYPxu-0000rQ-3F for xfs@oss.sgi.com; Mon, 29 Sep 2014 11:41:26 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XYPxu-0003BO-25 for xfs@oss.sgi.com; Mon, 29 Sep 2014 11:41:26 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH] xfs: compat_xfs_bstat does not have forkoff Date: Mon, 29 Sep 2014 11:41:26 +1000 X-ASG-Orig-Subj: [PATCH] xfs: compat_xfs_bstat does not have forkoff Message-Id: <1411954886-12200-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411954896 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10003 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner struct compat_xfs_bstat is missing the di_forkoff field and so does not fully translate the structure correctly. Fix it. Signed-off-by: Dave Chinner --- fs/xfs/xfs_ioctl32.c | 2 ++ fs/xfs/xfs_ioctl32.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c index a554646..94ce027 100644 --- a/fs/xfs/xfs_ioctl32.c +++ b/fs/xfs/xfs_ioctl32.c @@ -160,6 +160,7 @@ xfs_ioctl32_bstat_copyin( get_user(bstat->bs_gen, &bstat32->bs_gen) || get_user(bstat->bs_projid_lo, &bstat32->bs_projid_lo) || get_user(bstat->bs_projid_hi, &bstat32->bs_projid_hi) || + get_user(bstat->bs_forkoff, &bstat32->bs_forkoff) || get_user(bstat->bs_dmevmask, &bstat32->bs_dmevmask) || get_user(bstat->bs_dmstate, &bstat32->bs_dmstate) || get_user(bstat->bs_aextents, &bstat32->bs_aextents)) @@ -214,6 +215,7 @@ xfs_bulkstat_one_fmt_compat( put_user(buffer->bs_gen, &p32->bs_gen) || put_user(buffer->bs_projid, &p32->bs_projid) || put_user(buffer->bs_projid_hi, &p32->bs_projid_hi) || + put_user(buffer->bs_forkoff, &p32->bs_forkoff) || put_user(buffer->bs_dmevmask, &p32->bs_dmevmask) || put_user(buffer->bs_dmstate, &p32->bs_dmstate) || put_user(buffer->bs_aextents, &p32->bs_aextents)) diff --git a/fs/xfs/xfs_ioctl32.h b/fs/xfs/xfs_ioctl32.h index 80f4060..b1bb454 100644 --- a/fs/xfs/xfs_ioctl32.h +++ b/fs/xfs/xfs_ioctl32.h @@ -67,8 +67,9 @@ typedef struct compat_xfs_bstat { __u32 bs_gen; /* generation count */ __u16 bs_projid_lo; /* lower part of project id */ #define bs_projid bs_projid_lo /* (previously just bs_projid) */ + __u16 bs_forkoff; /* inode fork offset in bytes */ __u16 bs_projid_hi; /* high part of project id */ - unsigned char bs_pad[12]; /* pad space, unused */ + unsigned char bs_pad[10]; /* pad space, unused */ __u32 bs_dmevmask; /* DMIG event mask */ __u16 bs_dmstate; /* DMIG state info */ __u16 bs_aextents; /* attribute number of extents */ -- 2.0.0 From dave@fromorbit.com Sun Sep 28 20:42:05 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C6A107F51 for ; Sun, 28 Sep 2014 20:42:05 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 72373AC007 for ; Sun, 28 Sep 2014 18:42:05 -0700 (PDT) X-ASG-Debug-ID: 1411954923-04bdf003a251e450001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id 0pA2IqNhnfxHfo1j for ; Sun, 28 Sep 2014 18:42:03 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtYWAMW3KFR5LHimPGdsb2JhbABggw6IYq5+BptJgQAXAQYBAQEBODmEMS87GGoDBy2IPZoqpQyGEooBhF0FhiiLFaU9Ky+CSgEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 29 Sep 2014 11:11:52 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XYPyJ-0000rX-MG for xfs@oss.sgi.com; Mon, 29 Sep 2014 11:41:51 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XYPyJ-0003Ce-L0 for xfs@oss.sgi.com; Mon, 29 Sep 2014 11:41:51 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH] xfs: kill time.h Date: Mon, 29 Sep 2014 11:41:51 +1000 X-ASG-Orig-Subj: [PATCH] xfs: kill time.h Message-Id: <1411954911-12278-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411954923 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10003 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner The typedef for timespecs and nanotime() are completely unnecessary, and delay() can be moved to fs/xfs/linux.h, which means this file can go away. Signed-off-by: Dave Chinner --- fs/xfs/kmem.c | 1 - fs/xfs/time.h | 36 ------------------------------------ fs/xfs/xfs_inode.c | 4 ++-- fs/xfs/xfs_linux.h | 6 +++++- fs/xfs/xfs_trans_inode.c | 2 +- 5 files changed, 8 insertions(+), 41 deletions(-) delete mode 100644 fs/xfs/time.h diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c index 844e288..53e95b2 100644 --- a/fs/xfs/kmem.c +++ b/fs/xfs/kmem.c @@ -21,7 +21,6 @@ #include #include #include -#include "time.h" #include "kmem.h" #include "xfs_message.h" diff --git a/fs/xfs/time.h b/fs/xfs/time.h deleted file mode 100644 index 387e695..0000000 --- a/fs/xfs/time.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program 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. - * - * This program is distributed in the hope that it would 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 this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_SUPPORT_TIME_H__ -#define __XFS_SUPPORT_TIME_H__ - -#include -#include - -typedef struct timespec timespec_t; - -static inline void delay(long ticks) -{ - schedule_timeout_uninterruptible(ticks); -} - -static inline void nanotime(struct timespec *tvp) -{ - *tvp = CURRENT_TIME; -} - -#endif /* __XFS_SUPPORT_TIME_H__ */ diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index e5bbc1f..f07b443 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -654,7 +654,7 @@ xfs_ialloc( xfs_inode_t *ip; uint flags; int error; - timespec_t tv; + struct timespec tv; /* * Call the space management code to pick @@ -720,7 +720,7 @@ xfs_ialloc( ip->i_d.di_nextents = 0; ASSERT(ip->i_d.di_nblocks == 0); - nanotime(&tv); + tv = current_fs_time(mp->m_super); ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec; ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec; ip->i_d.di_atime = ip->i_d.di_mtime; diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h index d10dc8f..6a51619 100644 --- a/fs/xfs/xfs_linux.h +++ b/fs/xfs/xfs_linux.h @@ -56,7 +56,6 @@ typedef __uint64_t __psunsigned_t; #include "kmem.h" #include "mrlock.h" -#include "time.h" #include "uuid.h" #include @@ -179,6 +178,11 @@ typedef __uint64_t __psunsigned_t; #define MAX(a,b) (max(a,b)) #define howmany(x, y) (((x)+((y)-1))/(y)) +static inline void delay(long ticks) +{ + schedule_timeout_uninterruptible(ticks); +} + /* * XFS wrapper structure for sysfs support. It depends on external data * structures and is embedded in various internal data structures to implement diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index 50c3f56..cdb4d86 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.c @@ -70,7 +70,7 @@ xfs_trans_ichgtime( int flags) { struct inode *inode = VFS_I(ip); - timespec_t tv; + struct timespec tv; ASSERT(tp); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); -- 2.0.0 From david@fromorbit.com Sun Sep 28 22:32:54 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id CC99A7FCB for ; Sun, 28 Sep 2014 22:32:54 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id BB23E304032 for ; Sun, 28 Sep 2014 20:32:51 -0700 (PDT) X-ASG-Debug-ID: 1411961566-04cbb0730258eac0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id urg40SXqCY4iEwY8 for ; Sun, 28 Sep 2014 20:32:46 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Aus8AI7RKFR5LHimPGdsb2JhbABggw6IYq8VBpVYhWsCAgEBAoEDFwEGAQEBATg5hAQBAQQ6HCMQCAMOCgklDwUlAwcaE4g9vycYGIV6igwHhEsFnSeXfoFVKy+CSgEBAQ Received: from ppp121-44-120-166.lns20.syd6.internode.on.net (HELO dastard) ([121.44.120.166]) by ipmail04.adl6.internode.on.net with ESMTP; 29 Sep 2014 13:02:45 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XYRhc-00014I-8D; Mon, 29 Sep 2014 13:32:44 +1000 Date: Mon, 29 Sep 2014 13:32:44 +1000 From: Dave Chinner To: Brian Foster Cc: fstests@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH] xfs/053: test for stale data exposure via falloc/writeback interaction Message-ID: <20140929033244.GL4758@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs/053: test for stale data exposure via falloc/writeback interaction References: <1411756349-4537-1-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411756349-4537-1-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1411961566 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10007 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 26, 2014 at 02:32:29PM -0400, Brian Foster wrote: > XFS buffered I/O writeback has a subtle race condition that leads to > stale data exposure if the filesystem happens to crash after delayed > allocation blocks are converted on disk and before data is written back > to said blocks. > > Use file allocation commands to attempt to reproduce a related, but > slightly different variant of this problem. The associated falloc > commands can lead to partial writeback that converts an extent larger > than the range affected by falloc. If the filesystem crashes after the > extent conversion but before all other cached data is written to the > extent, stale data can be exposed. > > Signed-off-by: Brian Foster > --- > > This fell out of a combination of a conversation with Dave about XFS > writeback and buffer/cache coherency and some hacking I'm doing on the > XFS zero range implementation. Note that fpunch currently fails the > test. Also, this test is XFS specific primarily due to the use of > godown. ..... > +_crashtest() > +{ > + cmd=$1 > + img=$SCRATCH_MNT/$seq.img > + mnt=$SCRATCH_MNT/$seq.mnt > + file=$mnt/file > + > + # Create an fs on a small, initialized image. The pattern is written to > + # the image to detect stale data exposure. > + $XFS_IO_PROG -f -c "truncate 0" -c "pwrite 0 25M" $img \ > + >> $seqres.full 2>&1 > + $MKFS_XFS_PROG $MKFS_OPTIONS $img >> $seqres.full 2>&1 > + > + mkdir -p $mnt > + mount $img $mnt > + > + echo $cmd > + > + # write, run the test command and shutdown the fs > + $XFS_IO_PROG -f -c "pwrite -S 1 0 64k" -c "$cmd 60k 4k" $file | \ > + _filter_xfs_io So at this point the file is correctly 64k in size in memory. > + ./src/godown -f $mnt And here you tell godown to flush the log, so if there's a transaction in the that sets the inode size to 64k. > + umount $mnt > + mount $img $mnt Then log recovery will set the file size to 64k, and: > + > + # we generally expect a zero-sized file (this should be silent) > + hexdump $file This comment is not actually correct. I'm actually seeing 64k length files after recovery in 2 of 3 cases being tested, so I don't think this is a correct observation. Some clarification of what is actually being tested is needed here. Cheers, Dave. -- Dave Chinner david@fromorbit.com From boycha@tannoy.com Mon Sep 29 00:01:42 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.2 required=5.0 tests=HTML_MESSAGE,MIME_HTML_ONLY autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id BFCC07FD3 for ; Mon, 29 Sep 2014 00:01:42 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9F07F8F8040 for ; Sun, 28 Sep 2014 22:01:39 -0700 (PDT) X-ASG-Debug-ID: 1411966896-04cbb07301599c00001-NocioJ Received: from mx.zircon.net.ua (mx.zircon.net.ua [82.207.71.162]) by cuda.sgi.com with ESMTP id 2xjH5ECH7uSIigQw for ; Sun, 28 Sep 2014 22:01:37 -0700 (PDT) X-Barracuda-Envelope-From: boycha@tannoy.com X-Barracuda-Apparent-Source-IP: 82.207.71.162 Received: from assigned-81.0.240-113.casablanca.cz (c-217-115-50-229.cust.bredband2.com [217.115.50.229]) by mx.zircon.net.ua (Postfix) with ESMTPA id C44054266E; Mon, 29 Sep 2014 08:01:33 +0300 (EEST) Message-ID: From: =?windows-1251?Q?=CD=E0=F7=E0=EB=FC=ED=E8=EA_=EF=EB=E0=ED?= =?windows-1251?Q?=EE=E2=EE-=EF=F0=EE=E8=E7=E2=EE=E4=F1=F2?= =?windows-1251?Q?=E2=E5=ED=ED=EE=E3=EE_=EE=F2=E4=E5=EB=E0?= To: , , , Subject: =?windows-1251?Q?=CD=E5=F2_=E4=EE=EB=E3=EE=F1=F2=F0=EE=FE?= =?windows-1251?Q?!?= Date: Mon, 29 Sep 2014 07:01:31 +0200 X-ASG-Orig-Subj: =?windows-1251?Q?=CD=E5=F2_=E4=EE=EB=E3=EE=F1=F2=F0=EE=FE?= =?windows-1251?Q?!?= MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_14B7_01CFDBB3.330888E0" X-Priority: 3 X-Barracuda-Connect: mx.zircon.net.ua[82.207.71.162] X-Barracuda-Start-Time: 1411966897 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_TG035a, HTML_MESSAGE, MIME_HTML_ONLY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10009 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 BSF_SC0_TG035a Message contains invalid style definition This is a multi-part message in MIME format. ------=_NextPart_000_14B7_01CFDBB3.330888E0 Content-Type: text/html; charset="windows-1251" Content-Transfer-Encoding: base64 PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwv L0VOIj4NCjxIVE1MIHhtbG5zOm8gPSAidXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6 b2ZmaWNlIj48SEVBRD4NCjxNRVRBIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD13aW5kb3dz LTEyNTEiIGh0dHAtZXF1aXY9Q29udGVudC1UeXBlPg0KPE1FVEEgbmFtZT1HRU5FUkFUT1IgY29u dGVudD0iTVNIVE1MIDExLjAwLjk2MDAuMTcxMDUiPg0KPFNUWUxFPjwvU1RZTEU+DQo8L0hFQUQ+ DQo8Qk9EWSBiZ0NvbG9yPSNmZmZmZmY+DQo8RElWPsTl6fHy4uj/IO/uIO707vDs6+Xt6P4g4uLu 5OAg4iD96vHv6/Pg8uD26P4g7u/w5eTl6+Xt+yDx8i4gNTUgDQrD8ODk7vHy8O7o8uXr/O3u4+4g 6u7k5erx4Cwgwuzl8fLlIPEg8uXsIPD/5CDv8ODq8uj35fHq6PUg4u7v8O7x7uIg5+Dy8ODj6OLg /vLx/yANCuIg8ezl5u379SDn4Oru7e7k4PLl6/zt+/UgPEJSPuDq8uD1IOgg8PPq7uLu5P/56PUg 5O7q8+zl7fLg9SDy5fDw6PLu8Ojg6/zt+/UgDQru8OPg7e7iIPHy8O7o8uXr/O3u4+4g7eDk5+7w 4C4gPC9ESVY+DQo8RElWPiZuYnNwOzwvRElWPg0KPERJVj7CIDIwMTQg4y4g4/Dg5O7x8vDu6PLl 6/zt++kg6u7k5erxIO/u6/P36Osg8P/kIPHz+eXx8uLl7e379SDk7u/u6+3l7ejpLCDiIA0K8eL/ 5+gg8SD35ewg7/Do4+vg+ODl7CDx7+X26ODr6PHy7uIg7eAg7uHz9+D++ejpIOrz8PEg4iDR4O3q 8i3P5fLl8OHz8OPlLCANCu/u8eL/+eXt7fvpIPHr7ubt++wg4u7v8O7x4Owg4iDu4evg8fLoIPHk 4PfoIO7h+uXq8uAg6uDv6PLl6/zt7uPuIA0K8fLw7ujy5ev88fLi4C48L0RJVj4NCjxESVY+Jm5i c3A7PC9ESVY+DQo8RElWPs/QyMPLwNjFzcjFIMLbIM3AycSo0sUgws4gwsvOxsXNyMghPC9ESVY+ DQo8RElWPiZuYnNwOzwvRElWPg0KPERJVj7S5evl9O7tIOTr/yDx4v/n6DogIDggICAgeyAg6u7k X8/o8uXw4CAgfSA5OCAgNiAgID0gIDkzIC4gIPc3PC9ESVY+DQo8RElWPiZuYnNwOzwvRElWPg0K PERJVj7C7ejs4O3o/iDx7+X26ODr6PHy7uIhIMIg8ODs6uD1IPHl7Ojt4PDgIOLu5+zu5u3uIO/u 6/P35e3o5SDo7eTo4ujk8+Dr/O379SANCuru7fHz6/zy4Pbo6SDv7iDv8Ojq6+Dk7fvsIOLu7/Du 8eDsLjxCUj48L0RJVj48L0JPRFk+PC9IVE1MPg0K ------=_NextPart_000_14B7_01CFDBB3.330888E0 Content-Type: application/msword; name="PRIGLASHENIE.doc" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="PRIGLASHENIE.doc" 0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAAAAAAACAAAAlQAAAAAAAAAA EAAAlwAAAAEAAAD+////AAAAAJMAAACUAAAA//////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////s pcEAX8AZBAAA+BK/AAAAAAAAEAAAAAAACAAAtiAAAA4AYmpiagAVABUAAAAAAAAAAAAAAAAAAAAA AAAZBBYA+bsAAGJ/AABifwAAQQYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//w8AAAAA AAAAAAD//w8AAAAAAAAAAAD//w8AAAAAAAAAAAAAAAAAAAAAALcAAAAAAJ4FAAAAAAAAngUAABcT AAAAAAAAFxMAAAAAAAAXEwAAAAAAABcTAAAAAAAAFxMAABQAAAAAAAAAAAAAAP////8AAAAAKxMA AAAAAAArEwAAAAAAACsTAAAAAAAAKxMAACwAAABXEwAAHAAAACsTAAAAAAAAMRkAAGgBAABzEwAA AAAAAHMTAAAAAAAAcxMAAAAAAABzEwAAAAAAAHMTAAAAAAAAGhYAAAAAAAAaFgAAAAAAABoWAAAA AAAAmBgAAAIAAACaGAAAAAAAAJoYAAAAAAAAmhgAAAAAAACaGAAAAAAAAJoYAAAAAAAAmhgAACQA AACZGgAAsgIAAEsdAAA+AAAAvhgAAC0AAAAAAAAAAAAAAAAAAAAAAAAAFxMAAAAAAAAaFgAAAAAA AAAAAAAAAAAAAAAAAAAAAADaFQAAQAAAABoWAAAAAAAAGhYAAAAAAAAaFgAAAAAAAL4YAAAAAAAA AAAAAAAAAAAXEwAAAAAAABcTAAAAAAAAcxMAAAAAAAAAAAAAAAAAAHMTAABnAgAA6xgAABYAAADk FgAAAAAAAOQWAAAAAAAA5BYAAAAAAAAaFgAAFgAAABcTAAAAAAAAcxMAAAAAAAAXEwAAAAAAAHMT AAAAAAAAmBgAAAAAAAAAAAAAAAAAAOQWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYAAAAAAACYGAAAAAAAAAAAAAAAAAAA5BYAAAAAAAAAAAAA AAAAAOQWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5BYAAAAAAABzEwAAAAAAAP////8AAAAAMNXb30vb zwEAAAAAAAAAAP////8AAAAAMBYAAC4AAADkFgAAAAAAAAAAAAAAAAAAhBgAABQAAAABGQAAMAAA ADEZAAAAAAAA5BYAAAAAAACJHQAAAAAAAF4WAABMAAAAiR0AAAAAAADkFgAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAIkdAAAAAAAAAAAAAAAAAAAXEwAAAAAAAOQWAACgAQAAGhYAAAAAAAAaFgAAAAAAAOQW AAAAAAAAGhYAAAAAAAAaFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYA AAAAAAAaFgAAAAAAABoWAAAAAAAAvhgAAAAAAAC+GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAqhYAADoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoWAAAA AAAAGhYAAAAAAAAaFgAAAAAAADEZAAAAAAAAGhYAAAAAAAAaFgAAAAAAABoWAAAAAAAAGhYAAAAA AAAAAAAAAAAAAP////8AAAAA/////wAAAAD/////AAAAAAAAAAAAAAAA/////wAAAAD/////AAAA AP////8AAAAA/////wAAAAD/////AAAAAP////8AAAAA/////wAAAAD/////AAAAAP////8AAAAA /////wAAAAD/////AAAAAP////8AAAAA/////wAAAAD/////AAAAAIkdAAAAAAAAGhYAAAAAAAAa FgAAAAAAABoWAAAAAAAAGhYAAAAAAAAaFgAAAAAAABoWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaFgAAAAAAABoWAAAAAAAAGhYA AAAAAACeBQAAPwwAAN0RAAA6AQAABQASAQAAGQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEABwAH AA0AMwQuACAAIQQwBD0EOgRCBC0AHwQ1BEIENQRABDEEQwRABDMEDQAmBDUEPQRCBEAEIAAaBEAE MARCBDoEPgRBBEAEPgRHBD0ESwRFBCAAHwRABD4EMwRABDAEPAQ8BCAAHgQxBEMERwQ1BD0EOARP BA0AIgQ1BDsEXABEBDAEOgRBBCAAKAA4ADEAMgApACAAOQA4ADYAIAA5ADMAIAA0ADcADQAYBEEE RQQWIV8AXwBfAF8AXwBfAF8AXwAyADcAMQBfAF8AXwBfAF8AXwBfAF8AXwBfAF8AXwBfAA0AHgRC BCAAXwBfAF8AXwBfAF8AMgA5AC4AMAA5AC4AMgAwADEANABfAF8AXwBfAF8AXwBfAF8AXwBfAF8A XwBfAA0ABwAHAA0AEgQgAE4EQAQ4BDQEOARHBDUEQQQ6BDgEOQQgADQENQQ/BDAEQARCBDAEPAQ1 BD0EQgQNAA0AIQQ/BDUERgQ4BDAEOwQ4BEEEQgRDBCAAPwQ+BCAAPgREBD4EQAQ8BDsENQQ9BDgE TgQgAD0ENQQ0BDIEOAQ2BDgEPAQ+BEEEQgQ4BA0ADQAjBD8EQAQwBDIEOwQ1BD0EOAQ1BCAAOgQw BD8EOARCBDAEOwRMBD0EPgQzBD4EIABBBEIEQAQ+BDgEQgQ1BDsETARBBEIEMgQwBA0ADQANAA0A DQANABgEPQREBD4EQAQ8BDAERgQ4BE8EIAA0BDsETwQgAEEEPwQ1BEYEOAQwBDsEOARBBEIEPgQy BCAAOAQ9BDIENQRBBEIEOARGBDgEPgQ9BD0EPgQtAEEEQgRABD4EOARCBDUEOwRMBD0EPgQzBD4E IABBBDUEOgRCBD4EQAQwBCwAIABOBEAEOARBBEIEPgQyBCwAIAAzBDsEMAQyBD0ESwRFBCAAOAQ9 BDYENQQ9BDUEQAQ+BDIEOgANAA0AEgQyBD4ENAQgAD4EMQRKBDUEOgRCBDAEIAAyBCAATQQ6BEEE PwQ7BEMEMARCBDAERgQ4BE4EOgANACAEMAQ3BEAENQRIBDUEPQQ4BDUEIAA9BDAEIAAyBDIEPgQ0 BCwAIAA/BEAEOAQ1BDwEPgQtAEEENAQwBEIEPgRHBD0EMARPBCAANAQ+BDoEQwQ8BDUEPQRCBDAE RgQ4BE8ELAAgAD8EQwRBBDoEPgQ9BDAEOwQwBDQEPgRHBD0ESwQ1BCAAQAQwBDEEPgRCBEsEDQAf BEAEMAQyBD4EMgRLBDUEIAAwBEEEPwQ1BDoEQgRLBA0ADQAhBDUEPAQ4BD0EMARABCAAQQQgAEME RwQwBEEEQgQ4BDUEPAQgAEEEPwQ1BEYEOAQwBDsEOARBBEIEPgQyBCAAPwRABD4ERAQ4BDsETAQ9 BEsERQQgAEEEOwRDBDYEMQQgAD8EPgRBBDIETwRJBDUEPQQgAD0EPgRABDwEMARCBDgEMgQ9BD4E PARDBCAAQAQ1BDMEQwQ7BDgEQAQ+BDIEMAQ9BDgETgQgADcEMAQ6BDsETgRHBDgEQgQ1BDsETAQ9 BD4EOQQgAEEEQgQwBDQEOAQ4BCAAQQRCBEAEPgQ4BEIENQQ7BEwEQQRCBDIEMAQ6ACAAPwQ+BDsE QwRHBDUEPQQ4BE4EIABABDAENwRABDUESAQ1BD0EOARPBCAAPQQwBCAAMgQyBD4ENAQgADIEIABN BDoEQQQ/BDsEQwQwBEIEMARGBDgETgQgAD4EMQRKBDUEOgRCBDAEIAA6BDAEPwQ4BEIEMAQ7BEwE PQQ+BCAAQQRCBEAEPgQ4BEIENQQ7BEwEQQRCBDIEMAQgAC8AIABABDUEOgQ+BD0EQQRCBEAEQwQ6 BEYEOAQ4BC4ADQANACEENQQ8BDgEPQQwBEAEIABBBD4EQQRCBD4EOARCBEEETwQ6AA0AMAA2ACAA LQAgADAANwAgAD4EOgRCBE8EMQRABE8ELAAgACEEMAQ9BDoEQgQtAB8ENQRCBDUEQAQxBEMEQAQz BA0ADQAhBEAENQQ0BDgEIABCBDUEPAQ6AA0ALQAgAD0EPgRABDwEMARCBDgEMgQ9BDAETwQgADEE MAQ3BDAELAAgAEAENQQzBDsEMAQ8BDUEPQRCBDgEQARDBE4ESQQwBE8EIAA3BDAEMgQ1BEAESAQ1 BD0EOAQ1BCAAQQRCBEAEPgQ4BEIENQQ7BEwEQQRCBDIEMAQgADgEIABBBDQEMARHBEMEIAA+BDEE SgQ1BDoEQgQwBCAAMgQgAE0EOgRBBD8EOwRDBDAEQgQwBEYEOAROBDsADQAtACAAQAQwBDEEPgRH BDAETwQgADgEIAA4BEEEPwQ+BDsEPQQ4BEIENQQ7BEwEPQQwBE8EIAA0BD4EOgRDBDwENQQ9BEIE MARGBDgETwQ6ACAAPwQ+BDQEMwQ+BEIEPgQyBDoEMAQgAEAEMAQxBD4ERwQ1BDkEIAA6BD4EPAQ4 BEEEQQQ4BDgEOwANAC0AIAAgAB8EQAQ+BEYENQQ0BEMEQAQwBCAAMgRLBDQEMARHBDgEIAA3BDAE OgQ7BE4ERwQ1BD0EOARPBCAAPgQgAEEEPgQ+BEIEMgQ1BEIEQQRCBDIEOAQ4BCAAPwQ+BEEEQgRA BD4ENQQ9BD0EPgQzBD4EIAA+BDEESgQ1BDoEQgQwBCAAPwRABD4ENQQ6BEIEPQQ+BDkEIAAAAAAA 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 AAAA9QAAAAAAAAAAAAAAAPUAAAAAAAAAAAAAAAD1AAAAAAAAAAAAAAAA9QAAAAAAAAAAAAAAAPUA AAAAAAAAAAAAAAD1AAAAAAAAAAAAAAAA9QAAAAAAAAAAAAAAAPUAAAAAAAAAAAAAAAD1AAAAAAAA AAAAAAAA9QAAAAAAAAAAAAAAAPUAAAAAAAAAAAAAAAD1AAAAAAAAAAAAAAAA9QAAAAAAAAAAAAAA APUAAAAAAAAAAAAAAAD1AAAAAAAAAAAAAAAA9QAAAAAAAAAAAAAAAPUAAAAAAAAAAAAAAAD1AAAA AAAAAAAAAAAA8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAABAAAACQAAEmTwAAEAFKQAAGdk0RArAAAWNAQ+BDoEQwQ8BDUEPQRC BDAERgQ4BDgEIAA4BCAAQgRABDUEMQQ+BDIEMAQ9BDgETwQ8BCAAQgQ1BEUEPQQ4BEcENQRBBDoE OARFBCAAQAQ1BDMEOwQwBDwENQQ9BEIEPgQyBDsADQAtACAAQgRABDUEMQQ+BDIEMAQ9BDgETwQg AEIENQRFBD0EOARHBDUEQQQ6BDgERQQgAEAENQQzBDsEMAQ8BDUEPQRCBD4EMgQ7ACAAQQRCBEAE PgQ4BEIENQQ7BEwEPQRLBDkEIAA6BD4EPQRCBEAEPgQ7BEwEOwANAC0AIAA+BEEEPgQxBDUEPQQ9 BD4EQQRCBDgEIAAyBDIEPgQ0BDAEIAAyBCAATQQ6BEEEPwQ7BEMEMARCBDAERgQ4BE4EIAA+BEEE PgQxBD4EIAA+BD8EMARBBD0ESwRFBCAAOAQgAEIENQRFBD0EOARHBDUEQQQ6BDgEIABBBDsEPgQ2 BD0ESwRFBCAAPgQxBEoENQQ6BEIEPgQyBDsADQAtACAAPgRIBDgEMQQ6BDgELAAgADIEOwQ4BE8E TgRJBDgENQQgAD0EMAQgAD0EMARABEMESAQ1BD0EOAQ1BCAAQQRABD4EOgQ+BDIEIAA/BEAEOAQg AEEENAQwBEcENQQgAD4EMQRKBDUEOgRCBDAEOwANAC0AIAA6BDAENAQwBEEEQgRABD4EMgRLBDkE IABDBEcENQRCBCAAOAQgAD4ERAQ+BEAEPAQ7BDUEPQQ4BDUEIAA/BEAEMAQyBCAAPQQwBCAAMgQ9 BD4EMgRMBCAAQQQ+BDcENAQwBD0EPQRLBDUEIAA+BDEESgQ1BDoEQgRLBCAAPQQ1BDQEMgQ4BDYE OAQ8BD4EQQRCBDgEDQANABQEOwRPBCAAQwRHBDAEQQRCBD0EOAQ6BD4EMgQgAEEENQQ8BDgEPQQw BEAEMAQgAD8EQAQ1BDQEPgRBBEIEMAQyBDsETwROBEIEQQRPBCAAOAQ9BEQEPgRABDwEMARGBDgE PgQ9BD0ESwQ1BCAAPAQwBEIENQRABDgEMAQ7BEsEOwAgADgEPQQ+BDMEPgRABD4ENAQ9BDgEPAQg ADQENQQ5BEEEQgQyBEMENQRCBCAAMQRABD4EPQQ4BEAEPgQyBDAEPQQ4BDUEIAA9BD4EPAQ1BEAE PgQyBC4ADQANABQEOwRPBCAAQwRHBDAEQQRCBDgETwQgADIEIAA8BDUEQAQ+BD8EQAQ4BE8EQgQ4 BDgEOgAgACgAOAAxADIAKQAgADkAOAA2ACAAOQAzACAANAA3AA0ACAANABIEPQQ4BDwEMAQ9BDgE NQQhACAAHwQ+BDsEPQRLBDkEIABBBD8EOARBBD4EOgQgAEIENQQ8BCAAOAQgAEMEQQQ7BD4EMgQ4 BE8EIAA/BEAENQQ0BD4EQQRCBDAEMgQ7BE8ETgRCBEEETwQgAD8EQAQ4BCAAQAQ1BDMEOARBBEIE QAQwBEYEOAQ4BC4ADQANAA0ADQAIACAEQwQ6BD4EMgQ+BDQEOARCBDUEOwRMBCAAPgRABDMEOgQ+ BDwEOARCBDUEQgQwBAkACQAJAAkAIgQ4BDwEPgREBDUENQQyBDAEIAAeBC4AEwQNAA0AAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcB8AAKQfAACmHwAAqB8AAK4f AACwHwAAsh8AAMQfAADGHwAAyB8AAMofAABWIAAAWCAAAFogAABcIAAA59rJuKSUgHNjVkbaOSUm FmjRECsANQiBNgiBQ0oUAE9KAABRSgAAXAiBXQiBXkoAAGFKFAAAGBVoPBX0ABZo0RArAE9KAABR SgAAXkoAAAAeFWivZw8AFmjRECsANQiBT0oDAFFKAwBcCIFeSgMAABgVaK9nDwAWaNEQKwBPSgMA UUoDAF5KAwAAHgNqAAAAABZo0RArAFUIAW1IAARuSAAEdEgZBHUIAQAYFWiCI8sAFmjRECsAT0oD AFFKAwBeSgMAACYVaEVNSAAWaEVNSAA1CIFDSjQAT0oDAFFKAwBcCIFeSgMAYUo0AAAeFWg3MgkA FmjRECsANQiBT0oDAFFKAwBcCIFeSgMAACYVaG55aAAWaNEQKwA1CIFDShgAT0oDAFFKAwBcCIFe SgMAYUoYAAAgFmhFTUgANQiBQ0oYAE9KAwBRSgMAXAiBXkoDAGFKGAAAIBZo0RArADUIgUNKGABP SgMAUUoDAFwIgV5KAwBhShgAABgWaNEQKwA1CIFPSgMAUUoDAFwIgV5KAwAALxVobnloABZo0RAr ADUIgUIqBkNKGABPSgMAUUoDAFwIgV5KAwBhShgAcGj/AAAAAA5cIAAAXiAAAGAgAAB4IAAAeiAA AJAgAACYIAAAsiAAALQgAAC2IAAA8uLOwM7ArJyYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA BhZoKEvtAAAeFWinSTAAFmjRECsANQiBT0oDAFFKAwBcCIFeSgMAACYVaKdJMAAWaNEQKwA1CIFD ShgAT0oAAFFKAABcCIFeSgAAYUoYAAAaFmjRECsAQ0oYAE9KAABRSgAAXkoAAGFKGAAAJhVoZUgF ABZo0RArADUIgUNKGABPSgAAUUoAAFwIgV5KAABhShgAAB4DagAAAAAWaNEQKwBVCAFtSAAEbkgA BHRIGQR1CAEAGhZo0RArAENKFABPSgAAUUoAAF5KAABhShQACTwAHFABADGQaAE6cNEQKwAfsIIu ILDGQSGw7AQisFIDI5BoASSQbgQlsAAAF7DEAhiwxAIMkMQCRHABAAAAoEYd8NMuAABKAEZqTE9i LMisMfKWM5Oz///Y/+AAEEpGSUYAAQEBANwA3AAA/9sAQwACAQEBAQECAQEBAgICAgIEAwICAgIF BAQDBAYFBgYGBQYGBgcJCAYHCQcGBggLCAkKCgoKCgYICwwLCgwJCgoK/9sAQwECAgICAgIFAwMF CgcGBwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK/8AA EQgBGAHPAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIB AwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBka JSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SV lpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX2 9/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAEC dwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4 OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWm p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQAC EQMRAD8A/fyiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACi iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKK KACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoooo AKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopC4HX1xQAtFY3j H4h+BPh7otx4j8d+MNN0ewtYy9xealepDHGo6ksxAFfMvxW/4Lcf8E6Phfqc/hu0+NcvirWYUyuk +DNCu9SeVt23YJIozFuz2LigD6zor4sk/wCCn/7THxN06zuv2Y/+CX3xW1xb7d5WoeNmtfD9qn91 i07klT6nbT7qy/4LmfF1bWW11r4I/CizuhuuoBDea3qFkufu7jiCR8ddvA9aAPs8nH9awvFPxQ+G /gaAXPjX4gaHo8Zk2B9U1WG3Bb0Bdhk+1fJj/wDBLf8AaG+J+2b9p3/gpl8VfEUchH2vRvC80Wh2 DgHJULbgPg9OWJ967Lw1/wAEcf8AgnPoE/8AaGo/s0aT4gvTOJWvfFd5c6pIzZzkm5kcEk8njmgD W+Iv/BWf/gnL8K7l7Pxf+1x4S85GKvb6VcyahKpBwcpapI36Vxsv/Bdv/glhAyrP+086bgSC/gXX VGB3y1iOPevevCX7KH7MfgPRv+Ef8F/s9eCdKsiMG20/wxawp+Sx1tr8HPhYqLGPhzogVQAoGmxj AH/AaAK/wa+PHwg/aG8FQfET4J/EPS/EujXKgxX2l3AkAJGQrLw0bY6qwBHpXXVkeHvAvg7wlc3F 14V8J6bpr3eDdvYWSQmYjOC+wDcRk8n1rXoAKKKKAGu2wFjnAGelNt50uYlmj3bWXI3IV/Q8ipKK ACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA KKKKACiiigAooooAKKKCcDNABRXOeO/i98L/AIW6Y+tfEz4h6H4etIxl7jWtVhtlA+sjCvlj4mf8 F4v+CePgnWD4U8B+P9b+I2tmXyo9K+Hnhm71Fmcj5QJFQREE8ZVz+lAH2VkDqaTcv94c9Oa/PS+/ 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 AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUkhwhI7DI4pabMqvCyOcAqcn0oA/Mj9ryLQ/wBp3/gt H8HPgvo0MGo23hXWF1/WJYpBIkKabEZAjjPDedvj2EcHB6nFfpyORmvyq/4JZ/BqKw/4Ll/tW+No jC9r4daa2tikOWEmoXv2h9xJOGHluPcZ7cV+qtABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQ AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAB RRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSMAwKnoetFFAHDfC39mr4J/Bfxt4w+I/w28Dw6drnj7V l1LxbqYnkkk1C4UEKzb2IUKCcKoA5Jxk5ruqKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig AooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAC iiigAooooA//2aBGHfDYZgAAsnvv3YpKkyBZRoyNdkDDhv//2P/hGxtFeGlmAABNTQAqAAAACAAH ARIAAwAAAAEAAQAAARoABQAAAAEAAABiARsABQAAAAEAAABqASgAAwAAAAEAAgAAATEAAgAAABwA AAByATIAAgAAABQAAACOh2kABAAAAAEAAACkAAAA0AAK/IAAACcQAAr8gAAAJxBBZG9iZSBQaG90 b3Nob3AgQ1M1IFdpbmRvd3MAMjAxNDowNDoyMiAxNzozNzo0MwAAAAADoAEAAwAAAAH//wAAoAIA BAAAAAEAAACAoAMABAAAAAEAAACAAAAAAAAAAAYBAwADAAAAAQAGAAABGgAFAAAAAQAAAR4BGwAF AAAAAQAAASYBKAADAAAAAQACAAACAQAEAAAAAQAAAS4CAgAEAAAAAQAAGeUAAAAAAAAASAAAAAEA AABIAAAAAf/Y/+0ADEFkb2JlX0NNAAH/7gAOQWRvYmUAZIAAAAAB/9sAhAAMCAgICQgMCQkMEQsK CxEVDwwMDxUYExMVExMYEQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAQ0LCw0O DRAODhAUDg4OFBQODg4OFBEMDAwMDBERDAwMDAwMEQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM 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 s1Z6p3Naf+Dp0oq/63UrqEs0d4jiPeXyj+7FIgepry/i08DpePhAFvvtjb6hAEDnZUxvspr3fmM/ 656liuJJKCUjI2TZXgACgpJJJBL/AP/Z/+0iWlBob3Rvc2hvcCAzLjAAOEJJTQQlAAAAAAAQAAAA AAAAAAAAAAAAAAAAADhCSU0EOgAAAAAArwAAABAAAAABAAAAAAALcHJpbnRPdXRwdXQAAAAEAAAA AFBzdFNib29sAQAAAABJbnRlZW51bQAAAABJbnRlAAAAAEltZyAAAAAPcHJpbnRTaXh0ZWVuQml0 Ym9vbAAAAAALcHJpbnRlck5hbWVURVhUAAAAHQBDAGEAbgBvAG4AIABNAEYANAAwADEAMAAgAFMA ZQByAGkAZQBzACAAVQBGAFIASQBJACAATABUAAAAOEJJTQQ7AAAAAAGyAAAAEAAAAAEAAAAAABJw cmludE91dHB1dE9wdGlvbnMAAAASAAAAAENwdG5ib29sAAAAAABDbGJyYm9vbAAAAAAAUmdzTWJv b2wAAAAAAENybkNib29sAAAAAABDbnRDYm9vbAAAAAAATGJsc2Jvb2wAAAAAAE5ndHZib29sAAAA AABFbWxEYm9vbAAAAAAASW50cmJvb2wAAAAAAEJja2dPYmpjAAAAAQAAAAAAAFJHQkMAAAADAAAA AFJkICBkb3ViQG/gAAAAAAAAAAAAR3JuIGRvdWJAb+AAAAAAAAAAAABCbCAgZG91YkBv4AAAAAAA AAAAAEJyZFRVbnRGI1JsdAAAAAAAAAAAAAAAAEJsZCBVbnRGI1JsdAAAAAAAAAAAAAAAAFJzbHRV bnRGI1B4bEBSAAAAAAAAAAAACnZlY3RvckRhdGFib29sAQAAAABQZ1BzZW51bQAAAABQZ1BzAAAA AFBnUEMAAAAATGVmdFVudEYjUmx0AAAAAAAAAAAAAAAAVG9wIFVudEYjUmx0AAAAAAAAAAAAAAAA U2NsIFVudEYjUHJjQFkAAAAAAAA4QklNA+0AAAAAABAASAAAAAEAAgBIAAAAAQACOEJJTQQmAAAA AAAOAAAAAAAAAAAAAD+AAAA4QklNBA0AAAAAAAQAAAAeOEJJTQQZAAAAAAAEAAAAHjhCSU0D8wAA AAAACQAAAAAAAAAAAQA4QklNJxAAAAAAAAoAAQAAAAAAAAACOEJJTQP1AAAAAABIAC9mZgABAGxm ZgAGAAAAAAABAC9mZgABAKGZmgAGAAAAAAABADIAAAABAFoAAAAGAAAAAAABADUAAAABAC0AAAAG AAAAAAABOEJJTQP4AAAAAABwAAD/////////////////////////////A+gAAAAA//////////// /////////////////wPoAAAAAP////////////////////////////8D6AAAAAD///////////// ////////////////A+gAADhCSU0EAAAAAAAAAgAAOEJJTQQCAAAAAAACAAA4QklNBDAAAAAAAAEB ADhCSU0ELQAAAAAABgABAAAAAzhCSU0ECAAAAAAAEAAAAAEAAAJAAAACQAAAAAA4QklNBB4AAAAA AAQAAAAAOEJJTQQaAAAAAANBAAAABgAAAAAAAAAAAAAAgAAAAIAAAAAGBEYEPwQ/BDoALQAzAAAA AQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAACAAAAAgAAAAAAAAAAAAAAAAAAAAAABAAAA AAAAAAAAAAAAAAAAAAAAABAAAAABAAAAAAAAbnVsbAAAAAIAAAAGYm91bmRzT2JqYwAAAAEAAAAA AABSY3QxAAAABAAAAABUb3AgbG9uZwAAAAAAAAAATGVmdGxvbmcAAAAAAAAAAEJ0b21sb25nAAAA gAAAAABSZ2h0bG9uZwAAAIAAAAAGc2xpY2VzVmxMcwAAAAFPYmpjAAAAAQAAAAAABXNsaWNlAAAA EgAAAAdzbGljZUlEbG9uZwAAAAAAAAAHZ3JvdXBJRGxvbmcAAAAAAAAABm9yaWdpbmVudW0AAAAM RVNsaWNlT3JpZ2luAAAADWF1dG9HZW5lcmF0ZWQAAAAAVHlwZWVudW0AAAAKRVNsaWNlVHlwZQAA AABJbWcgAAAABmJvdW5kc09iamMAAAABAAAAAAAAUmN0MQAAAAQAAAAAVG9wIGxvbmcAAAAAAAAA AExlZnRsb25nAAAAAAAAAABCdG9tbG9uZwAAAIAAAAAAUmdodGxvbmcAAACAAAAAA3VybFRFWFQA AAABAAAAAAAAbnVsbFRFWFQAAAABAAAAAAAATXNnZVRFWFQAAAABAAAAAAAGYWx0VGFnVEVYVAAA AAEAAAAAAA5jZWxsVGV4dElzSFRNTGJvb2wBAAAACGNlbGxUZXh0VEVYVAAAAAEAAAAAAAlob3J6 QWxpZ25lbnVtAAAAD0VTbGljZUhvcnpBbGlnbgAAAAdkZWZhdWx0AAAACXZlcnRBbGlnbmVudW0A AAAPRVNsaWNlVmVydEFsaWduAAAAB2RlZmF1bHQAAAALYmdDb2xvclR5cGVlbnVtAAAAEUVTbGlj ZUJHQ29sb3JUeXBlAAAAAE5vbmUAAAAJdG9wT3V0c2V0bG9uZwAAAAAAAAAKbGVmdE91dHNldGxv bmcAAAAAAAAADGJvdHRvbU91dHNldGxvbmcAAAAAAAAAC3JpZ2h0T3V0c2V0bG9uZwAAAAAAOEJJ TQQoAAAAAAAMAAAAAj/wAAAAAAAAOEJJTQQUAAAAAAAEAAAAAzhCSU0EDAAAAAAaAQAAAAEAAACA AAAAgAAAAYAAAMAAAAAZ5QAYAAH/2P/tAAxBZG9iZV9DTQAB/+4ADkFkb2JlAGSAAAAAAf/bAIQA DAgICAkIDAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwM DAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwMDAwREQwMDAwMDBEMDAwMDAwMDAwMDAwM DAwMDAwMDAwMDAwMDAwM/8AAEQgAgACAAwEiAAIRAQMRAf/dAAQACP/EAT8AAAEFAQEBAQEBAAAA AAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcG CAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZE k1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5en t8fX5/cRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKS Q1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14/NGlKSFtJXE1OT0pbXF1eX1VmZ2 hpamtsbW5vYnN0dXZ3eHl6e3x//aAAwDAQACEQMRAD8A9VSSSSUpJJVM7qWPhN953WRuFYIB2j/C Pc8tZVV/wljkYxMjQFlBIAsttU7uq4VW8B5tdX9NtQ37f+Ne39HT/wBdexZ3pdT6p77nehikTB3N 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 rZd7LY2iwAGRzssY8OZdVu/wdn9j3q4kjGRibBooIBFF56xuZgWVPy6hkVY5LqrSSQwkOrc6vI99 tPse79Fmb6v+76jkV4OVRjUYz66GV1PqqqypABs2tblU2e+vJyKtr/oW/wCE/nl0apXdIwbQ7az0 TZq/0jtDj/wlX8zb/wBdrep45xYMrjIdY/L/AIn+ExnGdhqPH/vmrk1dSx3ZeTjuseGsrZRWT6gJ /wC1GT6P0t7GO/mmfznpf8Iqub1jq2HiV2Mr9QufdtdbWWueyv8Amf0W+nZZd/0/8Hjq0Oh30/0X J2Ds2HM/9trKaP8A2XSGJ11ujcgEedjf+/4Vn/Vp0ZY9L4J1+9+r/R4UES1+aN9vUwy+qdSZkZdV NB2UVGykitzjY4Mru9Ea+2z+d/43/rVisYY6jlYOVVmk022ue2p7RtLK7Gh9W2Pz8f1PR3/6SpCO L112jsgDzFjf++4Vf/VpfsS+7TKyd7e7Yc/8Miy2j/2WQPtiIFwiRXqj65XFI4rJ9R8D6WqwYVVe zJNLjTuH2fDG5mx7PSyK8l7ttbGX2fpf03pbP0f6RTbb1HqDRViN9HFDQ0Pl0ED6PqZXttu/qYf0 /wDywWjT0jBqDQ5nrbNWeqdzWn/g6dKKv+t1K6hLNHeI4j3l8o/uxSIHqa8v4tPA6Xj4QBb77Y2+ oQBA52VMb7Ka935jP+uepYriSSglIyNk2V4AAoKSSSQS/wD/2QA4QklNBCEAAAAAAFUAAAABAQAA AA8AQQBkAG8AYgBlACAAUABoAG8AdABvAHMAaABvAHAAAAATAEEAZABvAGIAZQAgAFAAaABvAHQA bwBzAGgAbwBwACAAQwBTADUAAAABADhCSU0EBgAAAAAABwABAAAAAQEA/+EOImh0dHA6Ly9ucy5h ZG9iZS5jb20veGFwLzEuMC8APD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpy ZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0 az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAw ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIv MjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4 bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5v cmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29t L3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4w L21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNv dXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3Mi IHhtcDpDcmVhdGVEYXRlPSIyMDE0LTA0LTA3VDE4OjUwOjExKzA0OjAwIiB4bXA6TW9kaWZ5RGF0 ZT0iMjAxNC0wNC0yMlQxNzozNzo0MyswNDowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxNC0wNC0y MlQxNzozNzo0MyswNDowMCIgZGM6Zm9ybWF0PSJpbWFnZS9qcGVnIiBwaG90b3Nob3A6Q29sb3JN b2RlPSIzIiBwaG90b3Nob3A6SUNDUHJvZmlsZT0iQWRvYmUgUkdCICgxOTk4KSIgeG1wTU06SW5z dGFuY2VJRD0ieG1wLmlpZDo5RENCQTVDNTE4Q0FFMzExODNGQ0E5RTUxOUY3QzA3MiIgeG1wTU06 RG9jdW1lbnRJRD0ieG1wLmRpZDo5Q0NCQTVDNTE4Q0FFMzExODNGQ0E5RTUxOUY3QzA3MiIgeG1w TU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjlDQ0JBNUM1MThDQUUzMTE4M0ZDQTlFNTE5 RjdDMDcyIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0OmFjdGlvbj0i Y3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo5Q0NCQTVDNTE4Q0FFMzExODNGQ0E5 RTUxOUY3QzA3MiIgc3RFdnQ6d2hlbj0iMjAxNC0wNC0wN1QxODo1MDoxMSswNDowMCIgc3RFdnQ6 c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIi8+IDxyZGY6bGkgc3RF dnQ6YWN0aW9uPSJjb252ZXJ0ZWQiIHN0RXZ0OnBhcmFtZXRlcnM9ImZyb20gaW1hZ2UvYm1wIHRv IGltYWdlL2pwZWciLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5j ZUlEPSJ4bXAuaWlkOjlEQ0JBNUM1MThDQUUzMTE4M0ZDQTlFNTE5RjdDMDcyIiBzdEV2dDp3aGVu PSIyMDE0LTA0LTIyVDE3OjM3OjQzKzA0OjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQ aG90b3Nob3AgQ1M1IFdpbmRvd3MiIHN0RXZ0OmNoYW5nZWQ9Ii8iLz4gPC9yZGY6U2VxPiA8L3ht cE1NOkhpc3Rvcnk+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw/eHBh Y2tldCBlbmQ9InciPz7/4gJASUNDX1BST0ZJTEUAAQEAAAIwQURCRQIQAABtbnRyUkdCIFhZWiAH zwAGAAMAAAAAAABhY3NwQVBQTAAAAABub25lAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLUFE QkUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApjcHJ0AAAA /AAAADJkZXNjAAABMAAAAGt3dHB0AAABnAAAABRia3B0AAABsAAAABRyVFJDAAABxAAAAA5nVFJD AAAB1AAAAA5iVFJDAAAB5AAAAA5yWFlaAAAB9AAAABRnWFlaAAACCAAAABRiWFlaAAACHAAAABR0 ZXh0AAAAAENvcHlyaWdodCAxOTk5IEFkb2JlIFN5c3RlbXMgSW5jb3Jwb3JhdGVkAAAAZGVzYwAA AAAAAAARQWRvYmUgUkdCICgxOTk4KQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWFlaIAAAAAAAAPNR AAEAAAABFsxYWVogAAAAAAAAAAAAAAAAAAAAAGN1cnYAAAAAAAAAAQIzAABjdXJ2AAAAAAAAAAEC MwAAY3VydgAAAAAAAAABAjMAAFhZWiAAAAAAAACcGAAAT6UAAAT8WFlaIAAAAAAAADSNAACgLAAA D5VYWVogAAAAAAAAJjEAABAvAAC+nP/uAA5BZG9iZQBkgAAAAAH/2wCEAAwICAgJCAwJCQwRCwoL ERUPDAwPFRgTExUTExgRDAwMDAwMEQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBDQsLDQ4N EA4OEBQODg4UFA4ODg4UEQwMDAwMEREMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM DP/AABEIAIAAgAMBIgACEQEDEQH/3QAEAAj/xAE/AAABBQEBAQEBAQAAAAAAAAADAAECBAUGBwgJ CgsBAAEFAQEBAQEBAAAAAAAAAAEAAgMEBQYHCAkKCxAAAQQBAwIEAgUHBggFAwwzAQACEQMEIRIx BUFRYRMicYEyBhSRobFCIyQVUsFiMzRygtFDByWSU/Dh8WNzNRaisoMmRJNUZEXCo3Q2F9JV4mXy s4TD03Xj80YnlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3EQACAgECBAQD BAUGBwcGBTUBAAIRAyExEgRBUWFxIhMFMoGRFKGxQiPBUtHwMyRi4XKCkkNTFWNzNPElBhaisoMH JjXC0kSTVKMXZEVVNnRl4vKzhMPTdePzRpSkhbSVxNTk9KW1xdXl9VZmdoaWprbG1ub2JzdHV2d3 h5ent8f/2gAMAwEAAhEDEQA/APVUkkklKSSVTO6lj4TYf7rI3CsEAx++9zy1lVX/AAljkYxMjQFl RNbttU7uq4VW8B5tdX9NtQ37f+Me39HV/wBdexZ/pdT6mN9zvQxSJg7msj+TX+iuv/4zJdTT/wB0 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 cYvXW6NyAfjY3/v+HZ/1SdEw0vgnX73o/R4UEHxHlqwyuqdRZkZVVNJ2UVGykhjnGxwZXb6PPts/ nf8Ajf8Arb1Ywx1HKwsqrNJpttc8VPaNpbXY0Pq2x+fj+p6W/wD0lSEcXrrtHZAHwsb/AN9wq/8A qk37Evu/pWTvHdsOf/7cWW0f+y6aeARAuEdvVH1y9Ktb6n8GswYVVezJNTjTuH2fDG5mx7PSyK8h 7trGMvf+l/S+l/g/0iky3qHUGirFb6OMGhofLoIH0fUyvbbd/UxP/Y9aNPSMGoNDmets1Z6nua0/ 8HVpRX/1upXUJZo9BxHvLYeUUiJ66eTTwOmY+EAW++2NvqEAQOdlTG+yqvd+Yz/rnqPVxJJQykZG ybK8ADZSSSSCn//ZAAAAAAAAABsrAABEAGQAAAAAAAAACgAAAAAAAAABAAAAAAAPBj4FjgPeAwAA AAAAAAAAAAAEAQEABAEBAAQBAQAEAQEAAAAAAAAADwAE8IIAAACyBArwCAAAAAEEAAAACgAAYwAL 8DgAAAAEQQEAAAAJAeE6AAD/AQAACAA/AxAAEACAwxQAAAC/AwAAAgAgBDgEQQRDBD0EPgQ6BCAA MgAAAFMAIvEeAAAAmwMAAAAAnAMAAAAAnQMAAAAAngMAAAAAvwMAgACAAAAQ8AQAAAAAAACAUgAH 8EUqAAAFBcMc2yEaXhhQLrQGb4JOwDH/ACEqAAABAAAARAAAAAAASgegRh3wGSoAAMMc2yEaXhhQ LrQGb4JOwDH//9j/4AAQSkZJRgABAQEA3ADcAAD/2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUE BAMEBgUGBgYFBgYGBwkIBgcJBwYGCAsICQoKCgoKBggLDAsKDAkKCgr/2wBDAQICAgICAgUDAwUK BwYHCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgr/wAAR CADNAO0DASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgED AwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRol JicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWW l5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3 +Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3 AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5 OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaan qKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIR AxEAPwD9/KKKKACignAzXnvjX9rf9lX4beJbnwZ8Rv2l/AHh/WLMr9r0rW/GNlaXMO5Qy7opZVZc qQRkcgg0AehUHgZrz/wL+1h+y38UPEsHgz4Z/tJeAvEesXKu1vpOg+MLK8uZQqlmKxRSsxAUEkgc AZNb/wAT/il4C+DvgHWfiX8SfE9tpGiaDp0t7quoXRISCGNSzMcck4GABkkkAAkgUAfH/wC0X/wX O+B/7OH/AAU28Jf8EwvEnwY8VX/ibxdLpUdn4ks7i1FhAb4sE3q7iT5cc4H0r7ejmWQ4AIOOhr+Z H9tzUPFv7UP/AAcw/BrVP2j/AIUQaRp/jTUfCxsfB99u+0w6JI7rbpe4Py3MkY810XHl+aI+ShY/ vQn/AATt8M+D2B/Z+/aS+MPw2VR+7tND8dPqlknsLXWkvoVXthEXA4BWgD6Jor52fwR/wU6+HoI8 L/HL4W/Eazj/ANXa+MPCN3oeoSDP8V7YzzQZxwMWY55JpjftbftQ+Bh5fxw/YA8ZwRoP3urfDnxD p/iS1Xnr5e+2vG454tfYZNAH0ZRXgnh3/gpl+xbfX8eieNfjPF4F1KZgsOlfE/Rrzwtcux6KqatF bmQk9Nuc9s17VoPi7wv4q0uPXPDHiGz1GylGYruxuFlicezKSD+FAGjRUa3MDnCyA8mpAQelABRR RQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFACP9w8dq/lS/4ONvB3ww1v8A4LA/Fa98 QfBv4nareE6QJb/w9qEKWkmNJswAgaxkIxjB+Y85r+q4jII9RUNvZrACBIxB5x70Afx2/wDBNn9q zwf/AME0v2t9B/a8+G/7IHxS8RatoFlfW8Gla3rKJbyrc2sluxYxacGyFkJGD1Ar7g+Nv/B0n8Uf 2iPiZ4SuPHf/AATm1ibwn4PvBq974Fi8QT7dX1RCDYzXj/ZMtBAweVIdoDTLG7E+WFP9G3lj+8a+ ePg7b+f/AMFE/jrGZSNng/wWVOOmV1X0+n60AfzI/tVf8FcvFvx//wCCw3gP/gpPe/svXuh6l4Sn 0aWDwDJqMskl39hZyoEphVh5mf8AnmcYNfoof+Dyn4zbiP8Ah1breM8Y8TXH/wAg1xX/AAVBcxf8 HcfwPtX+bN94Oy3TOXfNf0LeWP7xoA/B7/iMp+Mw6f8ABK3Wz/3M1x/8g0x/+DyP4xyE7/8AglVr eD1H/CTXHP8A5I1+8nlj+8aPLH940Afgd4g/4O/fiD4r0+TSPFP/AASOv9TtJVKy2t/rks0bg9QV awINeK67/wAF9PgZqmqSeIPDP/BELV/BmpynLar8N/H+q+GrgsOQS2l28G/nna4ZSeoNf0t+WP7x o8sf3jQB/M9H/wAHNX7d3gExTfBL4X/FBYoQBHo3xJuLbxDadc4My6ZbXpznBY3LV7F8Pf8Ag8Z/ a3sdBWD4r/8ABM6PUtSXG+68OahfWUDnv+6ngnZfb52+tfv/AOWP7xo8sf3jQB+D3/EZV8Z/+kVW t/8AhTXH/wAg0f8AEZV8Z/8ApFVrf/hTXH/yDX7w+WP7xo8sf3jQB+D3/EZV8Z/+kVWt/wDhTXH/ AMg12H7Pn/B2v8Xfjj8dvBvwbvv+CaWr6LD4q8U2GkS6tN4jnZLNLm4SEzMDZAEIHLYJH3etftj5 Y/vGo5rQykFZivr8oNAEkbFkUnuKdSImxQuc4GKWgAooooAKKKKACiiigAooooAKKKKACiiigAoo ooAK+evguM/8FGfjqf8AqTPBf/oOrf419C189/Bf/lIx8dv+xM8F/wDoOq0Afzy/8HV/xB8Z/Cv/ AILbt8Qvhz4s1LQtf0bwN4fu9I1nSLt7e5sp0SQrLFKhDI4PQggiov8Ag38/4KU/8FCvjn/wV6+D nwm+NX7b3xV8WeGdZvtVTU9A8ReO768s7oJo97KgkillZWw6KwyOCoPasv8A4O7YpJP+Cw+qFEJx 8OtCzgf9M5a8m/4NqRj/AILd/Alj0Gp6wCfroeoUAf2GW0bxwqshBYDkipKRHV1DKwIx1FLQAUUU UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAHXpRWJ4S8baD4z8PWfivwnqVrq OlahZx3OnalZXIkhuoXUMkiMOGVlKkEHkHj3uN4m0QRlxqtqcLn/AI+Vx+eelAF+iorS6F2hkUDb 1VlbIYetS0AFfPfwX/5SMfHb/sTPBf8A6DqtfQlfPfwX/wCUjHx2/wCxM8F/+g6rQB+Mf/BVnTtN 1n/g7b+Cuj6zptveWlzdeDo7i2uoRJHIpaQFWVshgQehGK/frSvgx8I9A1KHWvD3ww8Pafe27FoL yw0W3hljJBB2uqAjIJHB6EjvX4F/8FR/+Vu34Hf9f3g3/wBDev6GqAInUW0BMQ5HPIzk1+OP/BYv /g5z+OX/AATF/bn139krwd+y94T8VafpOj6dexavqetXNvM5ubdZWUogIAUtgHuBX7JP901/Jj/w dnf8po/Gn/YpeH//AE3x0AfTH/Eb1+0x/wBGM+BP/Covf/iKP+I3r9pj/oxnwJ/4VF7/APEV+H1f Sn/BLj/gmJ8YP+Crn7QOo/s6/BTx54a8PatpvhW416a98UyXC2zQRT28LIDBFI28tcIRlQMKec4y Afpb/wARvX7TH/RjPgT/AMKi9/8AiKP+I3r9pj/oxnwJ/wCFRe//ABFfPX7Xv/BrB+2Z+xp4D0P4 g/ET9oH4X6ja67430jwxbQaPdai0qXWoXK28UjCW0QbFZgWwc4BwDXoXjH/gzT/b48FeENX8Zaj+ 038IJrfR9NnvZ47e61UvIkUbSMFzZAZIXAyRzQB6H/xG9ftMf9GM+BP/AAqL3/4ilT/g93/aYdtv /DDXgQe58T3v/wARX4fzR+TK0ZbO1iM02gD+z/8A4Ir/APBR7xv/AMFS/wBiyD9qfx78NNL8KXs/ ii/0oaTpN3LPEqW5jAffIASTvORjAxX1zX5cf8Ggf/KHmw/7KRrn84a/UegAooooAKKKKACiiigA ooooAKKKKACiiigD8Mv2dv8AgpT/AMFmf2fPEviz9m/wT/wRH8Q3GlXqNr/h7wA/jDbL4WsLp3jl jt5Ps5zaNcpK0UZUeSWdFJQIq/Bt7/wSf/b4vb2W8k/4JKftMK88rOQnxmtdqknJGP7L6c+tf0c6 CxH/AAVQ1+IfdHwE0w/j/bV9+PavoVo1YYYZoA83/Y/8P614U/Zb+HXhbxDoN5pN/pvgXR7W80rU bnzriykjsYUaCWQBRJIjAqzgDcVJwM4r0mmxxRxZ2LjPWnUAFfPfwX/5SMfHb/sTPBf/AKDqtfQl fPfwX/5SMfHb/sTPBf8A6DqtAH40/wDBUf8A5W7fgd/1/eDf/Q3r+hqv55f+Co//ACt2/A7/AK/v Bv8A6G9f0NUAI/3TX8mP/B2d/wApo/Gn/YpeH/8A03x1/Wc/3TX8mP8Awdnf8po/Gn/YpeH/AP03 x0AfmtX37/wbk/8ABRL9nD/gmd+3Lrvx6/ai1TWLXw7f/De+0W3fRdKa8lN1LeWUqAopGF2wSfN6 getfAVfVn/BIL/gl14j/AOCtX7S2qfs2+FfizYeDbrTPB9zr7apqGmvdI6Q3FtCYgiOpyTcA5zwF PFAH64/8FUP+DkX/AIJh/ta/BHwX4F+D3iLxjLqOh/GTwt4kvxf+EJIFFhYX6z3BVix3OEBwvc8V 7z8VP+Dsr/gkF4v+F3ibwlpPi7x613qvh+8tLRZfA8oUyyQOignfwMsOa/Nf9tz/AINSviX+xV8N fD3xH139r3Qtci8Q/ELRPCsVtbeGJoWhk1G6Fus5ZpiCEJ3Fccgda9R8d/8ABlj8W/BHgXWfGs37 c/hyddH0u5vpIF8HXCmRYomkKg+ecZ246d6APxCmcSTPIDnLEjNNpZEEcjIGztYjOKSgD+rH/g0D /wCUPNh/2UjXP5w1+o9flx/waB/8oebD/spGufzhr9R6ACiiigAooooAKKKKACiiigAooooAKKKK APnjQf8AlKn4g7f8WC0vgdP+Q3f19D188aF/ylU8Qf8AZAtL4PX/AJDd/X0PQAUUUUAFfPfwX/5S MfHb/sTPBf8A6DqtfQlfPfwX/wCUjHx2/wCxM8F/+g6rQB+NP/BUf/lbt+B3/X94N/8AQ3r+hqv5 5f8AgqP/AMrdvwO/6/vBv/ob1/Q1QAj/AHTX8mP/AAdnf8po/Gn/AGKXh/8A9N8df1nP901/Jj/w dnf8po/Gn/YpeH//AE3x0AfmtX3P/wAG/wB/wUt+CX/BKz9s7Wv2jPjz4X8R6vo2pfD+80KG28MW 0Etws813ZzK5E0sS7Atu4J3ZyRx6fDFfX3/BFz/glzbf8FcP2qNV/ZoufjPJ4FXS/BN1r41hNCGo eYYbm1h8nyzNFjP2jdu3cbMY5yAD9MP+Clf/AAdC/sL/ALZ/wZ8I/Dr4cfCj4lWN5oPxZ8NeKLmT WNMsUja10+9W4mRTHduTIyjCggDPUivbPij/AMHi/wDwTi8afDfxF4P034K/FyO41jQ7uyt5JtF0 8IjzQvGpYi9JwCwzgfnXx3+3j/waiaX+xF8LvDPxIX9tmfxJ/wAJD8SvD/hQ2h8CC18galdrbG43 fbH3eXndswN3TcK9a8e/8GVWk+B/Aet+ND/wULuLkaNo91erbD4aBDJ5UTSbN39oHGcYzjvQB+CM 2DM7LnDMTz9abT5wFkaNeisQDimUAf1Y/wDBoH/yh5sP+yka5/OGv1Hr8uP+DQP/AJQ82H/ZSNc/ nDX6j0AFFFFABRRRQAUUUUAFFFfB3/Bxt+2N+0F+wp/wTYv/AI+/sy+OV8PeKbfxlpNlDqLafDc4 hmdxIuyZWTnA5xkYoA+8aK/kHH/B0D/wWrH+r/a0jAPb/hENL5/8l6P+IoH/AILWd/2tE/8ACR0z /wCR6AP6+KK/kH/4igf+C1f/AEdon/hI6Z/8j0f8RQP/AAWr/wCjtE/8JHTP/kegD+nHQf8AlKn4 gIHH/CgtL5/7jd/X0PXzxoXP/BVTxAT1/wCFBaXz/wBxu/r6HoAKKKKACvnv4L/8pGPjt/2Jngv/ ANB1WvoSvnv4L/8AKRj47f8AYmeC/wD0HVaAPxp/4Kj/APK3b8Dv+v7wb/6G9f0NV/PL/wAFR/8A lbt+B3/X94N/9Dev6GqAEf7pr+TH/g7O/wCU0fjT/sUvD/8A6b46/rOf7pr+TH/g7O/5TR+NP+xS 8P8A/pvjoA/Navs7/ghv/wAFQ/BH/BJf9rjWP2kfHfwr1TxfZ6n4Fu9BTTNIvo7eWOSa6tJxLukU gqBbkY6/MPSvjGvtT/ghT/wS++HP/BWT9rzWf2cfiZ8TNa8LWGmeA7rXo9Q0G3hlmeWK6tIRERKC u0i4Y56/KKAPuX/goX/wdYfAj9tb4SeGPhv4e/ZQ8WaDNoHxO8PeKZLq/wBdtplli069W4aEBFBD uoIDZwD1r1/4jf8AB6N+zh41+Hmv+CrP9ivxvDJrOjXVlHPL4ltCImliaMMQE5A3A8Yryv8A4KJ/ 8Gqn7M/7F3wj8K/EXwn+1H441i48Q/FDw74Wlg1LTbNEih1G9W3eZSi53orZAPBI5r2L4i/8GYP7 Jfgz4c6/42tP2vfiLJLpGi3V7FBNplhtdooWkCkhM4JXGfSgD+duZ1kkZ1HViabT7iIRSsitkBiA TTKAP6sf+DQP/lDzYf8AZSNc/nDX6j1+XH/BoH/yh5sP+yka5/OGv1HoAKKKKACiiigAooooAK/M D/g7xJH/AARy1bH/AEULQv8A0bJX6f1+YH/B3j/yhz1Yf9VD0L/0ZJQB/KPGQMFhkY6Gv2i+Fv8A wZjftH/Fb4Y+HPifp/7aXgmzg8RaDZ6nDayeHLtmiWeFJQjENgkB8E+1fi7GAeD6etf0vfAr/g7z /wCCZXwv+CHg34ba34G+Kkt74f8ACmnabeSW3hy0aNpYLaOJypN2CRuU4OBxQB8wf8QRH7TX/R8n gX/wmrz/AOKr8mv23/2WNT/Yi/aw8c/sn+J/FVnrmoeBtabTrvVrKB4obpwivuRWyVGGHBNf0Xf8 Rlv/AAS3/wCiffFr/wAJmz/+TK/n4/4Kg/tK/Dn9sz/goB8U/wBqH4X2uowaB408TNqOlw6tAsdw kZjRcSKrsFbKngE0Af136Dx/wVT8QAnH/FgtL+X/ALjd/X0PX5i6P/wXS/4JNW3/AAUL1r4u3P7a 3hmPw3cfBzT9Jh1V7S8CNex6rdzPCB5G4kRyo2cY5617V/xEP/8ABF3/AKP78JfX7Ff/APyPQB9o UV8X/wDEQ/8A8EXe37ffhL/wDvv/AJHo/wCIh/8A4Iu9/wBvzwiP+3S+/wDkegD7Qr57+C//ACkY +O3/AGJngv8A9B1Wr/7Jv/BTD9hj9ujxFq3hX9kv9ojR/G9/oVnHd6vb6XDOptoXfYjt5sacFgRx npVD4L/8pGPjt/2Jngv/ANB1WgD8af8AgqP/AMrdvwO/6/vBv/ob1/Q1X88v/BUf/lbt+B3/AF/e Df8A0N6/oaoAR/umv5Mf+Ds7/lNH40/7FLw//wCm+Ov6zn+6a/kx/wCDs7/lNH40/wCxS8P/APpv joA/NavrX/gjT/wVIn/4JIftTap+0rb/AAbTxwdT8GXWgHSH1s2Hlia4tpvO8wRS5x9nxt2jO/Oe Ofkqvuz/AIN8v+CbXwI/4Kmfto65+zr+0JrfiCw0XT/h7e65BP4avY4Lg3MV3ZxKC0kcgK7Z3yNv UDmgD6c/bw/4Ovr79tz4X+GfhvL+xTD4dHh34kaF4s+1r45NyZ/7Nu1uBb7fsibfMxt35O3rg9K9 V8ff8Hq2q+N/AmueC1/4J8W9uNZ0m5sTcf8ACxmbyhLEyb9v2EZxuzjP41vf8FMv+DYv9gH9jX4M eEPH/wAMvGvxFvL3Xfi54Y8M3kes63ayILTUL5beZlCWqEOEY7SSQDjg17b8T/8Agz9/4JkeDPhn 4j8Z6X8RPiu9xpGhXd7bRT+I7MoZIoHkG4CzBIJUAgEH3oA/mZkkEsjuBjLk4PvTadKqrM6KOFYj n602gD+rH/g0D/5Q82H/AGUjXP5w1+o9flx/waB/8oebD/spGufzhr7/AP2pf2u/2cv2Kvhonxi/ ai+KVj4Q8MvqUVgur6hHI8f2mQMyR4jVmyQjnp/CaAPSKK+Lj/wcQ/8ABF1VDN+314T5/wCnK+/+ R6T/AIiJP+CLf/R/fhP/AMAr/wD+R6APtKiviz/iIk/4It4z/wAN9eE//AK//wDkel/4iI/+CLec f8N9+E+v/Plf/wDyPQB9pUV8W/8AERJ/wRbxn/hvrwn/AOAV/wD/ACPR/wAREX/BFzOP+G+/CX/g Ff8A/wAj0AfaVfmB/wAHeP8Ayhy1b/soehf+jZK9t/4iI/8Agi5jP/DfXhP/AMAr7/5Hr4C/4OU/ +Cuv/BOL9s7/AIJial8Ff2Yf2qtB8X+KZfGmkXkejadbXSymCKRzI+ZIlXAyO/egD+dVeg+lLQVK HY3UcGigAooooAeGllGwfNjnBA4pu1xxz+dfT/8AwRk/Zp+E/wC2D/wUt+Fv7N/xy0S41Hwp4p1W 5t9Zs7W8e3kkRLOeVcSIQykOinIPav6OR/wakf8ABFxhu/4UL4h59PHV/wD/ABygD+SgJLjcM4+t NLb+rE496/qU/a//AODY7/gkN8Hv2TPij8WPAvwQ1631rwx8Odb1bSLiXxpfSLHdW1hPNExVpMMA 6KcHg4wa/lqAAJPrQB+4n/BkVtb9pX45g8keBdL/APS2Sv2x+C//ACkY+O3/AGJngv8A9B1WvxN/ 4Mh/+TmPjn/2Iul/+lstftl8F/8AlIx8dv8AsTPBf/oOq0AfjT/wVH/5W7fgd/1/eDf/AEN6/oar +eX/AIKj/wDK3b8Dv+v7wb/6G9f0NUAI/wB01/Jj/wAHZ3/KaPxp/wBil4f/APTfHX9Zz/dNfyY/ 8HZ3/KaPxp/2KXh//wBN8dAH5rV9R/8ABJv/AIKdfED/AIJMftGal+0l8OfhhpHirUdT8JXGgyad rlzLFAkU1xbzGQNEd24G3UAdPmNfLlfoL/wbf/8ABPz9mz/gpV+3Jr3wB/ap8O6jqXhyw+G19rNt FpWqyWUq3cV5ZRIxkjOSAs8gx7j0oA9V/bN/4Opf2iv21fh1oPw78X/sueDNGttB8e6L4ohudP1W 7d5LjTrpbiOEh+NjlcEjkA8V6T45/wCDzr9qvxl4N1bwTf8A7Hfw/gh1fTLiynlTWb7eiyxshZQT jIDcA19Ff8FTP+DdD/gmB+yP8D/Bfj34N/DrxLb6hrXxl8KeHb97/wAX3Nwj2F/qCwXChWPDFCQG HIPIr3n4q/8ABqh/wR58JfDDxL4w0T4X+MFvdK8P3l3Zs/jq7ZVkjgd0JGeRuAOO9AH8rk5V5GkV cBmJxuz3plPuBiZwBgbzimUAf1Y/8Ggf/KHmw/7KRrn84az/APg8V4/4JIWZ/wCqs6L/AOk97Wh/ waB/8oebD/spGufzhrP/AODxb/lEhZ/9la0X/wBEXtAH8tGkaPrPiPVIdG0LTLm+vbmQJb2lpC0k srnoqqoJY+wFdM37PPx+Thvgd4wGOpPhq6x/6Lr6B/4IVf8AKX79nsEAg/EmyByP96v7P0tLVYN3 koe+So9aAP4M7T4N/F6/1e70Gw+FviKe/sArX1lDos7TW4YZUyIE3JkHIyBntVz/AIZ5+P3/AEQz xj/4TF3/APG6/qZ/4J2QWz/8HBP7dCmNSsek+CQnA76ZHX6VfZLT+GCMfRBQB/B5/wAM9fH7/ohv jH/wmLv/AON0j/s+/HuKMyS/BDxgqKMszeGboAD1J8uv7xPslsOsSf8AfA/wrA+KtpbH4X+JBsUZ 0G85CjP+of2oA/hQ0H4NfGDxVpUeu+F/hT4l1KxlZhFeafoVxNE5VirAOiEHBBB54IIpNd+D/wAX fCOnPrvij4XeI9LtI2Ae81HRJ4IlJOAC7oBkngc1/WN/wa2xRTf8EWvho00akjXPEwGVHT+3b4/1 rnv+Ds2GKH/gjD4xliiXP/CW6AOFHe+T0oA/k3bO47sZzzikpXJZixPU0lABRRRQB6d+xx+1f8S/ 2H/2kPDH7UnwetdMn8SeE7qS40uLWbUzWzO8TxHzEVlLDbI3QjnFfoiv/B45/wAFX06eFvhN/wCE nc//ACXX5QUUAfp78X/+Ds//AIKe/G34UeJ/g54x8N/DBNJ8WeHb3RtTay8MXCTLb3UDwSFGN0dr bHbBIODjg1+YVFFAH7hf8GQ//JzHxz/7EXS//S2Wv2y+C/8AykY+O3/YmeC//QdVr8Tf+DIf/k5j 45/9iLpf/pbLX7ZfBf8A5SMfHb/sTPBf/oOq0AfjT/wVH/5W7fgd/wBf3g3/ANDev6Gq/nl/4Kj/ APK3b8Dv+v7wb/6G9f0NUAI/3TX8mP8Awdnf8po/Gn/YpeH/AP03x1/Wc/3TX8mP/B2d/wApo/Gn /YpeH/8A03x0AfmtX0f/AMEwf+Cm/wAa/wDglL8ftQ/aK+A/gvwtrusaj4XuNCls/F1rczWy2808 EzOBbzwvvDW6AHdjBbg8Y+cK/Rr/AINjf2IP2W/2/P2/fEPwa/az+Fkfi3w5Y/C+/wBVtdNl1O6t Qt3He2MaSb7aWNzhJpBgnHzcjgUAa/7XH/B0x+3N+2V4C0P4e/En4H/CfT7PQPG+k+KLSbQ9L1NJ Xu9PuBPDG5mv5FMbMMMAAcdGFeg+Lf8Ag8m/4KM+MvCOq+DNS/Z6+CsVrq+nTWdxLb6Nq4kRJYzG xUnUiMgE4yCPavuf/grh/wAEIf8AglT+zP8AAPwR40+C/wCyZaaLqWs/GzwloN/cjxRqs3mWF5qC xXEJEt04G9CV3KAwzkEV9EfGH/g25/4It+GvhN4p8S6P+xRZW99p3hy9ubSdPF2st5csdu7I2GvM HBUHBGD3oA/khml85zIVALMScUyn3ARZnWPoHIAx0pnWgD+rH/g0D/5Q82H/AGUjXP5w1n/8Hi3/ ACiQs/8AsrWi/wDoi9q//wAGgzCP/gj5YIwOf+Fka52PrDWf/wAHibK//BJG0UMAR8WNGOCcZ/cX vSgD+XXwL4q8Z+B/Fdl4u+HviXU9H1rT5hLpup6NeSW91bSjo8ckZDow9VOa9Yb9vD/gooZSf+Gz PjOTu6f8LD1f/wCP13//AAQ2srTUP+Cuv7P1lf2kc8EnxHslmhmjDIy/NkEHgj61/ZSvw0+GIh3n 4d6GTt7aRDz/AOO0Afw/6L+1X+2PoHi/WfHfh79pL4l2PiPWo4Rr+t2Hi/UIr3UBEuIhPKkoeUKM Bd5OB0xWqP28v+Cizdf20PjV/wCHE1cf+16/pO/4J7+C/Bl3/wAF+/24tLuvCOmS2UGleCjaWz2E bRRA6ZGTtUjC5JzxX6QH4Y/DE9fh1of46ND/APEUAfxJf8N4/wDBRYcj9tD40/8AhxNX/wDj9Nk/ bq/4KH3UTW15+2X8ZZIZFKSxy/ELVirKeCCDPggj1r+2/wD4Vj8MP+idaF/4J4f/AIisL4o/DT4Z J8M/EUifD3Q1YaFdkMNIhBB8l+fu0AfxMeBv2s/2z/hl4YtvBvwj/aZ+J3h7QrYu9rpfh7xlqNpa Rs7l3ZIoZlRdzMzHA5JJPJNM8fftX/th/FLwvN4O+Mv7SXxK8S6DPJG9xpfibxfqF5asytlWMU8r IWB6EjIPSv6hf+DYLwL4I1f/AIIzfDa+17wZpd5ctrfiQGe602OR2Ua5egcspJA6fhXP/wDB154J 8E6H/wAEa/GF/oPhHS7K5Hi3QAtxa6fHE4BvkyAyqD0oA/lKl2+Y20YG44AptOlLNIzM24kkls5z TaACiiigAooooAKKKKAP3C/4Mh/+TmPjn/2Iul/+lstftl8F/wDlIx8dv+xM8F/+g6rX4m/8GQ// ACcx8c/+xF0v/wBLZa/bL4L/APKRj47f9iZ4L/8AQdVoA/Gn/gqP/wArdvwO/wCv7wb/AOhvX9DV fzy/8FR/+Vu34Hf9f3g3/wBDev6GqAEf7pr+TH/g7O/5TR+NP+xS8P8A/pvjr+s5/umv5Mf+Ds7/ AJTR+NP+xS8P/wDpvjoA/Navef8Agnr/AMFFf2i/+CZHxpvfj7+zFPo0PiLUPD02i3Emu6X9rhNr LNDK4CFlw26CPBz0z614NX6Zf8Gqv7K/7Ov7X/8AwUR8S/C/9pv4PaH428PWvwo1DUYNI1+zE8CX SX+nokoU9GCyyDPoxoA5H9pj/g5O/wCCln7W/gfR/Anxi1PwTPp2ieMNM8SWA07woIHW+sJ/Otyz CQ5QOvzLjkcZrt/Ff/B2j/wVz8W+HNR8Ka3rHw8Nnq1hNaXYi8EhW8qVCjhT5vB2k8+tfqr/AMFk v+CTH/BNj4D/ALPXgLxT8Hv2MPAfh7UNT+O/g7Sb+70zRlR57K51JI54GOfuOmVI7g19HfGn/giX /wAEmPD/AMIvFer6N+wJ8NLa7sfDF9NaXEegKHikS3kZWU56ggHPrQB/HHIdzs5xlmJwKb0p9xgT OoHAYgD0GaZQB7d8Cf8AgpP+31+zB4CT4W/s7/te+PvBfhyO7kuU0Xw54jmtbYTSYLybEYDc2Bk9 8VH8e/8Ago7+3l+1L4GHwy/aO/a28d+NvD63sd2uj+JPEM11bidAwSQI5I3AM2D7mvFaKAN34afE 34g/Brx5pfxQ+FPjHUPD/iLRLtbrSNZ0q5aG4tJl6SRuvKsPUV9Bn/gtd/wVtIwf+CinxbI9D4zu f/iq+X6KAPcvCf8AwUz/AOCgngT4o+JfjZ4N/bE+IGmeLvGKW6eKvEdn4jmS71VYECQieQHL7FAC 56AV13/D67/grd/0kW+Ln/haXX/xVfL9FAH1B/w+u/4K3f8ASRb4uf8AhaXX/wAVUV7/AMFof+Cs epWc2nX/APwUN+LM0E8TRzQyeMrkq6MMFSN3IIOK+ZKKAPd/gz/wU/8A+Ch/7O3w9tPhP8Cv2zPi H4T8NWEs0lloeheJp7e2heWRpZSqIwALSOzn1LE96i+N/wDwUx/4KB/tLfD+4+FH7QH7YfxA8Y+G rueKa50PxD4kmuraSSNg0blHJBKsAQexrw2igAooooAKKKKACivpb/gj7+y18Lf21f8Ago38Mf2Y fjTb30vhnxZq09vqqabefZ5yiWs0o2SYO07ox2r+hL/iD+/4JFP866b8RwDyB/wm/wD9ooA/lXor +mf9rL/g1K/4JWfBb9lj4mfF/wAIaX8Qf7X8KfD7WdY0prrxlviFzbWM08RdfJG5d6LkdxxX8y4B yc/hQB7v+w//AMFI/wBr3/gnN4j13xd+yJ8S4/DOo+JLGKz1i4k0m2u/Ohjcuq4nRwuGOcgZr27Q /wDg4z/4K1+H/iJrvxZ039pGGPxB4ks7K11i+/4RXTj58NoJRAu0wbV2ieXlQM7hnOK+G6KAPoD4 q/8ABTf9sP4z/teaD+3Z8Qfict98TvDTWbaPr40i2jWFrUsYCYUjEbbd3dee9fQf/EUP/wAFrf8A o7CD/wAI7S//AJHr8/KKAP0D/wCIoX/gtQwxJ+1fCQeo/wCEP0v/AOR6+SP2uv2vfj3+3L8a7z9o T9pTxkuveK7+zt7W61JbGG2DxQII4l2QqqDCgDIHPevM6KACvYP2Lf27f2mv+CfPxSu/jR+yl4/X w34kvtEl0m5v302C6DWkkkUrpsnR1GXhjOcZ+Xr1rx+igD7M+Pf/AAX5/wCCpH7TfhbTfBnxp/aE i1bT9I8SWGvafAPDNhD5d/ZTCa3lzHCpba4B2nIPeus17/g5k/4LG+JNBvfDOsftRwz2WoWkttdw t4Q0xd8UilWGRBkZUnkYxmvgeigBXYu5djkkk9KSiigAooooAKKKKACiiigAooooAKKKKACinR7N 3z9MGv6fPgF/waZ/8EnfiX8B/BfxE8Q6d8Q/7R17wlp2o33keMdiGae2jlfaPKOBuY4HYUAfzA0V /VR/xB+f8Ei/+gd8SP8Awt//ALRX87//AAVR/Zx+Gf7Hv/BQv4rfsz/CKO7Xw34N8Ttp+krqVwJ5 xEsUbfPIVG45Y84FAHKfsJfteeM/2Df2rfCH7Wfw98M6XrGteDbyW5sNN1oyfZZ3eCSEiTy2VsAS E8EdK/UD/iNk/b0h/dD9k74RMF4BxqnT/wAC6/GKigD9ePjV/wAHhv7bXx3+DPi74L+I/wBmH4WW Wn+MPDGoaHf3VkdRE0EN3bSQPJHvuSN6rISMgjIGRX5Dg5ycYGeKKKACiiigAooooAKKKKACiiig AooooAKKKKACiiigAooooAKKKKACiiigAooooAVQC2GPB61+wXw2/wCDyv8Abf8AhX8OPD3wy0P9 ln4VXNn4d0O00y2uLoan5kiQQrErNtugNxCAnAAyelfj5RQB+z6f8Hs37eR+9+yb8Ih+Gqf/ACVX 5b/tm/tO+Jv23v2pfGv7V3jjQdM0fV/HGsHUdR0zTHkFtbyFFUrH5jM23CjqSea8oooA/9lNABYk ARckAUlmAQAAAAGWAAAhdgABaAEjdgAB0BQ6VgsAApZsAAeU7wUKdAAA4AENNiAPlAEAEJS0ABT2 AQAAHpS0ADXWBQABA9AUZTQBTQAWJAEXJAFJZgEAAAABlgAAIXYAAWgBI3YAAdAUOlYLAAKWbAAH lFkFCnQAAOABDTYgD5QBABCUtAAU9gEAAB6UtAA11gUAAQPQFGU0AQAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXgQP ABIAAQALAQ8ABwAAAAAAAAAAAAQACAAAAAgAAAAOAAAADgAAAA4AAAAOAAAADgAAAA4AAAAOAAAA DgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAMgYAABgAAADAAwAA0AMAAOADAADwAwAAAAQAABAEAAAgBAAAMAQA AEAEAABQBAAAYAQAAHAEAACABAAAkAQAAMADAADQAwAA4AMAAPADAAAABAAAEAQAADIGAAAoAgAA 2AEAAOgBAAAgBAAAMAQAAEAEAABQBAAAYAQAAHAEAACABAAAkAQAAMADAADQAwAA4AMAAPADAAAA BAAAEAQAACAEAAAwBAAAQAQAAFAEAABgBAAAcAQAAIAEAACQBAAAwAMAANADAADgAwAA8AMAAAAE AAAQBAAAIAQAADAEAABABAAAUAQAAGAEAABwBAAAgAQAAJAEAADAAwAA0AMAAOADAADwAwAAAAQA ABAEAAAgBAAAMAQAAEAEAABQBAAAYAQAAHAEAACABAAAkAQAAMADAADQAwAA4AMAAPADAAAABAAA EAQAACAEAAAwBAAAQAQAAFAEAABgBAAAcAQAAIAEAACQBAAAwAMAANADAADgAwAA8AMAAAAEAAAQ BAAAIAQAADAEAABABAAAUAQAAGAEAABwBAAAgAQAAJAEAAA4AQAAWAEAAPgBAAAIAgAAGAIAAFYC AAB+AgAAFAAAAF9IAQRtSBkEbkgZBHNIGQR0SBkEAAAAAFgAAGDx/wIAWAAMFAAA0RArAAAABwAe BDEESwRHBD0ESwQ5BAAADAAAABJkFAEBABSkyAAkAENKFgBPSgQAUUoEAF5KBABfSAEEYUoWAG1I GQRzSBkEdEgJBAAAAAAAAAAAAAAAAAAAAAAAAEIAQSDy/6EAQgAMBQAAAAAAAAAAFQAeBEEEPQQ+ BDIEPQQ+BDkEIABIBEAEOAREBEIEIAAwBDEENwQwBEYEMAQAAAAAWABpQPP/swBYAAwFAAAAAAAA AAAPAB4EMQRLBEcEPQQwBE8EIABCBDAEMQQ7BDgERgQwBAAAHAAX9gMAADTWBgABCgNsADTWBgAB BQMAAGH2AwAAAgALAAAALgBrIPT/wQAuAAAFAAAAAAAAAAAKAB0ENQRCBCAAQQQ/BDgEQQQ6BDAE AAACAAwAAAAAAFBLAwQUAAYACAAAACEA6d4Pv/8AAAAcAgAAEwAAAFtDb250ZW50X1R5cGVzXS54 bWyskctOwzAQRfdI/IPlLUqcskAIJemCx47HonzAyJkkFsnYsqdV+/dM0lRCqCAWbCzZM/eeO+Ny vR8HtcOYnKdKr/JCKyTrG0ddpd83T9mtVomBGhg8YaUPmPS6vrwoN4eASYmaUqV75nBnTLI9jpBy H5Ck0vo4Ass1diaA/YAOzXVR3BjriZE448lD1+UDtrAdWD3u5fmYJOKQtLo/Nk6sSkMIg7PAktTs qPlGyRZCLsq5J/UupCuJoc1ZwlT5GbDoXmU10TWo3iDyC4wSw7AMiV/PZyAZLea/O56J7NvWWWy8 3Y6yjnw2XsxOwf8UYPU/6BPTzH9bfwIAAP//AwBQSwMEFAAGAAgAAAAhAKXWp+fAAAAANgEAAAsA AABfcmVscy8ucmVsc4SPz2rDMAyH74W9g9F9UdLDGCV2L6WQQy+jfQDhKH9oIhvbG+vbT8cGCrsI hKTv96k9/q6L+eGU5yAWmqoGw+JDP8to4XY9v3+CyYWkpyUIW3hwhqN727VfvFDRozzNMRulSLYw lRIPiNlPvFKuQmTRyRDSSkXbNGIkf6eRcV/XH5ieGeA2TNP1FlLXN2Cuj6jJ/7PDMMyeT8F/ryzl RQRuN5RMaeRioagv41O9kKhlqtQe0LW4+db9AQAA//8DAFBLAwQUAAYACAAAACEAa3mWFoMAAACK AAAAHAAAAHRoZW1lL3RoZW1lL3RoZW1lTWFuYWdlci54bWwMzE0KwyAQQOF9oXeQ2TdjuyhFYrLL rrv2AEOcGkHHoNKf29fl44M3zt8U1ZtLDVksnAcNimXNLoi38Hwspxuo2kgcxSxs4ccV5ul4GMm0 jRPfSchzUX0j1ZCFrbXdINa1K9Uh7yzdXrkkaj2LR1fo0/cp4kXrKyYKAjj9AQAA//8DAFBLAwQU AAYACAAAACEApV59LccGAADXGwAAFgAAAHRoZW1lL3RoZW1lL3RoZW1lMS54bWzsWc9uG0UYvyPx DqO9t7ETJ42jOlXs2A20aaPYLepxvB7vTjO7s5oZJ/WtSo9IIERBHKgEXDggIFKLuLTv4D5DoAiK 1Ffgm5nd9U68oUkbQQXNId6d/X3//8w3uxcv3YkY2iVCUh43vOr5iodI7PMBjYOGd6PXObfsIalw PMCMx6ThjYn0Lq2++85FvKJCEhEE9LFcwQ0vVCpZmZuTPixjeZ4nJIZnQy4irOBWBHMDgfeAb8Tm 5iuVpbkI09hDMY6A7eSbyU+Tx5MDdH04pD7xVjP+bQZCYiX1gs9EV3MnGdHXT/cnB5Mnk0eTg6d3 4foJ/H5saAc7VU0hx7LFBNrFrOGB6AHf65E7ykMMSwUPGl7F/Hlzqxfn8EpKxNQxtAW6jvlL6VKC wc68kSmCfi602qnVL6zn/A2AqVlcu91utas5PwPAvg+WW12KPGud5Woz41kA2ctZ3q3KYqXm4gv8 F2Z0rjebzcV6qotlakD2sjaDX64s1dbmHbwBWfziDL7WXGu1lhy8AVn80gy+c6G+VHPxBhQyGu/M oHVAO52Uew4ZcrZRCl8G+HIlhU9RkA15tmkRQx6rk+ZehG9z0QECTciwojFS44QMsQ+J3sJRX1Cs BeIVggtP7JIvZ5a0bCR9QRPV8N5PMBTNlN+Lx9+/ePwQHe4/Otz/+fDevcP9Hy0jh2oDx0GR6vm3 n/z54C764+FXz+9/Vo6XRfyvP3z4y5NPy4FQTlN1nn1+8Nujg2dffPT7d/dL4GsC94vwHo2IRNfI HtrmERhmvOJqTvridBS9ENMixVocSBxjLaWEf1uFDvraGLM0Oo4eTeJ68KaAdlIGvDy67SjcDcVI 0RLJV8LIAW5yzppclHrhipZVcHNvFAflwsWoiNvGeLdMdgvHTnzbowT6apaWjuGtkDhqbjEcKxyQ mCikn/EdQkqsu0Wp49dN6gsu+VChWxQ1MS11SY/2nWyaEm3QCOIyLrMZ4u34ZvMmanJWZvU62XWR UBWYlSjfI8xx42U8UjgqY9nDESs6/CpWYZmS3bHwi7i2VBDpgDCO2gMiZRnNdQH2FoJ+BUMHKw37 JhtHLlIoulPG8yrmvIhc5zutEEdJGbZL47CIfU/uQIpitMVVGXyTuxWi7yEOOD423DcpccL98m5w gwaOStME0U9GoiSWlwl38rc7ZkNMTKuBJu/06ojGf9e4GYXObSWcXeOGVvnsywcler+pLXsNdq+y mtk40qiPwx1tzy0uBvTN787reBRvESiI2S3qbXN+25y9/3xzPq6ez74lT7swNGg9i9jB24zh0Ymn 8CFlrKvGjFyVZhCXsBcNOrCo+ZhDKslPaUkIl7qyQaCDCwQ2NEhw9QFVYTfECQzxVU8zCWTKOpAo 4RIOk2a5lLfGw0FA2aPooj6k2E4isdrkA7u8oJezs0jOxmgVmANwJmhBMzipsIULKVOw7VWEVbVS J5ZWNaqZJulIy03WLjaHeHB5bhos5t6EIQfBaAReXoLXBFo0HH4wIwPtdxujLCwmCmcZIhniAUlj pO2ejVHVBCnLlRlDtB02GfTB8iVeK0ira7avIe0kQSqKqx0jLove60Qpy+BplIDb0XJkcbE4WYz2 Gl59cX7RQz5OGt4Qzs1wGSUQdannSswCeD/lK2HT/qXFbKp8Gs16ZphbBFV4NWL9PmOw0wcSIdU6 lqFNDfMoTQEWa0lW//lFcOtZGVDSjU6mxcIyJMO/pgX40Q0tGQ6Jr4rBLqxo39nbtJXykSKiGw72 UJ+NxDaG8OtUBXsGVMLrD9MR9A28u9PeNo/c5pwWXfGNmcHZdcySEKftVpdoVskWbhpSroO5K6gH tpXqbow7vSmm5M/IlGIa/89M0fsJvI1YGOgI+PA2WWCkK6XhcaFCDl0oCanfETBImN4B2QLvf+Ex JBW80za/guzqX1tzlocpazhUqm0aIEFhP1KhIGQL2pLJvpcwq6Z7l2XJUkYmowrqysSq3Se7hPV0 D1zSe7uHQkh1003SNmBwR/PPvU8rqB/oIadYb04ny/deWwP/9ORjixmMcvuwGWgy/+cq5uPBdFe1 9IY823uLhugH0zGrllUFCCtsBfW07F9RhVNutbZjzVg8v5gpB1GctRgW84EogXdKSP+D/Y8Kn9mv I3pD7fFt6K0IPm5oZpA2kNXn7OCBdIO0i30YnOyiTSbNyro2HZ2017LN+own3VzuEWdrzU4S71M6 Ox/OXHFOLZ6ls1MPO762a8e6GiJ7tERhaZgdbExgzJe14pcv3r8NgV6HbwgjpqRJJviOJTDM0F1T B1D8VqIhXf0LAAD//wMAUEsDBBQABgAIAAAAIQAN0ZCftgAAABsBAAAnAAAAdGhlbWUvdGhlbWUv X3JlbHMvdGhlbWVNYW5hZ2VyLnhtbC5yZWxzhI9NCsIwFIT3gncIb2/TuhCRJt2I0K3UA4TkNQ02 PyRR7O0NriwILodhvplpu5edyRNjMt4xaKoaCDrplXGawW247I5AUhZOidk7ZLBggo5vN+0VZ5FL KE0mJFIoLjGYcg4nSpOc0IpU+YCuOKOPVuQio6ZByLvQSPd1faDxmwF8xSS9YhB71QAZllCa/7P9 OBqJZy8fFl3+UUFz2YUFKKLGzOAjm6pMBMpburrE3wAAAP//AwBQSwECLQAUAAYACAAAACEA6d4P v/8AAAAcAgAAEwAAAAAAAAAAAAAAAAAAAAAAW0NvbnRlbnRfVHlwZXNdLnhtbFBLAQItABQABgAI AAAAIQCl1qfnwAAAADYBAAALAAAAAAAAAAAAAAAAADABAABfcmVscy8ucmVsc1BLAQItABQABgAI AAAAIQBreZYWgwAAAIoAAAAcAAAAAAAAAAAAAAAAABkCAAB0aGVtZS90aGVtZS90aGVtZU1hbmFn ZXIueG1sUEsBAi0AFAAGAAgAAAAhAKVefS3HBgAA1xsAABYAAAAAAAAAAAAAAAAA1gIAAHRoZW1l L3RoZW1lL3RoZW1lMS54bWxQSwECLQAUAAYACAAAACEADdGQn7YAAAAbAQAAJwAAAAAAAAAAAAAA AADRCQAAdGhlbWUvdGhlbWUvX3JlbHMvdGhlbWVNYW5hZ2VyLnhtbC5yZWxzUEsFBgAAAAAFAAUA XQEAAMwKAAAAADw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25l PSJ5ZXMiPz4NCjxhOmNsck1hcCB4bWxuczphPSJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0 cy5vcmcvZHJhd2luZ21sLzIwMDYvbWFpbiIgYmcxPSJsdDEiIHR4MT0iZGsxIiBiZzI9Imx0MiIg dHgyPSJkazIiIGFjY2VudDE9ImFjY2VudDEiIGFjY2VudDI9ImFjY2VudDIiIGFjY2VudDM9ImFj Y2VudDMiIGFjY2VudDQ9ImFjY2VudDQiIGFjY2VudDU9ImFjY2VudDUiIGFjY2VudDY9ImFjY2Vu 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 AGUAcgBkAGEAbgBhAAAANy6QAcwAAg8FAgICBAMCBP8CAOH/rABACQAAAAAAAACfAQAAAAAAAEMA YQBsAGkAYgByAGkAAABBEpABAQACBAUDBQQGAwIEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQwBh AG0AYgByAGkAYQAgAE0AYQB0AGgAAAAiAAQA8QiIGADwxAIAAGgBAAAAAIR0Jydp5SkHAAAAAAsA BwAAAO4AAABTBQAAAQADAAAABAADEAsAAADuAAAAUwUAAAEAAwAAAAsAAAAAAAAAIQMA8BAAAAAB AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7ARoAbQAtACBgTI0AAAAAAAAAAAAAAAAAAA+BgAAPgYA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAIAAAAAAAAAAAABM4NRAPAQAAgA/P0BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEhQAAAA AAjw/w8BCAE/AADjBAAA////f////3////9/////f////3////9/////f9EQKwAABAAAMgAAAAAA AAAAAAAAAAAAAAAAAAAAACEEAAAAAAAAAAAAAAAAAAAAAAAAEBwAAAUAAAAAAAAAAAB4AAAAeAAA AAAAAAAAAAAAoAUAAAAAAAALAAAAAAAAANwAAAD//xIAAAAAAAAAAAAAAAAAAAAEAFUAcwBlAHIA BgB2AGkAYwB0AG8AcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v8AAAYBAgAAAAAAAAAAAAAA AAAAAAAAAQAAAOCFn/L5T2gQq5EIACsns9kwAAAAWAEAABAAAAABAAAAiAAAAAIAAACQAAAAAwAA AJwAAAAEAAAAqAAAAAUAAAC4AAAABwAAAMQAAAAIAAAA2AAAAAkAAADoAAAAEgAAAPQAAAAKAAAA FAEAAAwAAAAgAQAADQAAACwBAAAOAAAAOAEAAA8AAABAAQAAEAAAAEgBAAATAAAAUAEAAAIAAADj BAAAHgAAAAQAAAAAAAAAHgAAAAQAAAAAAAAAHgAAAAgAAABVc2VyAAAAAB4AAAAEAAAAAAAAAB4A AAAMAAAATm9ybWFsLmRvdG0AHgAAAAgAAAB2aWN0b3IAAB4AAAAEAAAAMTEAAB4AAAAYAAAATWlj cm9zb2Z0IE9mZmljZSBXb3JkAAAAQAAAAADqVvoAAAAAQAAAAABwpdd0n88BQAAAAADGkL9L288B AwAAAAEAAAADAAAA7gAAAAMAAABTBQAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7/AAAGAQIAAAAAAAAAAAAAAAAAAAAAAAEA AAAC1c3VnC4bEJOXCAArLPmuMAAAAOwAAAAMAAAAAQAAAGgAAAAPAAAAcAAAAAUAAAB8AAAABgAA AIQAAAARAAAAjAAAABcAAACUAAAACwAAAJwAAAAQAAAApAAAABMAAACsAAAAFgAAALQAAAANAAAA vAAAAAwAAADJAAAAAgAAAOMEAAAeAAAABAAAAAAAAAADAAAACwAAAAMAAAADAAAAAwAAAD4GAAAD AAAAAAAOAAsAAAAAAAAACwAAAAAAAAALAAAAAAAAAAsAAAAAAAAAHhAAAAEAAAABAAAAAAwQAAAC AAAAHgAAAAkAAADN4Ofi4O3o5QADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkA AAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAABIAAAATAAAAFAAAABUAAAAWAAAAFwAA ABgAAAAZAAAAGgAAABsAAAAcAAAAHQAAAB4AAAAfAAAAIAAAACEAAAAiAAAAIwAAACQAAAAlAAAA JgAAACcAAAAoAAAAKQAAACoAAAArAAAALAAAAC0AAAAuAAAALwAAADAAAAAxAAAAMgAAADMAAAA0 AAAANQAAADYAAAA3AAAAOAAAADkAAAA6AAAAOwAAADwAAAA9AAAAPgAAAD8AAABAAAAAQQAAAEIA AABDAAAARAAAAEUAAABGAAAARwAAAEgAAABJAAAASgAAAEsAAABMAAAATQAAAE4AAABPAAAAUAAA AFEAAABSAAAAUwAAAFQAAABVAAAAVgAAAFcAAABYAAAAWQAAAFoAAABbAAAAXAAAAF0AAAD+//// XwAAAGAAAABhAAAAYgAAAGMAAABkAAAAZQAAAGYAAABnAAAAaAAAAGkAAABqAAAAawAAAGwAAABt AAAAbgAAAG8AAABwAAAAcQAAAHIAAABzAAAA/v///3UAAAB2AAAAdwAAAHgAAAB5AAAAegAAAHsA AAB8AAAAfQAAAH4AAAB/AAAAgAAAAIEAAACCAAAA/v///4QAAACFAAAAhgAAAIcAAACIAAAAiQAA AIoAAAD+////jAAAAI0AAACOAAAAjwAAAJAAAACRAAAAkgAAAP7////9/////f///5YAAAD+//// /v////7///////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// ////////////////////////////UgBvAG8AdAAgAEUAbgB0AHIAeQAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYABQH//////////wMAAAAGCQIAAAAAAMAAAAAA AABGAAAAAAAAAAAAAAAA8E/s30vbzwGYAAAAgAAAAAAAAABEAGEAdABhAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgACAf////////////// /wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF4AAAC5KwAAAAAAADEAVABhAGIA bABlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO AAIBAQAAAAYAAAD/////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdAAAAIkd AAAAAAAAVwBvAHIAZABEAG8AYwB1AG0AZQBuAHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAABoAAgECAAAABQAAAP////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAA+bsAAAAAAAAFAFMAdQBtAG0AYQByAHkASQBuAGYAbwByAG0AYQB0AGkAbwBu AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAACAf///////////////wAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIMAAAAAEAAAAAAAAAUARABvAGMAdQBtAGUAbgB0AFMAdQBt AG0AYQByAHkASQBuAGYAbwByAG0AYQB0AGkAbwBuAAAAAAAAAAAAAAA4AAIBBAAAAP////////// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiwAAAAAQAAAAAAAAAQBDAG8AbQBw AE8AYgBqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIA AgD///////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcgAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAP///////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAEAAAD+//////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// ////////////////////////AQD+/wMKAAD/////BgkCAAAAAADAAAAAAAAARiAAAADE7urz7OXt 8iBNaWNyb3NvZnQgV29yZCA5Ny0yMDAzAAoAAABNU1dvcmREb2MAEAAAAFdvcmQuRG9jdW1lbnQu OAD0ObJxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAA= ------=_NextPart_000_14B7_01CFDBB3.330888E0-- From BATV+cfd817f7015a74b63a27+4054+infradead.org+hch@bombadil.srs.infradead.org Mon Sep 29 05:40:09 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6084D29DFB for ; Mon, 29 Sep 2014 05:40:09 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 3D2A0304039 for ; Mon, 29 Sep 2014 03:40:09 -0700 (PDT) X-ASG-Debug-ID: 1411987207-04cbb073015c53e0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id Ai2SeOu4w9ht0DDG (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 29 Sep 2014 03:40:07 -0700 (PDT) X-Barracuda-Envelope-From: BATV+cfd817f7015a74b63a27+4054+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XYYND-00020Z-0b; Mon, 29 Sep 2014 10:40:07 +0000 Date: Mon, 29 Sep 2014 03:40:06 -0700 From: Christoph Hellwig To: Dave Chinner Cc: Christoph Hellwig , xfs@oss.sgi.com Subject: Re: [PATCH 10/11 v2] xfs: check xfs_buf_read_uncached returns correctly Message-ID: <20140929104006.GB13582@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 10/11 v2] xfs: check xfs_buf_read_uncached returns correctly References: <1411648461-29003-1-git-send-email-david@fromorbit.com> <1411648461-29003-11-git-send-email-david@fromorbit.com> <20140926102148.GF22194@infradead.org> <20140926232012.GQ4945@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140926232012.GQ4945@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411987207 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10018 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS > Updated patch below. Looks good, Reviewed-by: Christoph Hellwig From BATV+cfd817f7015a74b63a27+4054+infradead.org+hch@bombadil.srs.infradead.org Mon Sep 29 05:43:23 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 14B8529DFF for ; Mon, 29 Sep 2014 05:43:23 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id E8F738F8035 for ; Mon, 29 Sep 2014 03:43:19 -0700 (PDT) X-ASG-Debug-ID: 1411987398-04cbb073015c58f0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id fTljjRUdGbJPTCNu (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 29 Sep 2014 03:43:18 -0700 (PDT) X-Barracuda-Envelope-From: BATV+cfd817f7015a74b63a27+4054+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XYYQI-0002ya-E5; Mon, 29 Sep 2014 10:43:18 +0000 Date: Mon, 29 Sep 2014 03:43:18 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: compat_xfs_bstat does not have forkoff Message-ID: <20140929104318.GA10847@infradead.org> X-ASG-Orig-Subj: Re: [PATCH] xfs: compat_xfs_bstat does not have forkoff References: <1411954886-12200-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411954886-12200-1-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411987398 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10018 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Mon, Sep 29, 2014 at 11:41:26AM +1000, Dave Chinner wrote: > From: Dave Chinner > > struct compat_xfs_bstat is missing the di_forkoff field and so does > not fully translate the structure correctly. Fix it. > > Signed-off-by: Dave Chinner > --- > fs/xfs/xfs_ioctl32.c | 2 ++ > fs/xfs/xfs_ioctl32.h | 3 ++- > 2 files changed, 4 insertions(+), 1 deletion(-) Looks good, Reviewed-by: Christoph Hellwig Any chance to get an xfstests test that verifies the forkoff value? Even if it would only reproduce this bug when running 32-bit userspace on a 64-bit kernel it would be useful I think. From BATV+cfd817f7015a74b63a27+4054+infradead.org+hch@bombadil.srs.infradead.org Mon Sep 29 05:44:45 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C5D1B29DFF for ; Mon, 29 Sep 2014 05:44:45 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id A33208F8035 for ; Mon, 29 Sep 2014 03:44:45 -0700 (PDT) X-ASG-Debug-ID: 1411987484-04cb6c50e44daa60001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id 57zBV85N6cpMkLeR (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 29 Sep 2014 03:44:44 -0700 (PDT) X-Barracuda-Envelope-From: BATV+cfd817f7015a74b63a27+4054+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XYYRf-0003jV-Tj; Mon, 29 Sep 2014 10:44:43 +0000 Date: Mon, 29 Sep 2014 03:44:43 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: kill time.h Message-ID: <20140929104443.GB10847@infradead.org> X-ASG-Orig-Subj: Re: [PATCH] xfs: kill time.h References: <1411954911-12278-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411954911-12278-1-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1411987484 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10018 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Mon, Sep 29, 2014 at 11:41:51AM +1000, Dave Chinner wrote: > From: Dave Chinner > > The typedef for timespecs and nanotime() are completely unnecessary, > and delay() can be moved to fs/xfs/linux.h, which means this file > can go away. Looks good, but shouldn't we just kill delay(), too? There's just 11 callers, and none of them in libxfs. Reviewed-by: Christoph Hellwig From BATV+cfd817f7015a74b63a27+4054+infradead.org+hch@bombadil.srs.infradead.org Mon Sep 29 06:06:13 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BAB3A7FD7 for ; Mon, 29 Sep 2014 06:06:13 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 65FC9AC005 for ; Mon, 29 Sep 2014 04:06:10 -0700 (PDT) X-ASG-Debug-ID: 1411988768-04bdf003a059f4e0001-NocioJ Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) by cuda.sgi.com with ESMTP id zagbm18lDnc2wL15 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO); Mon, 29 Sep 2014 04:06:08 -0700 (PDT) X-Barracuda-Envelope-From: BATV+cfd817f7015a74b63a27+4054+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1XYYmO-0006fB-DB; Mon, 29 Sep 2014 11:06:08 +0000 Date: Mon, 29 Sep 2014 04:06:08 -0700 From: Christoph Hellwig To: Olaf Weber Cc: Jeremy Allison , Christoph Hellwig , Dave Chinner , Ben Myers , linux-fsdevel@vger.kernel.org, tinguely@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140929110608.GB17258@infradead.org> X-ASG-Orig-Subj: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <20140922222611.GZ4322@dastard> <5422C540.1060007@sgi.com> <20140924231024.GA4758@dastard> <54257D3F.70302@sgi.com> <20140926165605.GA25274@infradead.org> <20140926170407.GB6012@samba2> <5425C067.7080904@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5425C067.7080904@sgi.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: bombadil.infradead.org[198.137.202.9] X-Barracuda-Start-Time: 1411988768 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10019 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 26, 2014 at 09:37:11PM +0200, Olaf Weber wrote: > My argument against "mount time case-insensitivity" and for "mkfs time > case-insensitivity" is related to switching from the case-sensitive domain > to the case-insensitive one. > > For case-sensitive, from "README" to "readme" there are 64 different > possible filenames. Let's say you create 63 out of these 64. Now remount > the filesystem case-insensitive, and try to open by the 64th version of > "readme". It is not an exact match for any of the 63 candidate files, and a > case-insensitive match to all 63 candidate files. Which of these 63 files > should be opened, and why that one in particular? Well, the point is not that we use the CI-capable hash all the time. I fully expect the current XFS behavior to remain the default for normal systems forever. I just want to make sure that the CI implementation you chose can also allow mixed lookups if we desire. From bfoster@redhat.com Mon Sep 29 07:18:57 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 840A07FCB for ; Mon, 29 Sep 2014 07:18:57 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 72DB9304032 for ; Mon, 29 Sep 2014 05:18:54 -0700 (PDT) X-ASG-Debug-ID: 1411993132-04cb6c50e44e6e80001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id jAAZfz1p5gyZCLBW (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 29 Sep 2014 05:18:53 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8TCINUY001404 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 29 Sep 2014 08:18:23 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8TCINZs006886; Mon, 29 Sep 2014 08:18:23 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 2279F120064; Mon, 29 Sep 2014 08:18:22 -0400 (EDT) Date: Mon, 29 Sep 2014 08:18:21 -0400 From: Brian Foster To: Christoph Hellwig Cc: Dave Chinner , xfs@oss.sgi.com Subject: Re: [PATCH 1/3] xfs: consider freeze levels in xfs_fs_writable() Message-ID: <20140929121821.GA65297@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 1/3] xfs: consider freeze levels in xfs_fs_writable() References: <1411647632-28240-1-git-send-email-david@fromorbit.com> <1411647632-28240-2-git-send-email-david@fromorbit.com> <20140925161756.GA25798@infradead.org> <20140925210330.GG4945@dastard> <20140926094436.GA10692@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140926094436.GA10692@infradead.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411993133 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Sep 26, 2014 at 02:44:36AM -0700, Christoph Hellwig wrote: > On Fri, Sep 26, 2014 at 07:03:30AM +1000, Dave Chinner wrote: > > I can mention it, but it's so trivial I didn't think it was worth > > it. > > It does change behavior, so it should document why that was changed. > > > The changelog says "Hence allow the caller to pass in the freeze > > level it is allowed to write" which is exactly what this code is > > doing. > > The changelog says the you can pass the argument now. It doesn't > say that it did change a caller to pass a different argument, and more > importanly why. > Note that iirc the patch I posted had a bug so this one is preferred, but feel free to steal the commit log/problem description from the old one: http://oss.sgi.com/archives/xfs/2014-08/msg00073.html Brian > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Mon Sep 29 08:21:05 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id E445B7FA5 for ; Mon, 29 Sep 2014 08:21:05 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id D1AC5304032 for ; Mon, 29 Sep 2014 06:21:02 -0700 (PDT) X-ASG-Debug-ID: 1411996857-04cb6c50e64ef7b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 6Ix4xLKfthPoFHBd (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 29 Sep 2014 06:20:58 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8TDKtlZ028511 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 29 Sep 2014 09:20:55 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8TDKsQt012171; Mon, 29 Sep 2014 09:20:55 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 9F36D120064; Mon, 29 Sep 2014 09:20:53 -0400 (EDT) Date: Mon, 29 Sep 2014 09:20:53 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 3/3] xfs: consolidate superblock logging functions Message-ID: <20140929132050.GB65297@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 3/3] xfs: consolidate superblock logging functions References: <1411647632-28240-1-git-send-email-david@fromorbit.com> <1411647632-28240-4-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411647632-28240-4-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411996857 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Sep 25, 2014 at 10:20:32PM +1000, Dave Chinner wrote: > From: Dave Chinner > > We now have several superblock loggin functions that are identical > except for the transaction reservation and whether it shoul dbe a > synchronous transaction or not. Consolidate these all into a single > function, a single reserveration and a sync flag and call it > xfs_sync_sb(). > > Also, xfs_mod_sb() is not really a modification function - it's the > operation of logging the superblock buffer. hence change the name of > it to reflect this. > > Note that we have to change the mp->m_update_flags that are passed > around at mount time to a boolean simply to indicate a superblock > update is needed. > > Signed-off-by: Dave Chinner > --- > fs/xfs/libxfs/xfs_attr_leaf.c | 2 +- > fs/xfs/libxfs/xfs_bmap.c | 10 +++--- > fs/xfs/libxfs/xfs_sb.c | 43 +++++++++++++++++++---- > fs/xfs/libxfs/xfs_sb.h | 42 ++--------------------- > fs/xfs/libxfs/xfs_shared.h | 26 ++++++-------- > fs/xfs/libxfs/xfs_trans_resv.c | 14 -------- > fs/xfs/libxfs/xfs_trans_resv.h | 1 - > fs/xfs/xfs_fsops.c | 29 ---------------- > fs/xfs/xfs_log.c | 17 ++++++++-- > fs/xfs/xfs_mount.c | 77 ++++++------------------------------------ > fs/xfs/xfs_mount.h | 3 +- > fs/xfs/xfs_qm.c | 27 ++------------- > fs/xfs/xfs_qm_syscalls.c | 7 ++-- > fs/xfs/xfs_super.c | 13 +++---- > 14 files changed, 95 insertions(+), 216 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c > index f4a47a7..bcb0ab1 100644 > --- a/fs/xfs/libxfs/xfs_attr_leaf.c > +++ b/fs/xfs/libxfs/xfs_attr_leaf.c > @@ -405,7 +405,7 @@ xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp) > if (!xfs_sb_version_hasattr2(&mp->m_sb)) { > xfs_sb_version_addattr2(&mp->m_sb); > spin_unlock(&mp->m_sb_lock); > - xfs_mod_sb(tp); > + xfs_log_sb(tp); > } else > spin_unlock(&mp->m_sb_lock); > } > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > index e33a780..d40be66 100644 > --- a/fs/xfs/libxfs/xfs_bmap.c > +++ b/fs/xfs/libxfs/xfs_bmap.c > @@ -1224,20 +1224,20 @@ xfs_bmap_add_attrfork( > goto bmap_cancel; > if (!xfs_sb_version_hasattr(&mp->m_sb) || > (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) { > - bool mod_sb = false; > + bool log_sb = false; > > spin_lock(&mp->m_sb_lock); > if (!xfs_sb_version_hasattr(&mp->m_sb)) { > xfs_sb_version_addattr(&mp->m_sb); > - mod_sb = true; > + log_sb = true; > } > if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) { > xfs_sb_version_addattr2(&mp->m_sb); > - mod_sb = true; > + log_sb = true; > } > spin_unlock(&mp->m_sb_lock); > - if (mod_sb) > - xfs_mod_sb(tp); > + if (log_sb) > + xfs_log_sb(tp); > } > > error = xfs_bmap_finish(&tp, &flist, &committed); > diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c > index 2803325..b5ffbe4 100644 > --- a/fs/xfs/libxfs/xfs_sb.c > +++ b/fs/xfs/libxfs/xfs_sb.c > @@ -744,14 +744,13 @@ xfs_initialize_perag_data( > } > > /* > - * xfs_mod_sb() can be used to copy arbitrary changes to the > - * in-core superblock into the superblock buffer to be logged. > - * It does not provide the higher level of locking that is > - * needed to protect the in-core superblock from concurrent > - * access. > + * xfs_log_sb() can be used to copy arbitrary changes to the in-core superblock > + * into the superblock buffer to be logged. It does not provide the higher > + * level of locking that is needed to protect the in-core superblock from > + * concurrent access. > */ > void > -xfs_mod_sb( > +xfs_log_sb( > struct xfs_trans *tp) > { > struct xfs_mount *mp = tp->t_mountp; > @@ -761,3 +760,35 @@ xfs_mod_sb( > xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); > xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb)); > } > + > +/* > + * xfs_sync_sb > + * > + * Sync the superblock to disk. > + * > + * Note that the caller is responsible for checking the frozen state of the > + * filesystem. This procedure uses the non-blocking transaction allocator and > + * thus will allow modifications to a frozen fs. This is required because this > + * code can be called during the process of freezing where use of the high-level > + * allocator would deadlock. > + */ > +int > +xfs_sync_sb( > + struct xfs_mount *mp, > + bool wait) > +{ > + struct xfs_trans *tp; > + int error; > + > + tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_CHANGE, KM_SLEEP); > + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0); > + if (error) { > + xfs_trans_cancel(tp, 0); > + return error; > + } > + > + xfs_log_sb(tp); > + if (wait) > + xfs_trans_set_sync(tp); > + return xfs_trans_commit(tp, 0); > +} > diff --git a/fs/xfs/libxfs/xfs_sb.h b/fs/xfs/libxfs/xfs_sb.h > index c28b3c1..73dff28 100644 > --- a/fs/xfs/libxfs/xfs_sb.h > +++ b/fs/xfs/libxfs/xfs_sb.h > @@ -274,45 +274,6 @@ typedef enum { > XFS_SBS_FIELDCOUNT > } xfs_sb_field_t; > > -/* > - * Mask values, defined based on the xfs_sb_field_t values. > - * Only define the ones we're using. > - */ > -#define XFS_SB_MVAL(x) (1LL << XFS_SBS_ ## x) > -#define XFS_SB_UUID XFS_SB_MVAL(UUID) > -#define XFS_SB_FNAME XFS_SB_MVAL(FNAME) > -#define XFS_SB_ROOTINO XFS_SB_MVAL(ROOTINO) > -#define XFS_SB_RBMINO XFS_SB_MVAL(RBMINO) > -#define XFS_SB_RSUMINO XFS_SB_MVAL(RSUMINO) > -#define XFS_SB_VERSIONNUM XFS_SB_MVAL(VERSIONNUM) > -#define XFS_SB_UQUOTINO XFS_SB_MVAL(UQUOTINO) > -#define XFS_SB_GQUOTINO XFS_SB_MVAL(GQUOTINO) > -#define XFS_SB_QFLAGS XFS_SB_MVAL(QFLAGS) > -#define XFS_SB_SHARED_VN XFS_SB_MVAL(SHARED_VN) > -#define XFS_SB_UNIT XFS_SB_MVAL(UNIT) > -#define XFS_SB_WIDTH XFS_SB_MVAL(WIDTH) > -#define XFS_SB_ICOUNT XFS_SB_MVAL(ICOUNT) > -#define XFS_SB_IFREE XFS_SB_MVAL(IFREE) > -#define XFS_SB_FDBLOCKS XFS_SB_MVAL(FDBLOCKS) > -#define XFS_SB_FEATURES2 XFS_SB_MVAL(FEATURES2) > -#define XFS_SB_BAD_FEATURES2 XFS_SB_MVAL(BAD_FEATURES2) > -#define XFS_SB_FEATURES_COMPAT XFS_SB_MVAL(FEATURES_COMPAT) > -#define XFS_SB_FEATURES_RO_COMPAT XFS_SB_MVAL(FEATURES_RO_COMPAT) > -#define XFS_SB_FEATURES_INCOMPAT XFS_SB_MVAL(FEATURES_INCOMPAT) > -#define XFS_SB_FEATURES_LOG_INCOMPAT XFS_SB_MVAL(FEATURES_LOG_INCOMPAT) > -#define XFS_SB_CRC XFS_SB_MVAL(CRC) > -#define XFS_SB_PQUOTINO XFS_SB_MVAL(PQUOTINO) > -#define XFS_SB_NUM_BITS ((int)XFS_SBS_FIELDCOUNT) > -#define XFS_SB_ALL_BITS ((1LL << XFS_SB_NUM_BITS) - 1) > -#define XFS_SB_MOD_BITS \ > - (XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \ > - XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \ > - XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \ > - XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2 | \ > - XFS_SB_BAD_FEATURES2 | XFS_SB_FEATURES_COMPAT | \ > - XFS_SB_FEATURES_RO_COMPAT | XFS_SB_FEATURES_INCOMPAT | \ > - XFS_SB_FEATURES_LOG_INCOMPAT | XFS_SB_PQUOTINO) > - > > /* > * Misc. Flags - warning - these will be cleared by xfs_repair unless > @@ -612,7 +573,8 @@ extern void xfs_perag_put(struct xfs_perag *pag); > extern int xfs_initialize_perag_data(struct xfs_mount *, xfs_agnumber_t); > > extern void xfs_sb_calc_crc(struct xfs_buf *bp); > -extern void xfs_mod_sb(struct xfs_trans *tp); > +extern void xfs_log_sb(struct xfs_trans *tp); > +extern int xfs_sync_sb(struct xfs_mount *mp, bool wait); > extern void xfs_sb_mount_common(struct xfs_mount *mp, struct xfs_sb *sbp); > extern void xfs_sb_from_disk(struct xfs_sb *to, struct xfs_dsb *from); > extern void xfs_sb_to_disk(struct xfs_dsb *to, struct xfs_sb *from); > diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h > index 82404da..4ae617a 100644 > --- a/fs/xfs/libxfs/xfs_shared.h > +++ b/fs/xfs/libxfs/xfs_shared.h > @@ -82,7 +82,7 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops; > #define XFS_TRANS_ATTR_RM 23 > #define XFS_TRANS_ATTR_FLAG 24 > #define XFS_TRANS_CLEAR_AGI_BUCKET 25 > -#define XFS_TRANS_QM_SBCHANGE 26 > +#define XFS_TRANS_SB_CHANGE 26 > /* > * Dummy entries since we use the transaction type to index into the > * trans_type[] in xlog_recover_print_trans_head() > @@ -95,17 +95,15 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops; > #define XFS_TRANS_QM_DQCLUSTER 32 > #define XFS_TRANS_QM_QINOCREATE 33 > #define XFS_TRANS_QM_QUOTAOFF_END 34 > -#define XFS_TRANS_SB_UNIT 35 > -#define XFS_TRANS_FSYNC_TS 36 > -#define XFS_TRANS_GROWFSRT_ALLOC 37 > -#define XFS_TRANS_GROWFSRT_ZERO 38 > -#define XFS_TRANS_GROWFSRT_FREE 39 > -#define XFS_TRANS_SWAPEXT 40 > -#define XFS_TRANS_SB_COUNT 41 > -#define XFS_TRANS_CHECKPOINT 42 > -#define XFS_TRANS_ICREATE 43 > -#define XFS_TRANS_CREATE_TMPFILE 44 > -#define XFS_TRANS_TYPE_MAX 44 > +#define XFS_TRANS_FSYNC_TS 35 > +#define XFS_TRANS_GROWFSRT_ALLOC 36 > +#define XFS_TRANS_GROWFSRT_ZERO 37 > +#define XFS_TRANS_GROWFSRT_FREE 37 38? FWIW, it also looks like the dummy entries are out of order between these definitions and the XFS_TRANS_TYPES definition below (aesthetic) and a couple of the create entries are missing. > +#define XFS_TRANS_SWAPEXT 39 > +#define XFS_TRANS_CHECKPOINT 40 > +#define XFS_TRANS_ICREATE 41 > +#define XFS_TRANS_CREATE_TMPFILE 42 > +#define XFS_TRANS_TYPE_MAX 43 > /* new transaction types need to be reflected in xfs_logprint(8) */ > > #define XFS_TRANS_TYPES \ > @@ -134,20 +132,18 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops; > { XFS_TRANS_ATTR_RM, "ATTR_RM" }, \ > { XFS_TRANS_ATTR_FLAG, "ATTR_FLAG" }, \ > { XFS_TRANS_CLEAR_AGI_BUCKET, "CLEAR_AGI_BUCKET" }, \ > - { XFS_TRANS_QM_SBCHANGE, "QM_SBCHANGE" }, \ > + { XFS_TRANS_SB_CHANGE, "SBCHANGE" }, \ > { XFS_TRANS_QM_QUOTAOFF, "QM_QUOTAOFF" }, \ > { XFS_TRANS_QM_DQALLOC, "QM_DQALLOC" }, \ > { XFS_TRANS_QM_SETQLIM, "QM_SETQLIM" }, \ > { XFS_TRANS_QM_DQCLUSTER, "QM_DQCLUSTER" }, \ > { XFS_TRANS_QM_QINOCREATE, "QM_QINOCREATE" }, \ > { XFS_TRANS_QM_QUOTAOFF_END, "QM_QOFF_END" }, \ > - { XFS_TRANS_SB_UNIT, "SB_UNIT" }, \ > { XFS_TRANS_FSYNC_TS, "FSYNC_TS" }, \ > { XFS_TRANS_GROWFSRT_ALLOC, "GROWFSRT_ALLOC" }, \ > { XFS_TRANS_GROWFSRT_ZERO, "GROWFSRT_ZERO" }, \ > { XFS_TRANS_GROWFSRT_FREE, "GROWFSRT_FREE" }, \ > { XFS_TRANS_SWAPEXT, "SWAPEXT" }, \ > - { XFS_TRANS_SB_COUNT, "SB_COUNT" }, \ > { XFS_TRANS_CHECKPOINT, "CHECKPOINT" }, \ > { XFS_TRANS_DUMMY1, "DUMMY1" }, \ > { XFS_TRANS_DUMMY2, "DUMMY2" }, \ > diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c > index f2bda7c..7c42e2c 100644 > --- a/fs/xfs/libxfs/xfs_trans_resv.c > +++ b/fs/xfs/libxfs/xfs_trans_resv.c > @@ -718,17 +718,6 @@ xfs_calc_clear_agi_bucket_reservation( > } > > /* > - * Clearing the quotaflags in the superblock. > - * the super block for changing quota flags: sector size > - */ > -STATIC uint > -xfs_calc_qm_sbchange_reservation( > - struct xfs_mount *mp) > -{ > - return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize); > -} > - > -/* > * Adjusting quota limits. > * the xfs_disk_dquot_t: sizeof(struct xfs_disk_dquot) > */ > @@ -866,9 +855,6 @@ xfs_trans_resv_calc( > * The following transactions are logged in logical format with > * a default log count. > */ > - resp->tr_qm_sbchange.tr_logres = xfs_calc_qm_sbchange_reservation(mp); > - resp->tr_qm_sbchange.tr_logcount = XFS_DEFAULT_LOG_COUNT; > - > resp->tr_qm_setqlim.tr_logres = xfs_calc_qm_setqlim_reservation(mp); > resp->tr_qm_setqlim.tr_logcount = XFS_DEFAULT_LOG_COUNT; > > diff --git a/fs/xfs/libxfs/xfs_trans_resv.h b/fs/xfs/libxfs/xfs_trans_resv.h > index 1097d14..2d5bdfc 100644 > --- a/fs/xfs/libxfs/xfs_trans_resv.h > +++ b/fs/xfs/libxfs/xfs_trans_resv.h > @@ -56,7 +56,6 @@ struct xfs_trans_resv { > struct xfs_trans_res tr_growrtalloc; /* grow realtime allocations */ > struct xfs_trans_res tr_growrtzero; /* grow realtime zeroing */ > struct xfs_trans_res tr_growrtfree; /* grow realtime freeing */ > - struct xfs_trans_res tr_qm_sbchange; /* change quota flags */ > struct xfs_trans_res tr_qm_setqlim; /* adjust quota limits */ > struct xfs_trans_res tr_qm_dqalloc; /* allocate quota on disk */ > struct xfs_trans_res tr_qm_quotaoff; /* turn quota off */ > diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c > index 2c44e0b..126b4b3 100644 > --- a/fs/xfs/xfs_fsops.c > +++ b/fs/xfs/xfs_fsops.c > @@ -763,35 +763,6 @@ out: > return 0; > } > > -/* > - * Dump a transaction into the log that contains no real change. This is needed > - * to be able to make the log dirty or stamp the current tail LSN into the log > - * during the covering operation. > - * > - * We cannot use an inode here for this - that will push dirty state back up > - * into the VFS and then periodic inode flushing will prevent log covering from > - * making progress. Hence we log a field in the superblock instead and use a > - * synchronous transaction to ensure the superblock is immediately unpinned > - * and can be written back. > - */ > -int > -xfs_fs_log_dummy( > - xfs_mount_t *mp) > -{ > - xfs_trans_t *tp; > - int error; > - > - tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1, KM_SLEEP); > - error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0); > - if (error) { > - xfs_trans_cancel(tp, 0); > - return error; > - } > - xfs_mod_sb(tp); > - xfs_trans_set_sync(tp); > - return xfs_trans_commit(tp, 0); > -} > - > int > xfs_fs_goingdown( > xfs_mount_t *mp, > diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c > index 7ada70c..b1131fe 100644 > --- a/fs/xfs/xfs_log.c > +++ b/fs/xfs/xfs_log.c > @@ -1292,9 +1292,20 @@ xfs_log_worker( > struct xfs_mount *mp = log->l_mp; > > /* dgc: errors ignored - not fatal and nowhere to report them */ > - if (xfs_log_need_covered(mp)) > - xfs_fs_log_dummy(mp); > - else > + if (xfs_log_need_covered(mp)) { > + /* > + * Dump a transaction into the log that contains no real change. > + * This is needed stamp the current tail LSN into the log during "... to stamp" Brian > + * the covering operation. > + * > + * We cannot use an inode here for this - that will push dirty > + * state back up into the VFS and then periodic inode flushing > + * will prevent log covering from making progress. Hence we > + * synchronously log the superblock instead to ensure the > + * superblock is immediately unpinned and can be written back. > + */ > + xfs_sync_sb(mp, true); > + } else > xfs_log_force(mp, 0); > > /* start pushing all the metadata that is currently dirty */ > diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c > index e555411..78a2799 100644 > --- a/fs/xfs/xfs_mount.c > +++ b/fs/xfs/xfs_mount.c > @@ -416,11 +416,11 @@ xfs_update_alignment(xfs_mount_t *mp) > if (xfs_sb_version_hasdalign(sbp)) { > if (sbp->sb_unit != mp->m_dalign) { > sbp->sb_unit = mp->m_dalign; > - mp->m_update_flags |= XFS_SB_UNIT; > + mp->m_update_sb = true; > } > if (sbp->sb_width != mp->m_swidth) { > sbp->sb_width = mp->m_swidth; > - mp->m_update_flags |= XFS_SB_WIDTH; > + mp->m_update_sb = true; > } > } else { > xfs_warn(mp, > @@ -588,38 +588,18 @@ int > xfs_mount_reset_sbqflags( > struct xfs_mount *mp) > { > - int error; > - struct xfs_trans *tp; > - > mp->m_qflags = 0; > > - /* > - * It is OK to look at sb_qflags here in mount path, > - * without m_sb_lock. > - */ > + /* It is OK to look at sb_qflags in the mount path without m_sb_lock. */ > if (mp->m_sb.sb_qflags == 0) > return 0; > spin_lock(&mp->m_sb_lock); > mp->m_sb.sb_qflags = 0; > spin_unlock(&mp->m_sb_lock); > > - /* > - * If the fs is readonly, let the incore superblock run > - * with quotas off but don't flush the update out to disk > - */ > if (!xfs_fs_writable(mp, SB_UNFROZEN)) > return 0; > - > - tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE); > - error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_sbchange, 0, 0); > - if (error) { > - xfs_trans_cancel(tp, 0); > - xfs_alert(mp, "%s: Superblock update failed!", __func__); > - return error; > - } > - > - xfs_mod_sb(tp); > - return xfs_trans_commit(tp, 0); > + return xfs_sync_sb(mp, false); > } > > __uint64_t > @@ -683,7 +663,7 @@ xfs_mountfs( > xfs_warn(mp, "correcting sb_features alignment problem"); > sbp->sb_features2 |= sbp->sb_bad_features2; > sbp->sb_bad_features2 = sbp->sb_features2; > - mp->m_update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2; > + mp->m_update_sb = true; > > /* > * Re-check for ATTR2 in case it was found in bad_features2 > @@ -697,17 +677,17 @@ xfs_mountfs( > if (xfs_sb_version_hasattr2(&mp->m_sb) && > (mp->m_flags & XFS_MOUNT_NOATTR2)) { > xfs_sb_version_removeattr2(&mp->m_sb); > - mp->m_update_flags |= XFS_SB_FEATURES2; > + mp->m_update_sb = true; > > /* update sb_versionnum for the clearing of the morebits */ > if (!sbp->sb_features2) > - mp->m_update_flags |= XFS_SB_VERSIONNUM; > + mp->m_update_sb = true; > } > > /* always use v2 inodes by default now */ > if (!(mp->m_sb.sb_versionnum & XFS_SB_VERSION_NLINKBIT)) { > mp->m_sb.sb_versionnum |= XFS_SB_VERSION_NLINKBIT; > - mp->m_update_flags |= XFS_SB_VERSIONNUM; > + mp->m_update_sb = true; > } > > /* > @@ -900,8 +880,8 @@ xfs_mountfs( > * the next remount into writeable mode. Otherwise we would never > * perform the update e.g. for the root filesystem. > */ > - if (mp->m_update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY)) { > - error = xfs_mount_log_sb(mp); > + if (mp->m_update_sb && !(mp->m_flags & XFS_MOUNT_RDONLY)) { > + error = xfs_sync_sb(mp, false); > if (error) { > xfs_warn(mp, "failed to write sb changes"); > goto out_rtunmount; > @@ -1101,9 +1081,6 @@ xfs_fs_writable(xfs_mount_t *mp, int frozen_state) > int > xfs_log_sbcount(xfs_mount_t *mp) > { > - xfs_trans_t *tp; > - int error; > - > /* > * We can be called during the fs freeze process, and we need to be > * able to write the superblock in that case. > @@ -1120,17 +1097,7 @@ xfs_log_sbcount(xfs_mount_t *mp) > if (!xfs_sb_version_haslazysbcount(&mp->m_sb)) > return 0; > > - tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_COUNT, KM_SLEEP); > - error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0); > - if (error) { > - xfs_trans_cancel(tp, 0); > - return error; > - } > - > - xfs_mod_sb(tp); > - xfs_trans_set_sync(tp); > - error = xfs_trans_commit(tp, 0); > - return error; > + return xfs_sync_sb(mp, true); > } > > /* > @@ -1424,28 +1391,6 @@ xfs_freesb( > } > > /* > - * Used to log changes to the superblock unit and width fields which could > - * be altered by the mount options, as well as any potential sb_features2 > - * fixup. Only the first superblock is updated. > - */ > -int > -xfs_mount_log_sb( > - xfs_mount_t *mp) > -{ > - xfs_trans_t *tp; > - int error; > - > - tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT); > - error = xfs_trans_reserve(tp, &M_RES(mp)->tr_sb, 0, 0); > - if (error) { > - xfs_trans_cancel(tp, 0); > - return error; > - } > - xfs_mod_sb(tp); > - return xfs_trans_commit(tp, 0); > -} > - > -/* > * If the underlying (data/log/rt) device is readonly, there are some > * operations that cannot proceed. > */ > diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h > index 01f66e5..06f16d5 100644 > --- a/fs/xfs/xfs_mount.h > +++ b/fs/xfs/xfs_mount.h > @@ -162,8 +162,7 @@ typedef struct xfs_mount { > struct delayed_work m_reclaim_work; /* background inode reclaim */ > struct delayed_work m_eofblocks_work; /* background eof blocks > trimming */ > - __int64_t m_update_flags; /* sb flags we need to update > - on the next remount,rw */ > + bool m_update_sb; /* sb needs update in mount */ > int64_t m_low_space[XFS_LOWSP_MAX]; > /* low free space thresholds */ > struct xfs_kobj m_kobj; > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index 1691edb..bfb017d 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -794,7 +794,7 @@ xfs_qm_qino_alloc( > else > mp->m_sb.sb_pquotino = (*ip)->i_ino; > spin_unlock(&mp->m_sb_lock); > - xfs_mod_sb(tp); > + xfs_log_sb(tp); > > if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES))) { > xfs_alert(mp, "%s failed (error %d)!", __func__, error); > @@ -1447,7 +1447,7 @@ xfs_qm_mount_quotas( > spin_unlock(&mp->m_sb_lock); > > if (sbf != (mp->m_qflags & XFS_MOUNT_QUOTA_ALL)) { > - if (xfs_qm_write_sb_changes(mp)) { > + if (xfs_sync_sb(mp, false)) { > /* > * We could only have been turning quotas off. > * We aren't in very good shape actually because > @@ -1576,29 +1576,6 @@ xfs_qm_dqfree_one( > xfs_qm_dqdestroy(dqp); > } > > -/* > - * Start a transaction and write the incore superblock changes to > - * disk. flags parameter indicates which fields have changed. > - */ > -int > -xfs_qm_write_sb_changes( > - struct xfs_mount *mp) > -{ > - xfs_trans_t *tp; > - int error; > - > - tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE); > - error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_sbchange, 0, 0); > - if (error) { > - xfs_trans_cancel(tp, 0); > - return error; > - } > - > - xfs_mod_sb(tp); > - return xfs_trans_commit(tp, 0); > -} > - > - > /* --------------- utility functions for vnodeops ---------------- */ > > > diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c > index 45f28f1..d558306 100644 > --- a/fs/xfs/xfs_qm_syscalls.c > +++ b/fs/xfs/xfs_qm_syscalls.c > @@ -93,7 +93,7 @@ xfs_qm_scall_quotaoff( > mutex_unlock(&q->qi_quotaofflock); > > /* XXX what to do if error ? Revert back to old vals incore ? */ > - return xfs_qm_write_sb_changes(mp); > + return xfs_sync_sb(mp, false); > } > > dqtype = 0; > @@ -370,7 +370,8 @@ xfs_qm_scall_quotaon( > if ((qf & flags) == flags) > return -EEXIST; > > - if ((error = xfs_qm_write_sb_changes(mp))) > + error = xfs_sync_sb(mp, false); > + if (error) > return error; > /* > * If we aren't trying to switch on quota enforcement, we are done. > @@ -795,7 +796,7 @@ xfs_qm_log_quotaoff( > mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL; > spin_unlock(&mp->m_sb_lock); > > - xfs_mod_sb(tp); > + xfs_log_sb(tp); > > /* > * We have to make sure that the transaction is secure on disk before we > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c > index a7d2def..d018f65 100644 > --- a/fs/xfs/xfs_super.c > +++ b/fs/xfs/xfs_super.c > @@ -1254,13 +1254,13 @@ xfs_fs_remount( > * If this is the first remount to writeable state we > * might have some superblock changes to update. > */ > - if (mp->m_update_flags) { > - error = xfs_mount_log_sb(mp); > + if (mp->m_update_sb) { > + error = xfs_sync_sb(mp, false); > if (error) { > xfs_warn(mp, "failed to write sb changes"); > return error; > } > - mp->m_update_flags = 0; > + mp->m_update_sb = false; > } > > /* > @@ -1290,8 +1290,9 @@ xfs_fs_remount( > > /* > * Second stage of a freeze. The data is already frozen so we only > - * need to take care of the metadata. Once that's done write a dummy > - * record to dirty the log in case of a crash while frozen. > + * need to take care of the metadata. Once that's done sync the superblock > + * to the log to dirty it in case of a crash while frozen. This ensures that we > + * will recover the unlinked inode lists on the next mount. > */ > STATIC int > xfs_fs_freeze( > @@ -1301,7 +1302,7 @@ xfs_fs_freeze( > > xfs_save_resvblks(mp); > xfs_quiesce_attr(mp); > - return xfs_fs_log_dummy(mp); > + return xfs_sync_sb(mp, true); > } > > STATIC int > -- > 2.0.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Mon Sep 29 09:09:38 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 28ACB7FED for ; Mon, 29 Sep 2014 09:09:38 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id EECBB30404E for ; Mon, 29 Sep 2014 07:09:34 -0700 (PDT) X-ASG-Debug-ID: 1411999770-04bdf003a15cbdc0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id TpLyDTTFRWKe3gph (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 29 Sep 2014 07:09:30 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8TE9Sc7025041 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 29 Sep 2014 10:09:28 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8TE9SHl014859; Mon, 29 Sep 2014 10:09:28 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 3FC10120064; Mon, 29 Sep 2014 10:09:27 -0400 (EDT) Date: Mon, 29 Sep 2014 10:09:27 -0400 From: Brian Foster To: Dave Chinner Cc: fstests@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH] xfs/053: test for stale data exposure via falloc/writeback interaction Message-ID: <20140929140926.GC65297@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs/053: test for stale data exposure via falloc/writeback interaction References: <1411756349-4537-1-git-send-email-bfoster@redhat.com> <20140929033244.GL4758@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140929033244.GL4758@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1411999770 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Sep 29, 2014 at 01:32:44PM +1000, Dave Chinner wrote: > On Fri, Sep 26, 2014 at 02:32:29PM -0400, Brian Foster wrote: > > XFS buffered I/O writeback has a subtle race condition that leads to > > stale data exposure if the filesystem happens to crash after delayed > > allocation blocks are converted on disk and before data is written back > > to said blocks. > > > > Use file allocation commands to attempt to reproduce a related, but > > slightly different variant of this problem. The associated falloc > > commands can lead to partial writeback that converts an extent larger > > than the range affected by falloc. If the filesystem crashes after the > > extent conversion but before all other cached data is written to the > > extent, stale data can be exposed. > > > > Signed-off-by: Brian Foster > > --- > > > > This fell out of a combination of a conversation with Dave about XFS > > writeback and buffer/cache coherency and some hacking I'm doing on the > > XFS zero range implementation. Note that fpunch currently fails the > > test. Also, this test is XFS specific primarily due to the use of > > godown. > ..... > > +_crashtest() > > +{ > > + cmd=$1 > > + img=$SCRATCH_MNT/$seq.img > > + mnt=$SCRATCH_MNT/$seq.mnt > > + file=$mnt/file > > + > > + # Create an fs on a small, initialized image. The pattern is written to > > + # the image to detect stale data exposure. > > + $XFS_IO_PROG -f -c "truncate 0" -c "pwrite 0 25M" $img \ > > + >> $seqres.full 2>&1 > > + $MKFS_XFS_PROG $MKFS_OPTIONS $img >> $seqres.full 2>&1 > > + > > + mkdir -p $mnt > > + mount $img $mnt > > + > > + echo $cmd > > + > > + # write, run the test command and shutdown the fs > > + $XFS_IO_PROG -f -c "pwrite -S 1 0 64k" -c "$cmd 60k 4k" $file | \ > > + _filter_xfs_io > > So at this point the file is correctly 64k in size in memory. > > > + ./src/godown -f $mnt > > And here you tell godown to flush the log, so if there's a > transaction in the that sets the inode size to 64k. > > > + umount $mnt > > + mount $img $mnt > > Then log recovery will set the file size to 64k, and: > > > + > > + # we generally expect a zero-sized file (this should be silent) > > + hexdump $file > > This comment is not actually correct. I'm actually seeing 64k length > files after recovery in 2 of 3 cases being tested, so I don't think > this is a correct observation. > > Some clarification of what is actually being tested is needed > here. > What output is dumped for the file? I normally see either a zero length file or data that was never written to the file. For example, punch fails with this: +0000000 cdcd cdcd cdcd cdcd cdcd cdcd cdcd cdcd +* +000f000 0000 0000 0000 0000 0000 0000 0000 0000 +* +0010000 I suppose it could be possible to see a non-zero length file with valid data, but I've not seen that occur. Brian > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com From jack@suse.cz Mon Sep 29 11:04:39 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 721077FF6 for ; Mon, 29 Sep 2014 11:04:39 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5F24C304051 for ; Mon, 29 Sep 2014 09:04:39 -0700 (PDT) X-ASG-Debug-ID: 1412006670-04cb6c50e65126f0001-NocioJ Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id QiFPMSbmhJjFqYRj (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 29 Sep 2014 09:04:31 -0700 (PDT) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 85408AB07; Mon, 29 Sep 2014 16:04:29 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 96E8A81C6B; Mon, 29 Sep 2014 17:55:15 +0200 (CEST) Date: Mon, 29 Sep 2014 17:55:15 +0200 From: Jan Kara To: Dave Chinner Cc: Jan Kara , Christoph Hellwig , adilger@dilger.ca, linux-api@vger.kernel.org, xfs@oss.sgi.com, dmonakhov@openvz.org, viro@zeniv.linux.org.uk, Li Xi , linux-fsdevel@vger.kernel.org, tytso@mit.edu, linux-ext4@vger.kernel.org Subject: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project Message-ID: <20140929155515.GE6328@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH 4/4] Adds ioctl interface support for ext4 project References: <1411567470-31799-1-git-send-email-lixi@ddn.com> <1411567470-31799-5-git-send-email-lixi@ddn.com> <20140924162507.GC27000@quack.suse.cz> <20140924162634.GA16886@infradead.org> <20140924170105.GE27000@quack.suse.cz> <20140925075912.GG4758@dastard> <20140925135213.GB15352@quack.suse.cz> <20140925224225.GJ4945@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140925224225.GJ4945@dastard> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: cantor2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1412006670 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10026 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri 26-09-14 08:42:25, Dave Chinner wrote: > On Thu, Sep 25, 2014 at 03:52:13PM +0200, Jan Kara wrote: > > On Thu 25-09-14 17:59:12, Dave Chinner wrote: > > > On Wed, Sep 24, 2014 at 07:01:05PM +0200, Jan Kara wrote: > > > > On Wed 24-09-14 09:26:34, Christoph Hellwig wrote: > > > > > On Wed, Sep 24, 2014 at 06:25:07PM +0200, Jan Kara wrote: > > > > > > On Wed 24-09-14 22:04:30, Li Xi wrote: > > > > > > > This patch adds ioctl interface for setting/getting project of ext4. > > > > > > The patch looks good to me. I was just wondering whether it won't be > > > > > > useful to add an ioctl() which isn't ext4 specific. We could just extend > > > > > > ->setattr() to allow setting of project ID (most filesystems would just > > > > > > return -EOPNOTSUPP but ext4 and xfs could do the right thing) and then call > > > > > > ->setattr from the generic ioctl. That way userspace won't have to care > > > > > > about filesystem type when setting project ID... What do others think? > > > > > > > > > > Absolutely. In general I also wonder why this patch doesn't implement > > > > > the full XFS API. Maybe there is a reason it was considered and > > > > > rejected, but it would be helpful to document why. > > > > Do you mean full get/setfsxattr API? > > > > > > That's a good start. > > > > > > The bigger issue in my mind is that we already have a fully featured > > > quota API that supports project quotas and userspace tools available > > > that manipulate it. xfstests already uses those tools and API > > > for testing project quotas. > > Well, the VFS quota API is trivially extended by adding additional quota > > type so I don't really see about which reinventing of quota API are you > > speaking here... > > It doesn't seem quite as trivial as you make out given all thei > issues so far around increasing MAXQUOTA, the increase in size of > the inode, etc. Well, troubles with increasing MAXQUOTAS is more about expectations that VFS quota subsystem can support only 2 quota types. So we have to do those changes regardless of interface we choose. There is one change necessary in the interface (not done yet) and that is that filesystems using VFS quotas and not supporting project quotas will need to refuse quotactls for project quotas. This won't be necessary if we simply refuse to manipulate project quotas using the standard VFS interface. But I wouldn't call it difficult either. > > > This whole patchset reinvents all the quota APIs, and will require > > > adding support in userspace, and hence require re-inventing all the > > > test infrastructure we already have because it won't be compatible > > > with the existing project quota test code. > > Well, quota-tools will have to extended to know about the new quota type. > > Yes. But that's easy to do. I think teaching xfs quota tools to work with > > ext4 will be a bigger project plus I don't think I want to force sysadmins > > which are used to work with quota-tools to switch to other utilities just > > because of project quotas. > > > > Regarding xfstests - I've checked and most of the project quota tests in > > xfs directory aren't directly usable for ext4 anyway because of other > > functionality ext4 doesn't support. So we'll need to distill the least > > common denominator from them anyway... > > I just did a quick scan - of the ~13 tests in tests/xfs that > exercise project quotas, only 2 of them test things that are xfs > specific (e.g. use xfs_db to peer at things, or use xfs_admin, etc). > The rest all rely on xfs_quota to manage and configure project > quotas but otherwise don't do anything XFS specific. Yeah, I messed up my original check (I originally found like 5 project quota related tests and they were those problematic). I checked again and most of them should be relatively easy to adapt (we'll need some changes for mount options handling but that's inevitable). > We want project quotas to have the same management interface for > administrators regardless of the filesystem they are using. The only > way we can do that is to ensure that the same tools work on either > filesystem, and right now it seems to me that the ext4 NIH syndrome > is winning out over what is best for our users... > > Look, I have no problems with extending the existing quota > interfaces to support project quotas, but that should be a > *secondary* improvement as userspace tools are updated. The > primary goal needs to be "works identically to XFS" and so it needs > to implement the interfaces that are currently used for management > so that we can actually test that it does work identically. So I had another look at the quotactl interface we are speaking about. XFS has the following commands there: Q_XQUOTAON Q_XQUOTAOFF These could be relatively easily hooked up to call appropriate VFS functions. Q_XQUOTARM This doesn't have equivalent in VFS and currently I'm not convinced we want to do the work in filesystems to support this... Q_XGETQSTAT Q_XGETQSTATV This corresponds to Q_GETINFO of VFS quotas although it provides more information. We don't easily have things like number of incore dquots or number of file extents available. There's also no limit on the number of warnings. But other than that diverting these to VFS interfaces through a translation function should be easy. Any idea on what numbers should we present from VFS? BTW how do you set the information? We have Q_SETINFO for that in VFS quotas. Q_XSETQLIM Q_XGETQUOTA These are already handled so they work regardless of the underlying fs type. Q_XQUOTASYNC This is the same as Q_SYNC. For VFS quotas we need to do some work in some cases. So all in all it seems relatively easy to make the VFS and XFS quota interfaces more compatible than they are now and it's a direction I like. I can have a look into that once I finish patches to move i_dquot[] array out of generic inode (which is desirable regardless of project quotas). Honza -- Jan Kara SUSE Labs, CR From anton.gamel@physik.uni-freiburg.de Mon Sep 29 11:47:49 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B5F7A7FFA for ; Mon, 29 Sep 2014 11:47:49 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id A458C8F8035 for ; Mon, 29 Sep 2014 09:47:46 -0700 (PDT) X-ASG-Debug-ID: 1412009264-04cbb073025fa410001-NocioJ Received: from mailgateway3.uni-freiburg.de (mailgateway3.uni-freiburg.de [132.230.2.213]) by cuda.sgi.com with ESMTP id 4dnNvnsqy4AqW6N2 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 29 Sep 2014 09:47:44 -0700 (PDT) X-Barracuda-Envelope-From: anton.gamel@physik.uni-freiburg.de X-Barracuda-Apparent-Source-IP: 132.230.2.213 Delivery-date: Mon, 29 Sep 2014 18:47:45 +0200 Received: from ms2.uni-freiburg.de ([132.230.2.3] helo=uni-freiburg.de) port 34910 by mailgateway3.uni-freiburg.de with esmtp (Exim 4.80.1 #2 built 18-Dec-2013 10:01:47 running on Gentoo) id 1XYe6u-00063t-0M; Mon, 29 Sep 2014 18:47:40 +0200 Received: from proton.ruf.uni-freiburg.de (account anton.gamel@physik.uni-freiburg.de [132.230.8.150] verified) by physik.uni-freiburg.de (CommuniGate Pro SMTP 6.0.9) with ESMTPA id 241337433; Mon, 29 Sep 2014 18:47:37 +0200 Message-ID: <54298D29.5000702@physik.uni-freiburg.de> Date: Mon, 29 Sep 2014 18:47:37 +0200 From: "Gamel Anton J." Organization: =?ISO-8859-1?Q?Universit=E4t_Freiburg?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: sandeen@sandeen.net, Dave Chinner CC: xfs@oss.sgi.com Subject: Re: irregular mkfs.xfs results on identical HW References: <54247484.2030808@physik.uni-freiburg.de> <20140925211901.GH4945@dastard> X-ASG-Orig-Subj: Re: irregular mkfs.xfs results on identical HW In-Reply-To: <20140925211901.GH4945@dastard> Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="------------ms030808090600060105090303" X-Barracuda-Connect: mailgateway3.uni-freiburg.de[132.230.2.213] X-Barracuda-Start-Time: 1412009264 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10028 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This is a cryptographically signed message in MIME format. --------------ms030808090600060105090303 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: quoted-printable Re Dave, Eric and all, thanks a lot for the quick answers. This is definitely a version issue I did not take into account at first. We ran into it when slurm found small differences in scratch space. All (diskless) SL6.5 computenodes have xfsprogs-3.1.1-10.el6.x86_64 installed, but creation of xfs was done with older versions on SL5. Recreation of xfs after disk problems changed the xfs outcome as seen. From the beginning the plan was to recreate xfs at every boot time. For some reason this did not work for (all) the diskless machines and we dropped that in favour of a find+rm. Now I reconsider a format at boot time again. Cheers Anton On 09/25/2014 11:19 PM, Dave Chinner wrote: > On Thu, Sep 25, 2014 at 10:01:08PM +0200, Gamel Anton J. wrote: >> Dear all, >> >> servers with identical disk setup (HW RAID0 H310a): >> >> Disk /dev/sda: 598.9 GB, 598879502336 bytes >> /dev/sda1 1 49152 394813439+ 82 Linux swap / S= olaris >> /dev/sda2 49153 50176 8225280 83 Linux >> /dev/sda3 6399 72809 533446357+ 44 Unknown >> >> mkfs.xfs creates on 28 of them: >> meta-data=3D/dev/sda3 isize=3D256 agcount=3D16, agsize= =3D8335099 blks >> =3D sectsz=3D512 attr=3D1, projid32b= it=3D0 >> data =3D bsize=3D4096 blocks=3D133361584, = imaxpct=3D25 >> =3D sunit=3D0 swidth=3D0 blks >> naming =3Dversion 2 bsize=3D4096 ascii-ci=3D0 >> log =3Dinternal bsize=3D4096 blocks=3D32768, vers= ion=3D1 >> =3D sectsz=3D512 sunit=3D0 blks, laz= y-count=3D1 >> realtime =3Dnone extsz=3D4096 blocks=3D0, rtextent= s=3D0 > > THat's clearly an old version of mkfs - it's selected version 1 logs > and attr1 by default and a log size of only 128MB. mkfs.xfs has > defaulted to v2 logs since 3.0.0 (2007). > >> but on four out of them: >> meta-data=3D/dev/sda3 isize=3D256 agcount=3D4, agsize=3D= 33340398 blks >> =3D sectsz=3D512 attr=3D2, projid32b= it=3D0 >> data =3D bsize=3D4096 blocks=3D133361589, = imaxpct=3D25 >> =3D sunit=3D0 swidth=3D0 blks >> naming =3Dversion 2 bsize=3D4096 ascii-ci=3D0 >> log =3Dinternal bsize=3D4096 blocks=3D65117, vers= ion=3D2 >> =3D sectsz=3D512 sunit=3D0 blks, laz= y-count=3D1 >> realtime =3Dnone extsz=3D4096 blocks=3D0, rtextent= s=3D0 > > Clearly much newer - attr2, log v2, log larger than 128MB... > > mkfs.xfs -V on each of the nodes will tell you that they are running > different versions of mkfs, I think. > >> The only way it worked was to dump nodeA:/dev/sda3 to nodeB:/dev/sda3 >> Is there an explanation? May be I missed something ... hints? > > If you are building a new storage system, then I'd highly recommend > all the nodes run the same software and that software is the newest > possible release you can get.... > > Cheers, > > Dave. > --=20 Beste Gruesse Anton J. Gamel HPC und GRID-Computing Physikalisches Institut Abteilung Professor Schumacher c/o Rechenzentrum der Universit=E4t Freiburg Arbeitsgruppe Dr. Winterer Hermann-Herder-Stra=DFe 10 79104 Freiburg Tel.: ++49 (0)761 203 -4670 -- Es bleibt immer ein Rest - und ein Rest vom Rest. --------------ms030808090600060105090303 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIEQjCC BD4wggMmoAMCAQICAlwKMA0GCSqGSIb3DQEBDQUAMDYxCzAJBgNVBAYTAkRFMRMwEQYDVQQK EwpHZXJtYW5HcmlkMRIwEAYDVQQDEwlHcmlkS2EtQ0EwHhcNMTQwNjMwMTMzMzI2WhcNMTUw NzMwMTMzMzI2WjBUMQswCQYDVQQGEwJERTETMBEGA1UEChMKR2VybWFuR3JpZDEUMBIGA1UE CxMLVW5pRnJlaWJ1cmcxGjAYBgNVBAMTEUFudG9uIEpvc2VmIEdhbWVsMIIBIjANBgkqhkiG 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvx9uDrse74v5oGPzZLMat9I50/WrLOIshXX7jwXxGH/1 RCdOKLOi3nEOg48i4/24IxwlxJNe1XPl8BIhBnKGWeTEt9rmu9rRoir4ogeGnBSm7mTinMOJ TmlonXEiIPerAIjAGdKVZNvCbup557HJ92bMiq/8IoNCpgD+Yu8r6VqoArws2APwVr3U/JcW njFQj0xX6ZMJwuF55HFC1mNQ3QifcobgWaHdFZK//eK9uT/13r5kB/BeX3X1Ha1xom26otPG Rl30bVMPLdxi8VyHK65zPIPGNh7FsXG32FS3iKQDhesXgrxh1heiFgyBff3xS1qa0bYcvUCT F3giJ8KPfQIDAQABo4IBNjCCATIwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBLAwHQYD VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBQDiUhVzQiNx2h2W9g8mGm4 05Y3wTAfBgNVHSMEGDAWgBTGdckorNEL/Dz/ubUe0187gGISNDAtBgNVHREEJjAkgSJhbnRv bi5nYW1lbEBwaHlzaWsudW5pLWZyZWlidXJnLmRlMBwGA1UdEgQVMBOBEWdyaWRrYS1jYUBr aXQuZWR1MDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9ncmlka2EtY2Eua2l0LmVkdS9jcmwv Z3JpZGthLWNybC5kZXIwKAYDVR0gBCEwHzAPBg0rBgEEAZQ2qywBAQEJMAwGCiqGSIb3TAUC AgEwDQYJKoZIhvcNAQENBQADggEBANWSgkn5qzIUp5/XZfuQ42OHhuppguXtrbzblWe2gtkf WOWm4GrX4oRRHaUvIRkjrgOlc7jPHnLRMwccQJf1EMRRNFRqd5RrQeZxetMzxoOG4GxpSxOJ 5wqHoNYThl4c/73Ph2F+dpSBoqsWucUZPbrjcrQTQ0s630uB9XHinDeicidT4WynSAgE13Zl mr2jXDVGTzA7Ja3CTYCZaDZH5KV7fnOBnAxvZnyGAg24eL65fJhEyQxj5oPDjZsnw78UQevt r+n1jdSEI0PzlFi/2/7TX1ZmGOejxvBOd0WwFtzl8omz92R0jRUiDXgg5SV1kEAo5lTgiSMY n92mUIEYlwwxggLOMIICygIBATA8MDYxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpHZXJtYW5H cmlkMRIwEAYDVQQDEwlHcmlkS2EtQ0ECAlwKMAkGBSsOAwIaBQCgggFnMBgGCSqGSIb3DQEJ AzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTE0MDkyOTE2NDczN1owIwYJKoZIhvcN AQkEMRYEFFQnp/Gn1Jsw9C388JbrK/cYtUATMEsGCSsGAQQBgjcQBDE+MDwwNjELMAkGA1UE BhMCREUxEzARBgNVBAoTCkdlcm1hbkdyaWQxEjAQBgNVBAMTCUdyaWRLYS1DQQICXAowTQYL KoZIhvcNAQkQAgsxPqA8MDYxCzAJBgNVBAYTAkRFMRMwEQYDVQQKEwpHZXJtYW5HcmlkMRIw EAYDVQQDEwlHcmlkS2EtQ0ECAlwKMGwGCSqGSIb3DQEJDzFfMF0wCwYJYIZIAWUDBAEqMAsG CWCGSAFlAwQBAjAKBggqhkiG9w0DBzAOBggqhkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAw BwYFKw4DAgcwDQYIKoZIhvcNAwICASgwDQYJKoZIhvcNAQEBBQAEggEAkPdKzmVyUHGLVEbB DAopF+2mcL1Fj+tLRkibbsZnqMmqxlx9tO4HKQyCy+/y3dP9YrN3EWvTJLeXPGz+UjR8BL5+ KjPKv0zFMFKoumR2m1ndUbkUMJ44QmItw91TkauiSyldMb+D2ZiaJsiBf1SE0qmDKyt5CBqS rmwun/EhGKSMbHLSEY48dLXcpChFZ6jNf8M+uvENDvjp7VW6Wu2Fvn76zZGH7fJUEEsYvJVL 9KpazpQ+WvTcN7sUlFv26FEnOW0HWNOnXfNBLW7dwFbMmTSudM8RuNoZyExgzwcVsWH1+iWT RLYigApbqNDKTxxNf1uNd9Yjl3ksiabeCZ+f9gAAAAAAAA== --------------ms030808090600060105090303-- From ratikala@cavblog.com Mon Sep 29 12:35:36 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.0 required=5.0 tests=DEAR_SOMETHING,HTML_MESSAGE, MIME_QP_LONG_LINE autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 346978007 for ; Mon, 29 Sep 2014 12:35:36 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id A8DC4AC001 for ; Mon, 29 Sep 2014 10:35:32 -0700 (PDT) X-ASG-Debug-ID: 1412012128-04cbb07302602560001-NocioJ Received: from smtp.mydomain.com ([191.101.2.73]) by cuda.sgi.com with ESMTP id LEmHJnFU4aUqU3qE for ; Mon, 29 Sep 2014 10:35:28 -0700 (PDT) X-Barracuda-Envelope-From: ratikala@cavblog.com X-Barracuda-Apparent-Source-IP: 191.101.2.73 Received: from ratikala (triband-mum-120.60.39.38.mtnl.net.in [120.60.39.38]) by smtp.mydomain.com (Postfix) with ESMTP id 9E18843A50 for ; Mon, 29 Sep 2014 23:03:17 +0530 (IST) Message-ID: <411-220149129173519718@ratikala> Return-Receipt-To: ratikala@cavblog.com Disposition-Notification-To: ratikala@cavblog.com From: "Ratikala" To: xfs@oss.sgi.com Subject: Get Daily New Customers from Google - Every day | Date: Mon, 29 Sep 2014 23:05:19 +0500 X-ASG-Orig-Subj: Get Daily New Customers from Google - Every day | MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_84815C5ABAF209EF376268C8" X-Barracuda-Connect: UNKNOWN[191.101.2.73] X-Barracuda-Start-Time: 1412012128 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.42 X-Barracuda-Spam-Status: No, SCORE=1.42 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_MJ1963, HTML_MESSAGE, MIME_QP_LONG_LINE, MIME_QP_LONG_LINE_2, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10031 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 MIME_QP_LONG_LINE RAW: Quoted-printable line longer than 76 chars 0.82 MIME_QP_LONG_LINE_2 RAW: Quoted-printable line longer than 76 chars 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 ------=_NextPart_84815C5ABAF209EF376268C8 Content-type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Dear Sir/Madam, For a very small annual fees, we will do following:=20 1) List your website in Trade Directories and Send you PROOF of listing=2E= =20 2) Write 10 NEW, innovative and unique ARTICLE on your website, business o= r company=2E=20 3) Create 2 Press-Release and Media Item =2E=2E=20 4) Create Social Media Accounts=2E=20 5) Create and Market a VIDEO on your company on Youtube and 30+ Video Shar= ing Websites=2E=20 6) Create Facebook & Twitter Profiles=2E=20 7) Manage and improve your Internet Marketing Campaign for the entire year= =2E=20 We are providing Search Engine Optimization (SEO) and Internet Marketing S= ervices to 5000+ clients in US, Africa, UK, Indai and Gulf=2E=20 Send us an email and contact details today with your Website Name=2E=20 Regards, Rati Singh=2E ------=_NextPart_84815C5ABAF209EF376268C8 Content-Type: text/html; charset=US-ASCII Content-Transfer-Encoding: quoted-printable

Dear=20 Customer,

You can get = higher=20 profits and acquire new customer by putting your company's name in Google = &=20 Bing Search Engines=2E

Use our prov= en=20 methodology to boost your business=2E 

For a cost l= ess than=20 Starbucks Coffee, you can get following services to boost your business:

1) List your= website=20 in 10 High-Page Rank Trade Directories and send you PROOF of your listing=2E=

2) Re-Write = content=20 on your website and make your website more compelling and attractive=2E

3) Create Yo= ur=20 Company's Mini-Website on Facebook, Twitter, Linkedin, Google Plus and=20 Youtube=2E

4) Create an= d=20 Configure your Google Analytics account to give real-time  report on = your=20 website visitors=2E

5) Create an= d=20 Configure Google Webmaster account to track and improve site's performance= on=20 Google Search Engine=2E

6) Provide y= ou=20 online LEAD capture and response software to capture/record email address = of=20 person visiting your website=2E

7) Re-design= your=20 website with attractive features & provide web-hosting on high-speed s= erver=2E=20 Provide Domain-Name Renewals=2E

8) Provide y= ou with=20 20 Google Apps Email/ Cloud Computing Account worth US $ 1000=2E Enjoy *be= st*=20 email service in the world from Google=2E

9) Provide y= ou with=20 a software to send 10,000 Email Messages to Target Customers=2E

You get ever= ything=20 required for your online success at one simple and ease-to-understand disc= ounted=20 price=2E

Domain, Host= ing,=20 Content Re-Writing, Website Re-Design, Website Updates, Google Apps, Digit= al=20 Marketing, Social Media, Email Marketing - Everything for a cost less than= =20 Starbucks Coffee=2E (Payable annually in advance)=2E

Respond toda= y to get=20 FREE 20+ Page report on what is missing on your website and how to improve= =20 it=2E

You can also= get=20 FREE 30 Minutes Telephonic Coaching and Training from our Search Engine=20= Optimization and Digital Marketing experts to enhance your success=2E


Ragards,

Ratikala=2E

22-28859041/42

SMS and Whatsapp no=2E 08652522293

------=_NextPart_84815C5ABAF209EF376268C8-- From bfoster@redhat.com Mon Sep 29 14:09:32 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 58F1C8007 for ; Mon, 29 Sep 2014 14:09:32 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 390EE304051 for ; Mon, 29 Sep 2014 12:09:29 -0700 (PDT) X-ASG-Debug-ID: 1412017767-04cbb07302611500001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id FKoKSHXDek1xWC9w (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 29 Sep 2014 12:09:28 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8TJ9OPr028844 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 29 Sep 2014 15:09:25 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8TJ9NYM025662; Mon, 29 Sep 2014 15:09:23 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 0EDE3120064; Mon, 29 Sep 2014 15:09:22 -0400 (EDT) Date: Mon, 29 Sep 2014 15:09:22 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 08/11] xfs: kill xfs_bioerror_relse Message-ID: <20140929190921.GB35666@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 08/11] xfs: kill xfs_bioerror_relse References: <1411648461-29003-1-git-send-email-david@fromorbit.com> <1411648461-29003-9-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411648461-29003-9-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1412017767 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Sep 25, 2014 at 10:34:18PM +1000, Dave Chinner wrote: > From: Dave Chinner > > There is only one caller now - xfs_trans_read_buf_map() - and it has > very well defined call semantics - read, synchronous, and b_iodone > is NULL. Hence it's pretty clear what error handling is necessary > for this case. The bigger problem of untangling > xfs_trans_read_buf_map error handling is left to a future patch. > > Signed-off-by: Dave Chinner > --- > fs/xfs/xfs_buf.c | 39 --------------------------------------- > fs/xfs/xfs_buf.h | 2 -- > fs/xfs/xfs_trans_buf.c | 9 ++++++--- > 3 files changed, 6 insertions(+), 44 deletions(-) > > diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c > index cc6a558..4696ff5 100644 > --- a/fs/xfs/xfs_buf.c > +++ b/fs/xfs/xfs_buf.c > @@ -1074,45 +1074,6 @@ xfs_buf_ioerror_alert( > (__uint64_t)XFS_BUF_ADDR(bp), func, -bp->b_error, bp->b_length); > } > > -/* > - * Same as xfs_bioerror, except that we are releasing the buffer > - * here ourselves, and avoiding the xfs_buf_ioend call. > - * This is meant for userdata errors; metadata bufs come with > - * iodone functions attached, so that we can track down errors. > - */ > -int > -xfs_bioerror_relse( > - struct xfs_buf *bp) > -{ > - int64_t fl = bp->b_flags; > - /* > - * No need to wait until the buffer is unpinned. > - * We aren't flushing it. > - * > - * chunkhold expects B_DONE to be set, whether > - * we actually finish the I/O or not. We don't want to > - * change that interface. > - */ > - XFS_BUF_UNREAD(bp); > - XFS_BUF_DONE(bp); > - xfs_buf_stale(bp); > - bp->b_iodone = NULL; > - if (!(fl & XBF_ASYNC)) { > - /* > - * Mark b_error and B_ERROR _both_. > - * Lot's of chunkcache code assumes that. > - * There's no reason to mark error for > - * ASYNC buffers. > - */ > - xfs_buf_ioerror(bp, -EIO); > - complete(&bp->b_iowait); > - } else { > - xfs_buf_relse(bp); > - } > - > - return -EIO; > -} > - > int > xfs_bwrite( > struct xfs_buf *bp) > diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h > index 44db8cd..d8f57f6 100644 > --- a/fs/xfs/xfs_buf.h > +++ b/fs/xfs/xfs_buf.h > @@ -297,8 +297,6 @@ extern void xfs_buf_iomove(xfs_buf_t *, size_t, size_t, void *, > #define xfs_buf_zero(bp, off, len) \ > xfs_buf_iomove((bp), (off), (len), NULL, XBRW_ZERO) > > -extern int xfs_bioerror_relse(struct xfs_buf *); > - > /* Buffer Utility Routines */ > extern xfs_caddr_t xfs_buf_offset(xfs_buf_t *, size_t); > > diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c > index 96c898e..db4be5b 100644 > --- a/fs/xfs/xfs_trans_buf.c > +++ b/fs/xfs/xfs_trans_buf.c > @@ -324,11 +324,14 @@ xfs_trans_read_buf_map( > */ > if (XFS_FORCED_SHUTDOWN(mp)) { > trace_xfs_bdstrat_shut(bp, _RET_IP_); > - xfs_bioerror_relse(bp); > - } else { > - xfs_buf_iorequest(bp); > + bp->b_flags &= ~(XBF_READ | XBF_DONE); > + xfs_buf_ioerror(bp, -EIO); > + xfs_buf_stale(bp); > + xfs_buf_relse(bp); Where does the xfs_buf_relse() come from in this particular scenario? Shouldn't the bp still remain locked/reffed against the transaction? Brian P.S., I realized it doesn't matter too much because this whole block goes away in the subsequent patch. > + return -EIO; > } > > + xfs_buf_iorequest(bp); > error = xfs_buf_iowait(bp); > if (error) { > xfs_buf_ioerror_alert(bp, __func__); > -- > 2.0.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Mon Sep 29 14:09:44 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_FRT_FOLLOW2 autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 4421A29DFF for ; Mon, 29 Sep 2014 14:09:44 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 23628304048 for ; Mon, 29 Sep 2014 12:09:43 -0700 (PDT) X-ASG-Debug-ID: 1412017782-04cb6c50e6542fe0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id kIFOCuFfFrev4CFf (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 29 Sep 2014 12:09:42 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8TJ9fXE010950 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 29 Sep 2014 15:09:41 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8TJ9fDk004593; Mon, 29 Sep 2014 15:09:41 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 97911120064; Mon, 29 Sep 2014 15:09:39 -0400 (EDT) Date: Mon, 29 Sep 2014 15:09:39 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 11/11] xfs: simplify xfs_zero_remaining_bytes Message-ID: <20140929190939.GC35666@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 11/11] xfs: simplify xfs_zero_remaining_bytes References: <1411648461-29003-1-git-send-email-david@fromorbit.com> <1411648461-29003-12-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411648461-29003-12-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1412017782 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Sep 25, 2014 at 10:34:21PM +1000, Dave Chinner wrote: > From: Christoph Hellwig > > xfs_zero_remaining_bytes() open codes a log of buffer manupulations lot > to do a read forllowed by a write. It can simply be replaced by an followed > uncached read followed by a xfs_bwrite() call. an > > [Christoph, can I get your sign-off for this?] > > Signed-off-by: Dave Chinner > --- Reviewed-by: Brian Foster > fs/xfs/xfs_bmap_util.c | 44 ++++++++++++++------------------------------ > 1 file changed, 14 insertions(+), 30 deletions(-) > > diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c > index 41d9488..c2aaa58 100644 > --- a/fs/xfs/xfs_bmap_util.c > +++ b/fs/xfs/xfs_bmap_util.c > @@ -1122,14 +1122,6 @@ xfs_zero_remaining_bytes( > if (endoff > XFS_ISIZE(ip)) > endoff = XFS_ISIZE(ip); > > - bp = xfs_buf_get_uncached(XFS_IS_REALTIME_INODE(ip) ? > - mp->m_rtdev_targp : mp->m_ddev_targp, > - BTOBB(mp->m_sb.sb_blocksize), 0); > - if (!bp) > - return -ENOMEM; > - > - xfs_buf_unlock(bp); > - > for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { > uint lock_mode; > > @@ -1152,32 +1144,24 @@ xfs_zero_remaining_bytes( > ASSERT(imap.br_startblock != DELAYSTARTBLOCK); > if (imap.br_state == XFS_EXT_UNWRITTEN) > continue; > - XFS_BUF_UNDONE(bp); > - XFS_BUF_UNWRITE(bp); > - XFS_BUF_READ(bp); > - XFS_BUF_SET_ADDR(bp, xfs_fsb_to_db(ip, imap.br_startblock)); > > - error = xfs_buf_submit_wait(bp); > - if (error) { > - xfs_buf_ioerror_alert(bp, > - "xfs_zero_remaining_bytes(read)"); > - break; > - } > + error = xfs_buf_read_uncached(XFS_IS_REALTIME_INODE(ip) ? > + mp->m_rtdev_targp : mp->m_ddev_targp, > + xfs_fsb_to_db(ip, imap.br_startblock), > + BTOBB(mp->m_sb.sb_blocksize), > + 0, &bp, NULL); > + if (error) > + return error; > + > memset(bp->b_addr + > - (offset - XFS_FSB_TO_B(mp, imap.br_startoff)), > - 0, lastoffset - offset + 1); > - XFS_BUF_UNDONE(bp); > - XFS_BUF_UNREAD(bp); > - XFS_BUF_WRITE(bp); > + (offset - XFS_FSB_TO_B(mp, imap.br_startoff)), > + 0, lastoffset - offset + 1); > > - error = xfs_buf_submit_wait(bp); > - if (error) { > - xfs_buf_ioerror_alert(bp, > - "xfs_zero_remaining_bytes(write)"); > - break; > - } > + error = xfs_bwrite(bp); > + xfs_buf_relse(bp); > + if (error) > + return error; > } > - xfs_buf_free(bp); > return error; > } > > -- > 2.0.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfields@fieldses.org Mon Sep 29 15:17:19 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 62E19800D for ; Mon, 29 Sep 2014 15:17:19 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 38F2C8F8033 for ; Mon, 29 Sep 2014 13:17:16 -0700 (PDT) X-ASG-Debug-ID: 1412021833-04bdf003a1606820001-NocioJ Received: from fieldses.org (fieldses.org [174.143.236.118]) by cuda.sgi.com with ESMTP id ptB1XCTYzKwOxvVL (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO); Mon, 29 Sep 2014 13:17:14 -0700 (PDT) X-Barracuda-Envelope-From: bfields@fieldses.org X-Barracuda-Apparent-Source-IP: 174.143.236.118 Received: from bfields by fieldses.org with local (Exim 4.76) (envelope-from ) id 1XYhNK-0001Aq-FL; Mon, 29 Sep 2014 16:16:50 -0400 Date: Mon, 29 Sep 2014 16:16:50 -0400 To: Olaf Weber Cc: Jeremy Allison , Christoph Hellwig , Dave Chinner , Ben Myers , linux-fsdevel@vger.kernel.org, tinguely@sgi.com, xfs@oss.sgi.com Subject: Re: [RFC v2] Unicode/UTF-8 support for XFS Message-ID: <20140929201650.GA3640@fieldses.org> X-ASG-Orig-Subj: Re: [RFC v2] Unicode/UTF-8 support for XFS References: <20140918195650.GI19952@sgi.com> <20140922222611.GZ4322@dastard> <5422C540.1060007@sgi.com> <20140924231024.GA4758@dastard> <54257D3F.70302@sgi.com> <20140926165605.GA25274@infradead.org> <20140926170407.GB6012@samba2> <5425C067.7080904@sgi.com> <20140926194656.GC13066@samba2> <5425C6A6.3060003@sgi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5425C6A6.3060003@sgi.com> User-Agent: Mutt/1.5.21 (2010-09-15) From: "J. Bruce Fields" X-Barracuda-Connect: fieldses.org[174.143.236.118] X-Barracuda-Start-Time: 1412021834 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10037 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 26, 2014 at 10:03:50PM +0200, Olaf Weber wrote: > On 26-09-14 21:46, Jeremy Allison wrote: > >On Fri, Sep 26, 2014 at 09:37:11PM +0200, Olaf Weber wrote: > >> > >>My argument against "mount time case-insensitivity" and for "mkfs > >>time case-insensitivity" is related to switching from the > >>case-sensitive domain to the case-insensitive one. > >> > >>For case-sensitive, from "README" to "readme" there are 64 different > >>possible filenames. Let's say you create 63 out of these 64. Now > >>remount the filesystem case-insensitive, and try to open by the 64th > >>version of "readme". It is not an exact match for any of the 63 > >>candidate files, and a case-insensitive match to all 63 candidate > >>files. Which of these 63 files should be opened, and why that one in > >>particular? > > > >I'm ok with "mkfs time case-insensitivity" - really ! > >Most of my OEMs would set that and claim victory (few > >of them care much about NFS semantics :-). > > I'd say you can have CIFS-style case-insensitive semantics or > NFS-style case-sensitive semantics, but not both. Note the NFSv4 specs do claim to allow case insensitivity. No idea how well clients deal with it. I think rfc3530bis has the most up to date language on NFSv4 internationalization issues: http://tools.ietf.org/html/draft-ietf-nfsv4-rfc3530bis-33 (One nit in the current knfsd: the server doesn't correctly report the case_insensitive attribute. If it had some flag it could check in the filesystem's superblock then it could do that right instead of just assuming 0 as it currently does (see FATTR4_WORD0_CASE_INSENSITIVE in fs/nfsd/nfs4xdr.c:nfsd4_encode_fattr).) --b. From dave@fromorbit.com Mon Sep 29 20:46:28 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id E3E338016 for ; Mon, 29 Sep 2014 20:46:28 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id BBDB5304066 for ; Mon, 29 Sep 2014 18:46:28 -0700 (PDT) X-ASG-Debug-ID: 1412041583-04cbb0730466e750001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id uQf1QTxmoglZK2ik for ; Mon, 29 Sep 2014 18:46:23 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Aq0TACQLKlR5LDjwPGdsb2JhbABggw6IY65kAQEBBpxZFwEGAQEBATg5hGAjGIECAweIar9MhhKKKYQ1BY9Lmh2NEiuBNySBHgEBAQ Received: from ppp121-44-56-240.lns20.syd6.internode.on.net (HELO dastard) ([121.44.56.240]) by ipmail06.adl2.internode.on.net with ESMTP; 30 Sep 2014 11:16:14 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XYmW5-0004N5-5V; Tue, 30 Sep 2014 11:46:13 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XYmW5-0004vq-4H; Tue, 30 Sep 2014 11:46:13 +1000 From: Dave Chinner To: xfs@oss.sgi.com Cc: iusty@k1024.org Subject: [PATCH 0/2] xfs: cleanup XFS_IOC_SETXATTR behaviour Date: Tue, 30 Sep 2014 11:46:03 +1000 X-ASG-Orig-Subj: [PATCH 0/2] xfs: cleanup XFS_IOC_SETXATTR behaviour Message-Id: <1412041565-18873-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1412041583 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10048 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi folks, A while back Iustin Pop sent a patch to fix a problem with being unable to set extent size hint values on directories. That patch - along with new xfstests functionality to always check the scratch device after a test - has pointed out that we allow certain directory only inode flags to be set on other types of inodes (e.g. regular files). It also pointed out that we could set extent size hints on inodes that don't have extent size hint flags set. This patchset does not attempt to fix the original problem, not add any new validation of what is passed from userspace. Instead, it simply ensures that what we end up with on disk is valid. That is, directory only flags are only set on directory inodes, and extent size hints are set if the inode flags are set, otherwise it is cleared. Hence we don't end up with "invalid" state on disk, and so xfstests doesn't get upset with directory only flags being set on non directory inodes. Further followups will be needed to address the original issue of changing extent size hints on directories and handling invalid flag/value combinations from userspace. I have not attempted to solve that problem here because it could have impact on userspace application behaviour and that's a different issue to ensuring we end up with valid inode state on disk. Thoughts, comments, flames? Cheers, Dave. From dave@fromorbit.com Mon Sep 29 20:46:29 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E1E568016 for ; Mon, 29 Sep 2014 20:46:29 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id C73BA8F8050 for ; Mon, 29 Sep 2014 18:46:29 -0700 (PDT) X-ASG-Debug-ID: 1412041583-04cbb0730466e750002-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id pQJfr7qo2yL3Fzb4 for ; Mon, 29 Sep 2014 18:46:28 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgIUACQLKlR5LDjwPGdsb2JhbABggw6BKoc5rmQBAQEGnFkXAQYBAQEBODmEBAEFJy8jEAgYMTkDBxQZiD2/TIYSiimENQW2eisvgkoBAQE Received: from ppp121-44-56-240.lns20.syd6.internode.on.net (HELO dastard) ([121.44.56.240]) by ipmail06.adl2.internode.on.net with ESMTP; 30 Sep 2014 11:16:14 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XYmW5-0004N7-6d; Tue, 30 Sep 2014 11:46:13 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XYmW5-0004vy-5e; Tue, 30 Sep 2014 11:46:13 +1000 From: Dave Chinner To: xfs@oss.sgi.com Cc: iusty@k1024.org Subject: [PATCH 2/2] xfs: only set extent size hint when asked Date: Tue, 30 Sep 2014 11:46:05 +1000 X-ASG-Orig-Subj: [PATCH 2/2] xfs: only set extent size hint when asked Message-Id: <1412041565-18873-3-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1412041565-18873-1-git-send-email-david@fromorbit.com> References: <1412041565-18873-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1412041587 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10048 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner Currently the extent size hint is set unconditionally in xfs_ioctl_setattr(), even when the FSX_EXTSIZE flag is not set. This means we can set values from uninitialised stack variables. Hence only set the extent size hint from userspace when both the mask falg is set and the inode has the XFS_DIFLAG_EXTSIZE flag set to indicate that we should have an extent size hint set on the inode. Signed-off-by: Dave Chinner --- fs/xfs/xfs_ioctl.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 87c3bd1..24c926b 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -1231,13 +1231,25 @@ xfs_ioctl_setattr( } - if (mask & FSX_EXTSIZE) - ip->i_d.di_extsize = fa->fsx_extsize >> mp->m_sb.sb_blocklog; if (mask & FSX_XFLAGS) { xfs_set_diflags(ip, fa->fsx_xflags); xfs_diflags_to_linux(ip); } + /* + * Only set the extent size hint if we've already determined that the + * extent size hint should be set on the inode. If no extent size flags + * are set on the inode then unconditionally clear the extent size hint. + */ + if (mask & FSX_EXTSIZE) { + int extsize = 0; + + if (ip->i_d.di_flags & + (XFS_DIFLAG_EXTSIZE | XFS_DIFLAG_EXTSZINHERIT)) + extsize = fa->fsx_extsize >> mp->m_sb.sb_blocklog; + ip->i_d.di_extsize = extsize; + } + xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); -- 2.0.0 From dave@fromorbit.com Mon Sep 29 20:46:30 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id DEB048016 for ; Mon, 29 Sep 2014 20:46:30 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id B64218F8039 for ; Mon, 29 Sep 2014 18:46:30 -0700 (PDT) X-ASG-Debug-ID: 1412041588-04cb6c50e45e0ed0001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id A6QtzttuB7VSrPcO for ; Mon, 29 Sep 2014 18:46:28 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgYUACQLKlR5LDjwPGdsb2JhbABggw6BKoc5rmQBAQEGiy6RKxcBBgEBAQE4OYQEAQUnLyMQCBgxOQMHFBmIPb9MhhKKKYQ1BZcmkkkEjQcrL4JKAQEB Received: from ppp121-44-56-240.lns20.syd6.internode.on.net (HELO dastard) ([121.44.56.240]) by ipmail06.adl2.internode.on.net with ESMTP; 30 Sep 2014 11:16:14 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1XYmW5-0004N6-61; Tue, 30 Sep 2014 11:46:13 +1000 Received: from dave by disappointment with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1XYmW5-0004vt-57; Tue, 30 Sep 2014 11:46:13 +1000 From: Dave Chinner To: xfs@oss.sgi.com Cc: iusty@k1024.org Subject: [PATCH 1/2] xfs: project id inheritance is a directory only flag Date: Tue, 30 Sep 2014 11:46:04 +1000 X-ASG-Orig-Subj: [PATCH 1/2] xfs: project id inheritance is a directory only flag Message-Id: <1412041565-18873-2-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.0.0 In-Reply-To: <1412041565-18873-1-git-send-email-david@fromorbit.com> References: <1412041565-18873-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1412041588 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10048 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner xfs_set_diflags() allows it to be set on non-directory inodes, and this flags errors in xfs_repair. Further, inode allocation allows the same directory-only flag to be inherited to non-directories. Make sure directory inode flags don't appear on other types of inodes. This fixes several xfstests scratch fileystem corruption reports (e.g. xfs/050) now that xfstests checks scratch filesystems after test completion. Signed-off-by: Dave Chinner --- fs/xfs/xfs_inode.c | 4 ++-- fs/xfs/xfs_ioctl.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index f07b443..8ed049d 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -769,6 +769,8 @@ xfs_ialloc( di_flags |= XFS_DIFLAG_EXTSZINHERIT; ip->i_d.di_extsize = pip->i_d.di_extsize; } + if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) + di_flags |= XFS_DIFLAG_PROJINHERIT; } else if (S_ISREG(mode)) { if (pip->i_d.di_flags & XFS_DIFLAG_RTINHERIT) di_flags |= XFS_DIFLAG_REALTIME; @@ -789,8 +791,6 @@ xfs_ialloc( if ((pip->i_d.di_flags & XFS_DIFLAG_NOSYMLINKS) && xfs_inherit_nosymlinks) di_flags |= XFS_DIFLAG_NOSYMLINKS; - if (pip->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) - di_flags |= XFS_DIFLAG_PROJINHERIT; if ((pip->i_d.di_flags & XFS_DIFLAG_NODEFRAG) && xfs_inherit_nodefrag) di_flags |= XFS_DIFLAG_NODEFRAG; diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 7a6b406..87c3bd1 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -968,8 +968,6 @@ xfs_set_diflags( di_flags |= XFS_DIFLAG_NOATIME; if (xflags & XFS_XFLAG_NODUMP) di_flags |= XFS_DIFLAG_NODUMP; - if (xflags & XFS_XFLAG_PROJINHERIT) - di_flags |= XFS_DIFLAG_PROJINHERIT; if (xflags & XFS_XFLAG_NODEFRAG) di_flags |= XFS_DIFLAG_NODEFRAG; if (xflags & XFS_XFLAG_FILESTREAM) @@ -981,6 +979,8 @@ xfs_set_diflags( di_flags |= XFS_DIFLAG_NOSYMLINKS; if (xflags & XFS_XFLAG_EXTSZINHERIT) di_flags |= XFS_DIFLAG_EXTSZINHERIT; + if (xflags & XFS_XFLAG_PROJINHERIT) + di_flags |= XFS_DIFLAG_PROJINHERIT; } else if (S_ISREG(ip->i_d.di_mode)) { if (xflags & XFS_XFLAG_REALTIME) di_flags |= XFS_DIFLAG_REALTIME; -- 2.0.0 From jianpeng.ma@intel.com Mon Sep 29 21:39:33 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 621BD7FD1 for ; Mon, 29 Sep 2014 21:39:33 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id F0E04AC008 for ; Mon, 29 Sep 2014 19:39:32 -0700 (PDT) X-ASG-Debug-ID: 1412044771-04cbb07304670570001-NocioJ Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by cuda.sgi.com with ESMTP id OAfEgEuaqhFaOMeW for ; Mon, 29 Sep 2014 19:39:31 -0700 (PDT) X-Barracuda-Envelope-From: jianpeng.ma@intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.93 X-Barracuda-IPDD: Level2 [intel.com/192.55.52.93] Received: from azsmga001.ch.intel.com ([10.2.17.19]) by fmsmga102.fm.intel.com with ESMTP; 29 Sep 2014 19:39:30 -0700 X-Barracuda-IPDD: Level2 [intel.com/192.55.52.93] X-Barracuda-IPDD: Level2 [intel.com/192.55.52.93] X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.04,624,1406617200"; d="scan'208";a="480883395" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by azsmga001.ch.intel.com with ESMTP; 29 Sep 2014 19:39:30 -0700 Received: from fmsmsx152.amr.corp.intel.com (10.18.125.5) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.195.1; Mon, 29 Sep 2014 19:39:29 -0700 Received: from shsmsx104.ccr.corp.intel.com (10.239.110.15) by FMSMSX152.amr.corp.intel.com (10.18.125.5) with Microsoft SMTP Server (TLS) id 14.3.195.1; Mon, 29 Sep 2014 19:39:30 -0700 Received: from shsmsx101.ccr.corp.intel.com ([169.254.1.203]) by SHSMSX104.ccr.corp.intel.com ([169.254.5.230]) with mapi id 14.03.0195.001; Tue, 30 Sep 2014 10:39:29 +0800 From: "Ma, Jianpeng" To: "xfs@oss.sgi.com" Subject: Question: How to use systemtap count the total inode read from disk Thread-Topic: Question: How to use systemtap count the total inode read from disk X-ASG-Orig-Subj: Question: How to use systemtap count the total inode read from disk Thread-Index: Ac/cVt4En3gsc1Z+SWqcVqynRHXRHA== Date: Tue, 30 Sep 2014 02:39:28 +0000 Message-ID: <6AA21C22F0A5DA478922644AD2EC308C8C986B@SHSMSX101.ccr.corp.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Barracuda-Connect: mga11.intel.com[192.55.52.93] X-Barracuda-Start-Time: 1412044771 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hi all, I want to count the total read inode from disk.=20 I count the call number of xfs_dinoe_from_disk. But at the same time, I use blktrace to trace all read-meta operation. And= using xfs_db to analysis the read-operation. I found more meta-read are re= ad inode. But the count of systemtap is zero. The script of systemtap #! /usr/bin/env stap global count function report() { printf("total count %u\n", count) } probe module("xfs").function("xfs_dinode_from_disk") { count++ } probe end { report() } probe begin { printf("starting probe\n") count =3D 0 } Who know why? And How to do which can achieve my aim. Thanks! From avdej83@tannoy.com Mon Sep 29 23:29:26 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.2 required=5.0 tests=HTML_MESSAGE,MIME_HTML_ONLY autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C828429DFB for ; Mon, 29 Sep 2014 23:29:26 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id B63638F8035 for ; Mon, 29 Sep 2014 21:29:23 -0700 (PDT) X-ASG-Debug-ID: 1412051342-04cbb07301673bd0001-NocioJ Received: from mail.proxen.kiev.ua (mail.proxen.kiev.ua [87.76.66.186]) by cuda.sgi.com with ESMTP id FNOlHPwKYU50LEEl (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Mon, 29 Sep 2014 21:29:04 -0700 (PDT) X-Barracuda-Envelope-From: avdej83@tannoy.com X-Barracuda-Apparent-Source-IP: 87.76.66.186 Received: from Unknown ([193.238.111.14]) (authenticated bits=0) by mail.proxen.kiev.ua (8.14.9/8.14.9) with ESMTP id s8U4Shj6064827; Tue, 30 Sep 2014 07:28:44 +0300 (EEST) (envelope-from avdej83@tannoy.com) Message-ID: <7B7EC89B904463904C49008A0E8B4A23@uuejqp> From: =?windows-1251?B?yuDk4PHy8O7i4P8g7vbl7erg?= To: , , , Subject: =?windows-1251?B?6Ofs5e3l7ej/IOIg5+Xs5ev87fvpIOru5OXq?= =?windows-1251?B?8SAyMDE0?= Date: Tue, 30 Sep 2014 06:28:43 +0200 X-ASG-Orig-Subj: =?windows-1251?B?6Ofs5e3l7ej/IOIg5+Xs5ev87fvpIOru5OXq?= =?windows-1251?B?8SAyMDE0?= MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_05E1_01CFDC77.C7E84260" X-Priority: 3 X-Barracuda-Connect: mail.proxen.kiev.ua[87.76.66.186] X-Barracuda-Start-Time: 1412051343 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_TG035a, HTML_MESSAGE, MIME_HTML_ONLY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10052 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 BSF_SC0_TG035a Message contains invalid style definition This is a multi-part message in MIME format. ------=_NextPart_000_05E1_01CFDC77.C7E84260 Content-Type: text/html; charset="windows-1251" Content-Transfer-Encoding: quoted-printable
=CE=EF=F0=E5=E4=E5=EB=E5=ED =EF=E5=F0=E5=F7=E5=ED=FC =EC=E5=F0=EE=EF= =F0=E8=FF=F2=E8=E9 =EF=EE =F0=E5=E0=EB=E8=E7=E0=F6=E8=E8 =CF=C7=C7 =ED=E0= =F0=E5=E3=E8=EE=ED=E0=EB=FC=ED=EE=EC =E8=20 =EC=F3=ED=E8=F6=E8=EF=E0=EB=FC=ED=EE=EC =F3=F0=EE=E2=ED=E5!
 
=CA=EE=ED=F1=F3=EB=FC=F2=E0=F6=E8=E8 =F1=EF=E5=F6=E8=E0=EB=E8=F1=F2=EE= =E2 =D6=E5=ED=F2=F0=E0 =E7=E5=EC=E5=EB=FC=ED=EE=E3=EE =EF=F0=E0=E2=E0 - =C2= =D1=DF =C8=CD=D4=CE=D0=CC=C0=D6=C8=DF =C2=CE=20 =C2=CB=CE=C6=C5=CD=CD=CD=CE=CC =D4=C0=C9=CB=C5.
------=_NextPart_000_05E1_01CFDC77.C7E84260 Content-Type: application/msword; name="=?windows-1251?B?6u7t8fPr/PLg9uj/LmRvYw==?=" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="=?windows-1251?B?6u7t8fPr/PLg9uj/LmRvYw==?=" 0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAAAAAAACAAAAyQAAAAAAAAAA EAAAywAAAAEAAAD+////AAAAAMcAAADIAAAA//////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////s pcEAX8AZBAAA+BK/AAAAAAAAEAAAAAAACAAAOigAAA4AYmpiagAVABUAAAAAAAAAAAAAAAAAAAAA AAAZBBYAxwABAGJ/AABifwAAzQkAAAAAAAANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//w8AAAAA AAAAAAD//w8AAAAAAAAAAAD//w8AAAAAAAAAAAAAAAAAAAAAALcAAAAAAMAHAAAAAAAAwAcAAAgV AAAAAAAACBUAAAAAAAAIFQAAAAAAAAgVAAAAAAAACBUAABQAAAAAAAAAAAAAAP////8AAAAAHBUA AAAAAAAcFQAAAAAAABwVAAA4AAAAVBUAACwAAACAFQAAJAAAABwVAAAAAAAAqicAAOIBAACkFQAA AAAAAKQVAAAAAAAApBUAAAAAAACkFQAAAAAAAKQVAAAAAAAAJxgAAAAAAAAnGAAAAAAAACcYAAAA AAAAHScAAAIAAAAfJwAAAAAAAB8nAAAAAAAAHycAAAAAAAAfJwAAAAAAAB8nAAAAAAAAHycAACQA AACMKQAAsgIAAD4sAABQAAAAQycAACEAAAAAAAAAAAAAAAAAAAAAAAAACBUAAAAAAAAnGAAAAAAA AAAAAAAAAAAAAAAAAAAAAADnFwAAQAAAACcYAAAAAAAAJxgAAAAAAAAnGAAAAAAAAEMnAAAAAAAA AAAAAAAAAAAIFQAAAAAAAAgVAAAAAAAApBUAAAAAAAAAAAAAAAAAAKQVAABDAgAAZCcAABYAAABH GAAAAAAAAEcYAAAAAAAARxgAAAAAAAAnGAAAEAAAAAgVAAAAAAAApBUAAAAAAAAIFQAAAAAAAKQV AAAAAAAAHScAAAAAAAAAAAAAAAAAAEcYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAJxgAAAAAAAAdJwAAAAAAAAAAAAAAAAAARxgAAAAAAABHGAAA qgAAAIckAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/yUAAAAAAACkFQAAAAAAAP////8AAAAAADEEryLc zwEAAAAAAAAAAP////8AAAAANxgAABAAAAADJQAAEgAAAAAAAAAAAAAACScAABQAAAB6JwAAMAAA AKonAAAAAAAAFSUAAOoAAACOLAAAAAAAAEcYAAAAAAAAjiwAACQAAAD/JQAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ JQAAHgAAAI4sAAAAAAAAAAAAAAAAAAAIFQAAAAAAAB0mAADsAAAAJxgAAAAAAAAnGAAAAAAAAEcY AAAAAAAAJxgAAAAAAAAnGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJxgA AAAAAAAnGAAAAAAAACcYAAAAAAAAQycAAAAAAABDJwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAARxgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACcYAAAA AAAAJxgAAAAAAAAnGAAAAAAAAKonAAAAAAAAJxgAAAAAAAAnGAAAAAAAACcYAAAAAAAAJxgAAAAA AAAAAAAAAAAAAP////8AAAAA/////wAAAAD/////AAAAAAAAAAAAAAAA/////wAAAAD/////AAAA AP////8AAAAA/////wAAAAD/////AAAAAP////8AAAAA/////wAAAAD/////AAAAAP////8AAAAA /////wAAAAD/////AAAAAP////8AAAAA/////wAAAAD/////AAAAAI4sAAAAAAAAJxgAAAAAAAAn GAAAAAAAACcYAAAAAAAAJxgAAAAAAAAnGAAAAAAAACcYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnGAAAAAAAACcYAAAAAAAAJxgA AAAAAADABwAADgwAAM4TAAA6AQAABQASAQAAGQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEABwAH AA0AMwQuACAAIQQwBD0EOgRCBC0AHwQ1BEIENQRABDEEQwRABDMELAAgAA0AJgQ1BD0EQgRABCAA GgRABDAEQgQ6BD4EQQRABD4ERwQ9BEsERQQgAB8EQAQ+BDMEQAQwBDwEPAQgAB4EMQRDBEcENQQ9 BDgETwQNACIENQQ7BFwARAQwBDoEQQQgACgAOAAxADIAKQAgADkAOAA3ACAAOAAzACAANAA5AA0A GARBBEUEFiFfAF8AXwBfAF8AXwBfAF8AXwBfADgAMAAwAF8AXwBfAF8AXwBfAF8AXwBfAF8AXwBf AF8ADQAeBEIEIABfAF8AXwBfAF8AXwAzADAALgAwADkALgAyADAAMQA0AF8AXwBfAF8AXwBfAF8A XwBfAF8AXwBfAA0ABwAHAA0AEgQgAE4EQAQ4BDQEOARHBDUEQQQ6BDgEOQQgADQENQQ/BDAEQARC BDAEPAQ1BD0EQgQNAA0AIQQ/BDUERgQ4BDAEOwQ4BEEEQgRDBCAAPwQ+BCAAPgREBD4EQAQ8BDsE NQQ9BDgETgQgAD0ENQQ0BDIEOAQ2BDgEPAQ+BEEEQgQ4BA0ADQAjBD8EQAQwBDIEOwQ1BD0EOAQ1 BCAAOgQwBD8EOARCBDAEOwRMBD0EPgQzBD4EIABBBEIEQAQ+BDgEQgQ1BDsETARBBEIEMgQwBA0A DQANAA0ADQANAA0ADQANAA0AGAQ9BEQEPgRABDwEMARGBDgEPgQ9BD0EPgQ1BCAAPwQ4BEEETAQ8 BD4EDQANAB0EPgQyBD4ENQQgADIEIAA/BEAEMAQyBD4EMgQ+BDwEIABABDUEMwRDBDsEOARABD4E MgQwBD0EOAQ4BCAAPgREBD4EQAQ8BDsENQQ9BDgETwQgAD8EQAQwBDIEIAA9BDAEIAA+BDEESgQ1 BDoEQgRLBCAAPQQ1BDQEMgQ4BDYEOAQ8BD4EQQRCBDgELgAgAA0AMgAyADEALQAkBBcEIACrAB4E IAAzBD4EQQRDBDQEMARABEEEQgQyBDUEPQQ9BD4EPAQgADoEMAQ0BDAEQQRCBEAENQQgAD0ENQQ0 BDIEOAQ2BDgEPAQ+BEEEQgQ4BLsALgAgABoEMAQ0BDAEQQRCBEAEPgQyBEsEOQQgAEMERwQ1BEIE LAAgADwENQQ2BDUEMgRLBDUEIAA/BDsEMAQ9BEsELAAgAD4ERgQ1BD0EOgQwBCAAPQQ1BDQEMgQ4 BDYEOAQ8BD4EQQRCBDgELgAgAB8EPgRBBDsENQQ0BD0EOAQ1BCAAOAQ3BDwENQQ9BDUEPQQ4BE8E IAAyBCAANwQwBDoEPgQ9BD4ENAQwBEIENQQ7BEwEQQRCBDIENQQsACAAMARABDEEOARCBEAEMAQ2 BD0EMARPBCAAPwRABDAEOgRCBDgEOgQwBC4AIAANAA0AIQQ1BDwEOAQ9BDAEQAQgADEAMwAgAC0A IAAxADQAIAA+BDoEQgRPBDEEQARPBCwAIAAhBDAEPQQ6BEIELQAfBDUEQgQ1BEAEMQRDBEAEMwQu AA0ADQAQBDoEQgRDBDAEOwRMBD0ESwQ1BCAAQgQ1BDwESwQ6AA0AHwQ+BEEEOwQ1BDQEPQQ4BDUE IAA4BDcEPAQ1BD0ENQQ9BDgETwQgADIEIAA/BEAEMAQyBD4EMgQ+BDwEIABABDUEMwRDBDsEOARA BD4EMgQwBD0EOAQ4BCAAPgREBD4EQAQ8BDsENQQ9BDgETwQgAD8EQAQwBDIEIAA9BDAEIAA+BDEE SgQ1BDoEQgRLBCAAPQQ1BDQEMgQ4BDYEOAQ8BD4EQQRCBDgEOgAgADMEQAQwBDYENAQwBD0EQQQ6 BD4ENQQsACAANwQ1BDwENQQ7BEwEPQQ+BDUELAAgADMEQAQwBDQEPgRBBEIEQAQ+BDgEQgQ1BDsE TAQ9BD4ENQQsACAAOgQwBDQEMARBBEIEQAQ+BDIEPgQtAEAENQQzBDgEQQRCBEAEMARGBDgEPgQ9 BD0EPgQ1BCAANwQwBDoEPgQ9BD4ENAQwBEIENQQ7BEwEQQRCBDIEPgQgADIEIAAyADAAMQA0ACAA MwQuACAAGgQ+BDwEPAQ1BD0EQgQwBEAEOAQ4BCAAOgQgADgENwQ8BDUEPQQ1BD0EOARPBDwEIAAy BCAAMgAyADEALQAkBBcEIACrAB4EIAAzBD4EQQRDBDQEMARABEEEQgQyBDUEPQQ9BD4EPAQgADoE MAQ0BDAEQQRCBEAENQQgAD0ENQQ0BDIEOAQ2BDgEPAQ+BEEEQgQ4BLsAIAAoABMEGgQdBCkALgAg AA0AGgQwBEIENQQzBD4EQAQ4BDgEIAA3BDUEPAQ1BDsETAQsACAAQgQ1BEAEQAQ4BEIEPgRABDgE MAQ7BEwEPQRLBDUEIAA4BCAARARDBD0EOgRGBDgEPgQ9BDAEOwRMBD0ESwQ1BCAANwQ+BD0ESwQs ACAAIAAyBDgENARLBCAAQAQwBDcEQAQ1BEgEUQQ9BD0EPgQzBD4EIAA4BEEEPwQ+BDsETAQ3BD4E MgQwBD0EOARPBCAANwQ1BDwENQQ7BEwEPQRLBEUEIABDBEcEMARBBEIEOgQ+BDIEIAA0BDsETwQg AEEEQgRABD4EOARCBDUEOwRMBEEEQgQyBDAEIABABDAENwQ7BDgERwQ9BEsERQQgAD4EMQRKBDUE OgRCBD4EMgQsACAAPwQ1BEAENQQyBD4ENAQgADgEIAA4BDcEPAQ1BD0ENQQ9BDgENQQgADIEOAQ0 BDAEIABABDAENwRABDUESARRBD0EPQQ+BDMEPgQgADgEQQQ/BD4EOwRMBDcEPgQyBDAEPQQ4BE8E IAA3BDUEPAQ1BDsETAQ9BD4EMwQ+BCAAQwRHBDAEQQRCBDoEMAQsACAAPgREBD4EQAQ8BDsENQQ9 BDgENQQgADcENQQ8BDsENQQ/BD4EOwRMBDcEPgQyBDAEPQQ4BE8EIAA0BDsETwQgADgENwRLBEEE OgQwBEIENQQ7BEwEQQQ6BDgERQQgAEAEMAQxBD4EQgQuACAAGgRABDgEQgQ1BEAEOAQ4BCAAPgRC BD0ENQRBBDUEPQQ4BE8EIAA+BDEESgQ1BDoEQgQ+BDIEIAA6BCAAOAQ8BDUETgRJBDgEPAQgADME PgRBBEMENAQwBEAEQQRCBDIENQQ9BD0EPgQ1BCAAOAQ7BDgEIAA8BEMEPQQ4BEYEOAQ/BDAEOwRM BD0EPgQ1BCAANwQ9BDAERwQ1BD0EOAQ1BC4ADQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAggAAAQI AAAGCAAACAgAAA4IAAAwCAAAfAgAAH4IAACQCAAAoAgAAK4IAACwCAAAzAgAANIIAAAACQAABAkA AAgJAADm1c66pJGkun9qWLrVStVKOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxVo8SqgABZon0of AD4qAUNKFABPSgAAUUoAAF5KAABhShQAGhZon0ofAENKFABPSgAAUUoAAF5KAABhShQAACMMKgYW aJ9KHwA1CIFDShIAT0oAAFFKAABcCIFeSgAAYUoSACkMKgYVaJMrdwAWaJ9KHwA1CIFDShIAT0oA AFFKAABcCIFeSgAAYUoSACMMKgYWaJ9KHwA1CIFDShQAT0oAAFFKAABcCIFeSgAAYUoUACQWaJ9K HwA1CIFAiAwAQ0oUAE9KAABRSgAAXAiBXkoAAGFKFAAAKhVo8SqgABZon0ofADUIgUCIDABDShQA T0oAAFFKAABcCIFeSgAAYUoUAAAmFWjxKqAAFmifSh8ANQiBQ0oUAE9KAABRSgAAXAiBXkoAAGFK FAAADBVo8SqgABZon0ofAAAgFWjxKqAAFmifSh8AQ0oUAE9KAABRSgAAXkoAAGFKFAAAMgNqAAAA ABZokR66AENKFABPSgAAUUoAAFUIAV5KAABhShQAbUgABG5IAAR0SBkEdQgBEQAIAAAECAAABggA AAgIAAAyCAAAfggAALAIAADuCAAALgkAADAJAADlAAAAAAAAAAAAAAAAnQAAAAAAAAAAAAAAAOUA AAAAAAAAAAAAAADlAAAAAAAAAAAAAAAA5QAAAAAAAAAAAAAAAOUAAAAAAAAAAAAAAADlAAAAAAAA AAAAAAAA5QAAAAAAAAAAAAAAAOUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAEcAAGtkgzsAABYkARckAUlmAQAAAAKWbAAHlEoGCNYaAAGU/3gP AAbkDwAAAAAAAAAAAAAAAAAAAAAKdAAA4AENNiAPlAEAEJS0ABT2AQAAF/YDAAAa1gQAAAD/G9YE AAAA/xzWBAAAAP8d1gQAAAD/HpS0ADTWBgABBQMAADTWBgABCgNsAGH2AwAAZTQBABkAAAMkARJk 8AABABSkAAAWJAEZhAEAGyYgIyQCL4S0AElmAQAAAGEkAWIkAWdkmnxUAAAJCAkAAAoJAAAUCQAA MAkAADIJAAA0CQAAZgkAAGgJAAC2CQAAuAkAAAYKAAAYCgAARAoAAEYKAADUCgAA2AoAAPDezca1 oI6gjqCAa1dDMgAAAAAAAAAAAAAAAAAAAAAAAAAAACAWaJ9KHwA1CIFDShwAT0oAAFFKAABcCIFe SgAAYUocAAAmFWhNWx8AFmifSh8ANQiBQ0ocAE9KAABRSgAAXAiBXkoAAGFKHAAAJhVoGB2kABZo n0ofADUIgUNKHABPSgAAUUoAAFwIgV5KAABhShwAACkVaOZHXwAWaJ9KHwA1CIE+KgFDShgAT0oA AFFKAABcCIFeSgAAYUoYABoWaJ9KHwBDShQAT0oAAFFKAABeSgAAYUoUAAAjFmifSh8ANQiBPioB Q0oYAE9KAABRSgAAXAiBXkoAAGFKGAApFWh5CqoAFmifSh8ANQiBPioBQ0oYAE9KAABRSgAAXAiB XkoAAGFKGAAgFWgYHaQAFmifSh8AQ0oUAE9KAABRSgAAXkoAAGFKFAAADBVo8SqgABZon0ofAAAg FWjxKqAAFmifSh8AQ0oUAE9KAABRSgAAXkoAAGFKFAAAIxVo8SqgABZon0ofAD4qAUNKFABPSgAA UUoAAF5KAABhShQAHRZon0ofAD4qAUNKFABPSgAAUUoAAF5KAABhShQAAA8wCQAAMgkAADQJAABo CQAAagkAALgJAAC6CQAABgoAAAgKAAAKCgAADAoAAA4KAAAQCgAAEgoAABQKAAAWCgAAGAoAAEQK AABGCgAAtwAAAAAAAAAAAAAAAK0AAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAA AKAAAAAAAAAAAAAAAACtAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAK0AAAAAAAAAAAAAAACtAAAA AAAAAAAAAAAArQAAAAAAAAAAAAAAAK0AAAAAAAAAAAAAAACtAAAAAAAAAAAAAAAArQAAAAAAAAAA AAAAAK0AAAAAAAAAAAAAAACtAAAAAAAAAAAAAAAArQAAAAAAAAAAAAAAAK0AAAAAAAAAAAAAAACt AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAADJAISZPAAAQAUpAAAYSQCZ2Q8FfQAAAkAABJk8AAB ABSkAABnZDwV9AAARwAAa2TSOwAAFiQBFyQBSWYBAAAAApZsAAeUoQUI1hoAAZT/eA8ABuQPAAAA AAAAAAAAAAAAAAAAAAp0AADgAQ02IA+UAQAQlLQAFPYBAAAX9gMAABrWBAAAAP8b1gQAAAD/HNYE AAAA/x3WBAAAAP8elLQANNYGAAEFAwAANNYGAAEKA2wAYfYDAABlNAEAEkYKAADYCgAAJgwAACgM AAB8DAAAfgwAAKAMAAC2DgAAfBEAALggAABiJAAA3iYAAOAmAAA2JwAAwicAAMQnAADGJwAAyCcA AB4oAAAiKAAAJCgAACgoAAAqKAAALigAADAoAAD1AAAAAAAAAAAAAAAA9QAAAAAAAAAAAAAAAPUA AAAAAAAAAAAAAAD1AAAAAAAAAAAAAAAA9QAAAAAAAAAAAAAAAPUAAAAAAAAAAAAAAADgAAAAAAAA AAAAAAAA4AAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAA APUAAAAAAAAAAAAAAAD1AAAAAAAAAAAAAAAA9QAAAAAAAAAAAAAAAPUAAAAAAAAAAAAAAAD1AAAA AAAAAAAAAAAA9QAAAAAAAAAAAAAAAPUAAAAAAAAAAAAAAADWAAAAAAAAAAAAAAAA1AAAAAAAAAAA AAAAANYAAAAAAAAAAAAAAADUAAAAAAAAAAAAAAAA1gAAAAAAAAAAAAAAANQAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAQAAAAkAABJk8AABABSkAABnZOZHXwAVDwAKJgALRgYAD4QAABGEAAASZPAA AQAUpAAAXoQAAGCEAABnZDwV9AAACQAAEmTwAAEAFKQAAGdkPBX0AAAY2AoAACYMAAAoDAAAOAwA AHoMAAB8DAAAoAwAAAQOAAAGDgAAtA4AALYOAAB8EQAAAB4AAN4mAADgJgAAHCcAAB4nAAAgJwAA 7NzIt8immY+Zj5mNgGxYQVgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ACwMKgYVaDwV9AAWaJ9KHwA1CIE+KgFDSiAAT0oAAFFKAABcCIFeSgAAYUogAAAmDCoGFmifSh8A NQiBPioBQ0ogAE9KAABRSgAAXAiBXkoAAGFKIAAAJgwqBhZon0ofADUIgT4qAUNKHABPSgAAUUoA AFwIgV5KAABhShwAABgVaOZHXwAWaJ9KHwBPSgAAUUoAAF5KAAAAA1UIARIWaJ9KHwBPSgAAUUoA AF5KAAAAGBVoPBX0ABZon0ofAE9KAABRSgAAXkoAAAAgFmifSh8ANQiBQ0oYAE9KAABRSgAAXAiB XkoAAGFKGAAAIBZon0ofADUIgUNKHABPSgAAUUoAAFwIgV5KAABhShwAACYVaHkKqgAWaJ9KHwA1 CIFDShwAT0oAAFFKAABcCIFeSgAAYUocAAAeFWg8FfQAFmifSh8ANQiBT0oAAFFKAABcCIFeSgAA ACYVaDwV9AAWaJ9KHwA1CIFDShgAT0oAAFFKAABcCIFeSgAAYUoYABEeBEEEPgQxBDUEPQQ9BD4E QQRCBDgEIAA/BEAENQQ0BD4EQQRCBDAEMgQ7BDUEPQQ4BE8EIAA3BDUEPAQ1BDsETAQ9BEsERQQg AEMERwQwBEEEQgQ6BD4EMgQgADQEOwRPBCAARgQ1BDsENQQ5BCAAQQRCBEAEPgQ4BEIENQQ7BEwE QQRCBDIEMAQuACAAFwQwBEEEQgRABD4EOQQ6BDAEIAA3BDUEPAQ1BDsETAQgADoEMAQ6BCAAMgQ4 BDQEIAA/BEAEOARABD4ENAQ+BD8EPgQ7BEwENwQ+BDIEMAQ9BDgETwQuACAAEgQ7BDgETwQ9BDgE NQQgAEEERQQ1BDwEIABCBDUEQARABDgEQgQ+BEAEOAQwBDsETAQ9BD4EMwQ+BCAAPwQ7BDAEPQQ4 BEAEPgQyBDAEPQQ4BE8ELAAgADMENQQ9BDUEQAQwBDsETAQ9BEsERQQgAD8EOwQwBD0EPgQyBCwA IAA/BEAEMAQyBDgEOwQgADcENQQ8BDsENQQ/BD4EOwRMBDcEPgQyBDAEPQQ4BE8EIAA4BCAANwQw BEEEQgRABD4EOQQ6BDgEIAA4BCAAOARFBCAAPgRCBEEEQwRCBEEEQgQyBDgETwQgAD0EMAQgAD8E QAQ1BDQEPgRBBEIEMAQyBDsENQQ9BDgENQQgADcENQQ8BDUEOwRMBD0ESwRFBCAAQwRHBDAEQQRC BDoEPgQyBCAAOAQ3BCAAMwQ+BEEEQwQ0BDAEQARBBEIEMgQ1BD0EPQQ+BDkEIAA4BDsEOAQgADwE QwQ9BDgERgQ4BD8EMAQ7BEwEPQQ+BDkEIABBBD4EMQRBBEIEMgQ1BD0EPQQ+BEEEQgQ4BCAAOAQg AD4ERAQ+BEAEPAQ7BDUEPQQ4BDUEIABBBEIEQAQ+BDgEQgQ1BDsETARBBEIEMgQwBC4ADQAhBDsE PgQ2BD0ESwQ1BCAAMgQ+BD8EQAQ+BEEESwQgAEMEQgQ+BEcEPQQ1BD0EOARPBCAAMwRABDAEPQQ4 BEYELAAgAD4EMQRABDAENwQ+BDIEMAQ9BDgETwQgADgEIAA/BD4EQQRCBDAEPQQ+BDIEOgQ4BCAA NwQ1BDwENQQ7BEwEPQRLBEUEIABDBEcEMARBBEIEOgQ+BDIEIAA9BDAEIAA6BDAENAQwBEEEQgRA BD4EMgRLBDkEIABDBEcEUQRCBC4AIAAcBDUENgQ1BDIEPgQ5BCAAPwQ7BDAEPQQuACAAHwQ+BEAE TwQ0BD4EOgQgAEEEPgQzBDsEMARBBD4EMgQwBD0EOARPBCAAPAQ1BEEEQgQ+BD8EPgQ7BD4ENgQ1 BD0EOARPBCAAMwRABDAEPQQ4BEYEIAA3BDUEPAQ1BDsETAQ9BEsERQQgAEMERwQwBEEEQgQ6BD4E MgQuACAAHAQ9BD4EMwQ+BDoEPgQ9BEIEQwRABD0ESwQ1BCAANwQ1BDwENQQ7BEwEPQRLBDUEIABD BEcEMARBBEIEOgQ4BC4AIAAiBDUERQQ9BDgERwQ1BEEEOgQ4BDkEIAA/BDsEMAQ9BCAAQQQ+BD4E QARDBDYENQQ9BDgETwQuACAAEAQ6BEIEIAA+BDEEQQQ7BDUENAQ+BDIEMAQ9BDgETwQuACAAIQQ+ BD4EQgQ9BD4ESAQ1BD0EOAQ1BCAAPwRABD4ENQQ6BEIEPgQyBCAAPwQ7BDAEPQQ4BEAEPgQyBDoE OAQgADgEIAA8BDUENgQ1BDIEMAQ9BDgETwQgAEIENQRABEAEOARCBD4EQAQ4BDgEIABBBCAAMAQ6 BEIEPgQ8BCAAMgRLBDEEPgRABDAEIAA3BDUEPAQ1BDsETAQ9BD4EMwQ+BCAAQwRHBDAEQQRCBDoE MAQgADgEIAA/BEAENQQ0BDIEMARABDgEQgQ1BDsETAQ9BEsEPAQgAEEEPgQzBDsEMARBBD4EMgQw BD0EOAQ1BDwEIAA8BDUEQQRCBDAEIABABDAENwQ8BDUESQQ1BD0EOARPBCAAPgQxBEoENQQ6BEIE MAQsACAAQQQ+BDMEOwQwBEEEPgQyBDAEPQQ4BE8EIAA/BEAENQQ0BD4EQQRCBDAEMgQ7BDUEPQQ4 BE8EIAA3BDUEPAQ1BDsETAQ9BEsERQQgAEMERwQwBEEEQgQ6BD4EMgQgADgEIABBBEIEQAQ+BDgE QgQ1BDsETARBBEIEMgQwBC4AIAANAB8EQAQwBDIEPgQyBD4ENQQgAEAENQQzBEMEOwQ4BEAEPgQy BDAEPQQ4BDUEIAA4BCAAPgRBBD4EMQQ1BD0EPQQ+BEEEQgQ4BCAAMwQ+BEEEQwQ0BDAEQARBBEIE MgQ1BD0EPQQ+BDkEIABABDUEMwQ4BEEEQgRABDAERgQ4BDgEIAA0BD4EMwQ+BDIEPgRABDAEIAA6 BEMEPwQ7BDgELQA/BEAEPgQ0BDAENgQ4BCAAPgQxBEoENQQ6BEIEPgQyBCAAPQQ1BDQEMgQ4BDYE OAQ8BD4EQQRCBDgELgAgAB8EQAQ+BDEEOwQ1BDwESwQsACAAQQQyBE8ENwQwBD0EPQRLBDUEIABB BCAAPwRABDgEPAQ1BD0ENQQ9BDgENQQ8BCAAPwQ+BDsEPgQ2BDUEPQQ4BDkEIABBBEIELgAgADEA MwAwACAAEwQaBCAAIAQkBCAAKAA9BDUENAQyBDgENgQ4BDwESwQ1BCAAOAQgADQEMgQ4BDYEOAQ8 BEsENQQgADIENQRJBDgEKQAgADgEIAAxADIAMgAtACQEFwQgAD8EQAQ4BCAAQAQ1BEgENQQ9BDgE OAQgADcENQQ8BDUEOwRMBD0ESwRFBCAAQQQ/BD4EQAQ+BDIELAAgADIEIABCBD4EPAQgAEcEOARB BDsENQQgADIEIAA+BEIEPQQ+BEgENQQ9BDgEOAQgADsEOAQ9BDUEOQQ9BEsERQQgAD4EMQRKBDUE OgRCBD4EMgQgADgEIAA+BDEESgQ1BDoEQgQ+BDIEIAA4BD0ENgQ1BD0ENQRABD0EPgQ5BCAAOAQ9 BEQEQAQwBEEEQgRABEMEOgRCBEMEQARLBC4AIAANAA0AIgQ1BDsENQREBD4EPQRLBCAANAQ7BE8E IABABDUEMwQ4BEEEQgRABDAERgQ4BDgEOgAgACgAOAAxADIAKQAgADkAOAA3ACAAOAAzACAANAA5 ACAADQAIACMEQQQ7BD4EMgQ4BE8EIABDBEcEMARBBEIEOARPBCwAIAA/BD4EOwQ9BDAETwQgAD8E QAQ+BDMEQAQwBDwEPAQwBCAAPAQ1BEAEPgQ/BEAEOARPBEIEOARPBCAAMgRLBEEESwQ7BDAETgRC BEEETwQgACAAPwQ+BCAANwQwBD8EQAQ+BEEEQwQNAA0ADQANAAgAIARDBDoEPgQyBD4ENAQ4BEIE NQQ7BEwEIAA+BEAEMwQ6BD4EPAQ4BEIENQRCBDAECQAJAAkACQAiBDgEPAQ+BEQENQQ1BDIEMAQg AB4ELgATBA0AAwANAA0ABAANAA0AAwANAA0ABAANAA0ADQANAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgJwAAMicAADQnAAA2JwAAOCcAAFYn AACqJwAAwicAAMQnAADGJwAAyCcAAMonAADiJwAA5CcAAPonAAACKAAAHCgAAOzXxbWklqSJdWe1 U0VTRTQAAAAAAAAAAAAAAAAAAAAAAAAAACAVaHYpPQAWaJ9KHwBDShgAT0oAAFFKAABeSgAAYUoY AAAaFmifSh8AQ0oYAE9KAABRSgAAXkoAAGFKGAAAJhVoZUgFABZon0ofADUIgUNKGABPSgAAUUoA AFwIgV5KAABhShgAABoWaJ9KHwBDShQAT0oAAFFKAABeSgAAYUoUAAAmFmifSh8ANQiBNgiBQ0oU AE9KAABRSgAAXAiBXQiBXkoAAGFKFAAAGBVoPBX0ABZon0ofAE9KAABRSgAAXkoAAAAbFmifSh8A NQiBPioBT0oAAFFKAABcCIFeSgAAIRVoPBX0ABZon0ofADUIgT4qAU9KAABRSgAAXAiBXkoAAB4D agAAAAAWaJEeugBVCAFtSAAEbkgABHRIGQR1CAEAIxZon0ofADUIgT4qAUNKIABPSgAAUUoAAFwI gV5KAABhSiAAKRVoPBX0ABZon0ofADUIgT4qAUNKIABPSgAAUUoAAFwIgV5KAABhSiAAJgwqBhZo n0ofADUIgT4qAUNKKABPSgAAUUoAAFwIgV5KAABhSigAEBwoAAAeKAAAICgAACQoAAAmKAAAKigA ACwoAAAwKAAAMigAADgoAAA6KAAA7+fj5+Pn4+fj7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGFmiRHroAAA8DagAAAAAWaJEeugBVCAEg FWgYHaQAFmifSh8AQ0oUAE9KAABRSgAAXkoAAGFKFAAKMCgAADQoAAA2KAAAOCgAADooAAD1AAAA AAAAAAAAAAAA8wAAAAAAAAAAAAAAAPMAAAAAAAAAAAAAAADpAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJAAASZPAAAQAUpAAA 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 xxzMx7zS4lmlYI2P+Ol+/K32681e4eV5fwXv5VmrhRqpyAuaoaSSvsSgEiADYlpu+dt///2bRJb0 78c//vGGzN978ncbT4xtko9WPn/8wjf8w8dKlQOTcKCC9yRcq/es4wBzAW30TW96U5M8Qotkgy4B 7dJrOPRoqPmfaBAJMEP/3Nf2vFLHYem48QE/8AV/8GnVzUd1e2wMByp4bwyft9xbxCprwMsMIClF gknYf/vizEuBcVGuM5+Ym3mar3mbf2ls95YTkDrhqTlQwXtqFtYHDOWA8q6iL4Qpir5IE3qEwo0r rLQZgG08xpUm3rBzm4O/jW7EMJTf9frV5EAF79Vc16WelZogkl3SPx3PxUPnfyrvTQLo7mt7nvfk 797qNVqWWphWePAVvFd4cevUKgcqB1aXAxW8V3dt68wqByoHVpgDFbxXeHHr1CoHKgdWlwMVvFd3 bevMKgcqB1aYAxW8V3hx69QqByoHVpcDFbxXd23rzCoHKgdWmAMVvFd4cevUKgcqB1aXAxW8V3dt 68wqByoHVpgDFbxXeHHr1CoHKgdWlwP/P0ptqR2V93ilAAAAAElFTkSuQmCCoEYd8NMuAABKAEZq TE9iLMisMfKWM5Oz///Y/+AAEEpGSUYAAQEBANwA3AAA/9sAQwACAQEBAQECAQEBAgICAgIEAwIC AgIFBAQDBAYFBgYGBQYGBgcJCAYHCQcGBggLCAkKCgoKCgYICwwLCgwJCgoK/9sAQwECAgICAgIF AwMFCgcGBwoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoK /8AAEQgBGAHPAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQ AAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYX GBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqS k5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz 9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQE AAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1 Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKj pKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwD AQACEQMRAD8A/fyiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKK KACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoooo AKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigA ooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoopC4HX1xQAt FY3jH4h+BPh7otx4j8d+MNN0ewtYy9xealepDHGo6ksxAFfMvxW/4Lcf8E6Phfqc/hu0+NcvirWY Uyuk+DNCu9SeVt23YJIozFuz2LigD6zor4sk/wCCn/7THxN06zuv2Y/+CX3xW1xb7d5WoeNmtfD9 qn91i07klT6nbT7qy/4LmfF1bWW11r4I/CizuhuuoBDea3qFkufu7jiCR8ddvA9aAPs8nH9awvFP xQ+G/gaAXPjX4gaHo8Zk2B9U1WG3Bb0Bdhk+1fJj/wDBLf8AaG+J+2b9p3/gpl8VfEUchH2vRvC8 0Wh2DgHJULbgPg9OWJ967Lw1/wAEcf8AgnPoE/8AaGo/s0aT4gvTOJWvfFd5c6pIzZzkm5kcEk8n jmgDW+Iv/BWf/gnL8K7l7Pxf+1x4S85GKvb6VcyahKpBwcpapI36Vxsv/Bdv/glhAyrP+086bgSC /gXXVGB3y1iOPevevCX7KH7MfgPRv+Ef8F/s9eCdKsiMG20/wxawp+Sx1tr8HPhYqLGPhzogVQAo GmxjAH/AaAK/wa+PHwg/aG8FQfET4J/EPS/EujXKgxX2l3AkAJGQrLw0bY6qwBHpXXVkeHvAvg7w lc3F14V8J6bpr3eDdvYWSQmYjOC+wDcRk8n1rXoAKKKKAGu2wFjnAGelNt50uYlmj3bWXI3IV/Q8 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 XNf8F2P2gLz4f/Ae7+GXhXVp/wC2/EmiPpGm6dbXKqbu71OeOyhUqDvbEf2phxgFQc+n1t+yr8HL T9n39nPwR8FrOFFHhrwxZ2EpjBw8qQqJX55+aTe340Aeg0UUUAFFFFABRRRQAUUUUAFFFFABRRRQ AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAB RRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUkhwhI7DI4pabMqvCyOcAqcn0oA/Mj9ryLQ/wBp 3/gtH8HPgvo0MGo23hXWF1/WJYpBIkKabEZAjjPDedvj2EcHB6nFfpyORmvyq/4JZ/BqKw/4Ll/t W+NojC9r4daa2tikOWEmoXv2h9xJOGHluPcZ7cV+qtABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAB RRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFF FFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABSMAwKnoetFFAHDfC39mr4J/Bfxt4w+I/w28Dw6dr nj7Vl1LxbqYnkkk1C4UEKzb2IUKCcKoA5Jxk5ruqKKACiiigAooooAKKKKACiiigAooooAKKKKAC iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK KKACiiigAooooA//2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACDOwAARABkAAAAAAAAAAgA AAAAAAAAAAAAAAAACQbrBegD6AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8ABPBo AAAAsgQK8AgAAAABBAAAAAoAAIMAC/BEAAAABEEBAAAABgFAAAAACQFmJgAAPwEEAAQA/wEAAAgA PwMQABAAgMMUAAAAvwMAAAIAIAQ4BEEEQwQ9BD4EOgQgADIAAAAAABDwBAAAAAAAAIBiAAfwxzoA AAYG6umLJzpF3a4PHjstjrxE7f8AozoAAAEAAABEAAAAAADOBwBuHvCbOgAA6umLJzpF3a4PHjst jrxE7f+JUE5HDQoaCgAAAA1JSERSAAAAuAAAALcIAwAAAJa7ZCAAAAMAUExURQAAAP////R+YPF+ X7gfJPIhItIcHd4gIesiJOYiJrobHOIiJtYgIt4iJtoiJtYiJtIhIr8eIOgmJ9IiJs4hIs4iJuIm J84mJ7UiJN0sLc0rLa0mKMUsLegdJMgZINgdJcAaH+4hKuQhKsweJtwkK7oeItQjK7YeIsoiJsUi Jr4iJroiJsQkK7YkKr0xNfQiL9oeK7oaIsMeJuYkML4eJroeJssiKrYeJt0nM70jK7oWIrYWIsAa JtAdKroaJsQeKrYcKr4eKsglNPTr7MAaL8UgNPfx8r+7vMe8weXd4t7V29bM0/z1+/Tp9MzEzP76 /vby9uzl7cTDy+Tk7MvL0vT0+93d4/r6/vLy9tTV3Ovt8+zz9dvj5cLMzM7W1u/39/X8/OXs7NXb 2/r+/rvCwPP79ev07fH28sLMwtXb1fr++tzk2+Ts49DVzLi6tNzd2vb38OTk2+zs5fv79fPz7f7+ +s3Mw9zb1cnDubywpOHTycq5rtrW1MPBwOHHu/F+T8iik8+sneOCYL6ajebb1/N8VvB+Wed7We2C Xt57Wu3k4fZ+WvF6WvZ/XvJ+Xux9XvGCYtWCa9uwo/JzVfZ6Wvp7Xft/YvJ6XvZ+YvJ+YuJ1W+V6 Xut+YtyEb8l7Z8aKe9SYiM/LyuZqUfR1XPZ6Xux1XdZtVe96YveAZvF+ZuF5ZOxgSPFoTvt5YvZ6 YvqAbNeKe91WQfhqVPtzXfN2YuJAL+5XQ85WR9hwZe1+cMRrYO5CMtY9L+1LPbk5L9tIO91bTr1P RtJlWsBcU8giGdUzJ+I0KswzKLUsJMw8NO0iHNgiG+cmIeImIN4mINInH9onIdYnIOwrJLojHeQr JM4mIckmIdwrJcAmIc0rJbkmIuwzLboqJOcdG+YiIeIhIdohIcohIcUhId4mJrAgHtomJtYnJr4i ItImJroiIskmJsAmJrgmJtQsLL0rK7ErKuE7OLs9O89FQs3Dw/z19f76+tbS0uTj49/e3sbFxf7+ /vr6+vb29vLy8u3t7f///zzY9RsAAAEAdFJOU/////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////wBT 9wclAAAAAWJLR0QAiAUdSAAAAAxjbVBQSkNtcDA3MTIAAAADSABzvAAANhRJREFUeF7VnQtcU1e2 8G9BEtI8IUHQNkSeErQdBiyt35Xr7TBDAiIv0YKCAkZBgUQeQkIINwFuRUYJYCsoEEBFrdr7QTuA gzAgKr0SwFpffVySgA98TFs0SIhC+q0TSJAEilDvz37LB+Sck73/e52111p7n3P2+Zdf/j+Vf5mO e+tHH320fv1o6tiEhM1RfHx81o/6PN/6bOvuZylbY3fNt5zUVJ/1IB9Nxzgd+O5dQ0MpqbFr12rm KcnR0dGpu3bt8g98+iwqasuWeRajAYLkZO/UlKFpyI3Ad+/albIlTBOsSoqPH5kQzhzF13edr2rd 2rBtO58/3+ITrFKpxguaYzEchEClStZ4p+5KMWQ3BH+6Kyoqau3aYKgq0y9znjK8Iz0jaUNwUOzu QP8t+flJnHmWNOznx+FsUAVHR4+lGmp9Kviz51FBQWuDk3z91lRzRVVF85QK+F5xom/Sxl3+QwnF tbXzLKaoSsRXB1QPZ27wXesTq5mKPgV8Z9SW5xuDVdHxGaKKuh+ofzCfELs5iplZV3dFtW/8ptT1 KUlHLDHzLceO2tVaJErbHMNRqTSaTbEvmssL4M8Ct/ivXRsRn5F1qu56Z2+XuZ3ZPKUTvlkR4Bux 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 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAGoEFgASAAEACwEPAAcAAwADAAMAAAAEAAkAAAAJAAAADwAAAA8AAAAPAAAADwAA AA8AAAAPAAAADwAAAA8AAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAABAAAA AQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAAP AAAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYG AAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAACQAA ADYGAAA2BgAAAQAAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAACQAAADYGAAA2BgAA NgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAAAkAAAAJAAAANgYAADYGAAA2 BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYG AAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYA ADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAA 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 ZXMiPz4NCjxhOmNsck1hcCB4bWxuczphPSJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5v cmcvZHJhd2luZ21sLzIwMDYvbWFpbiIgYmcxPSJsdDEiIHR4MT0iZGsxIiBiZzI9Imx0MiIgdHgy PSJkazIiIGFjY2VudDE9ImFjY2VudDEiIGFjY2VudDI9ImFjY2VudDIiIGFjY2VudDM9ImFjY2Vu dDMiIGFjY2VudDQ9ImFjY2VudDQiIGFjY2VudDU9ImFjY2VudDUiIGFjY2VudDY9ImFjY2VudDYi IGhsaW5rPSJobGluayIgZm9sSGxpbms9ImZvbEhsaW5rIi8+AAAAANsJAAAMAAAwAAAIAP////8A AAAAAwAAAAYAAAAGAAAACQAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADwAAAAAI AAAICQAA2AoAACAnAAAcKAAAOigAAAkAAAALAAAADgAAABUAAAAWAAAAAAgAADAJAABGCgAAMCgA ADooAAAKAAAADAAAAA0AAAAXAAAADwAA8KwAAAAAAAbwGAAAAAQEAAACAAAAAwAAAAEAAAABAAAA BAAAAC8AAfBYAAAAYgAH8CQAAAAGBir8YloWxXFO76IN5ungzkD/ALihAAABAAAANDAAAAAAAABS AAfwJAAAAAUFSgBGakxPYizIrDHyljOTs/8A2y4AAAEAAADs0QAAAAAAACMAC/AMAAAAhsEAAAAA xcEAAAAAQAAe8RAAAAD//wAAAAD/AICAgAD3AAAQAA8AAvCGAQAAEAAI8AgAAAADAAAAAwQAAA8A A/AkAQAADwAE8CgAAAABAAnwEAAAAAAAAAAAAAAAAAAAAAAAAAACAArwCAAAAAAEAAAFAAAADwAE 8GIAAACyBArwCAAAAAIEAAAACgAAUwAL8DIAAAAEQQEAAAAGAUAAAAA/AxAAEACAwxQAAAC/AyAA IgAgBDgEQQRDBD0EPgQ6BCAAMwAAAAAAEPAEAAAAAAAAAAAAEfAEAAAAAQAAAA8ABPCCAAAAsgQK 8AgAAAADBAAAAAoAAGMAC/BSAAAABEECAAAABgFAAAAAPwMQABAAgMMUAAAAgcMaAAAAvwMgACIA IAQ4BEEEQwQ9BD4EOgQgADcAAAA/BD4ENAQ/BDgEQQRMBDIALgBqAHAAZwAAAAAAEPAEAAAAAQAA AAAAEfAEAAAAAQAAAA8ABPBCAAAAEgAK8AgAAAABBAAAAA4AAFMAC/AeAAAAvwEAABAAywEAAAAA /wEAAAgABAMJAAAAPwMBAAEAAAAR8AQAAAABAAAAWQkAAKIJAADbCQAAAgQAAGwbAAAXAAAAzCQA AEoJAAB0QAAAAAADBAAAhQsAABn8//9bFwAAPwMAAHRAAAAAAAAAAADMCQAA3AkAAAMABwAAAAAA zAkAANwJAAADAAcABgASCq0Evrf8D/8P/w//D/8P/w//D/8P/w//DxAATXWgLviaNrv/D/8P/w// D/8P/w//D/8P/w8QAEw85kmiSvri/w//D/8P/w//D/8P/w//D/8PEACcP/5RJp6+Wv8P/w//D/8P /w//D/8P/w//DxAAL3IsZkBZqJz/D/8P/w//D/8P/w//D/8P/w8QAAUsdH0Yb2IM/w//D/8P/w// D/8P/w//D/8PEAABAAAAFwAAAAAAAAAAAAAAAAAAAAAAAAAPEAAAD4TQAhGEmP5ehNACYISY/k9K AQBRSgEAXkoBAG8oAAEAt/ABAAAABAABAAAAAAAAAAAAAAAAAAAAAAAAEAAAD4SgBRGEmP5ehKAF YISY/gIAAQAuAAEAAAACAgEAAAAAAAAAAAAAAAAAAAAAAAAQAAAPhHAIEYRM/16EcAhghEz/AgAC AC4AAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAABAAAA+EQAsRhJj+XoRAC2CEmP4CAAMALgABAAAA BAABAAAAAAAAAAAAAAAAAAAAAAAAEAAAD4QQDhGEmP5ehBAOYISY/gIABAAuAAEAAAACAgEAAAAA AAAAAAAAAAAAAAAAAAAQAAAPhOAQEYRM/16E4BBghEz/AgAFAC4AAQAAAAAAAQAAAAAAAAAAAAAA AAAAAAAAABAAAA+EsBMRhJj+XoSwE2CEmP4CAAYALgABAAAABAABAAAAAAAAAAAAAAAAAAAAAAAA EAAAD4SAFhGEmP5ehIAWYISY/gIABwAuAAEAAAACAgEAAAAAAAAAAAAAAAAAAAAAAAAQAAAPhFAZ EYRM/16EUBlghEz/AgAIAC4AAQAAABcAAAAAAAAAAAAAAAAAAAAAAAAADxAAAA+E0AIRhJj+XoTQ AmCEmP5PSgEAUUoBAF5KAQBvKAABALfwAQAAABcAAAAAAAAAAAAAAAAAAAAAAAAADxAAAA+EoAUR hJj+XoSgBWCEmP5PSgUAUUoFAF5KBQBvKAABAG8AAQAAABcAAAAAAAAAAAAAAAAAAAAAAAAADxAA AA+EcAgRhJj+XoRwCGCEmP5PSgYAUUoGAF5KBgBvKAABAKfwAQAAABcAAAAAAAAAAAAAAAAAAAAA AAAADxAAAA+EQAsRhJj+XoRAC2CEmP5PSgEAUUoBAF5KAQBvKAABALfwAQAAABcAAAAAAAAAAAAA AAAAAAAAAAAADxAAAA+EEA4RhJj+XoQQDmCEmP5PSgUAUUoFAF5KBQBvKAABAG8AAQAAABcAAAAA AAAAAAAAAAAAAAAAAAAADxAAAA+E4BARhJj+XoTgEGCEmP5PSgYAUUoGAF5KBgBvKAABAKfwAQAA ABcAAAAAAAAAAAAAAAAAAAAAAAAADxAAAA+EsBMRhJj+XoSwE2CEmP5PSgEAUUoBAF5KAQBvKAAB ALfwAQAAABcAAAAAAAAAAAAAAAAAAAAAAAAADxAAAA+EgBYRhJj+XoSAFmCEmP5PSgUAUUoFAF5K BQBvKAABAG8AAQAAABcAAAAAAAAAAAAAAAAAAAAAAAAADxAAAA+EUBkRhJj+XoRQGWCEmP5PSgYA UUoGAF5KBgBvKAABAKfwAQAAABcAAAAAAAAAAAAAAAAAAAAAAAAADxAAAA+E0AIRhJj+XoTQAmCE mP5PSgEAUUoBAF5KAQBvKAABALfwAQAAABcAAAAAAAAAAAAAAAAAAAAAAAAADxAAAA+EoAURhJj+ XoSgBWCEmP5PSgUAUUoFAF5KBQBvKAABAG8AAQAAABcAAAAAAAAAAAAAAAAAAAAAAAAADxAAAA+E cAgRhJj+XoRwCGCEmP5PSgYAUUoGAF5KBgBvKAABAKfwAQAAABcAAAAAAAAAAAAAAAAAAAAAAAAA DxAAAA+EQAsRhJj+XoRAC2CEmP5PSgEAUUoBAF5KAQBvKAABALfwAQAAABcAAAAAAAAAAAAAAAAA AAAAAAAADxAAAA+EEA4RhJj+XoQQDmCEmP5PSgUAUUoFAF5KBQBvKAABAG8AAQAAABcAAAAAAAAA AAAAAAAAAAAAAAAADxAAAA+E4BARhJj+XoTgEGCEmP5PSgYAUUoGAF5KBgBvKAABAKfwAQAAABcA AAAAAAAAAAAAAAAAAAAAAAAADxAAAA+EsBMRhJj+XoSwE2CEmP5PSgEAUUoBAF5KAQBvKAABALfw AQAAABcAAAAAAAAAAAAAAAAAAAAAAAAADxAAAA+EgBYRhJj+XoSAFmCEmP5PSgUAUUoFAF5KBQBv KAABAG8AAQAAABcAAAAAAAAAAAAAAAAAAAAAAAAADxAAAA+EUBkRhJj+XoRQGWCEmP5PSgYAUUoG AF5KBgBvKAABAKfwAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAxAAAA+E0AIRhJj+XoTQAmCEmP5v KAACAAAALgABAAAABAABAAAAAAAAAAAAAAAAAAAAAAAAEAAAD4SgBRGEmP5ehKAFYISY/gIAAQAu AAEAAAACAgEAAAAAAAAAAAAAAAAAAAAAAAAQAAAPhHAIEYRM/16EcAhghEz/AgACAC4AAQAAAAAA AQAAAAAAAAAAAAAAAAAAAAAAABAAAA+EQAsRhJj+XoRAC2CEmP4CAAMALgABAAAABAABAAAAAAAA AAAAAAAAAAAAAAAAEAAAD4QQDhGEmP5ehBAOYISY/gIABAAuAAEAAAACAgEAAAAAAAAAAAAAAAAA AAAAAAAQAAAPhOAQEYRM/16E4BBghEz/AgAFAC4AAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAABAA AA+EsBMRhJj+XoSwE2CEmP4CAAYALgABAAAABAABAAAAAAAAAAAAAAAAAAAAAAAAEAAAD4SAFhGE mP5ehIAWYISY/gIABwAuAAEAAAACAgEAAAAAAAAAAAAAAAAAAAAAAAAQAAAPhFAZEYRM/16EUBlg hEz/AgAIAC4AAQAAABcAAAAAAAAAAAAAAAAAAAAAAAAADxAAAA+E0AIRhJj+XoTQAmCEmP5PSgYA UUoGAF5KBgBvKAABAPzwAQAAAAQAAQAAAAAAAAAAAAAAAAAAAAAAABAAAA+EoAURhJj+XoSgBWCE mP4CAAEALgABAAAAAgIBAAAAAAAAAAAAAAAAAAAAAAAAEAAAD4RwCBGETP9ehHAIYIRM/wIAAgAu AAEAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAQAAAPhEALEYSY/l6EQAtghJj+AgADAC4AAQAAAAQA AQAAAAAAAAAAAAAAAAAAAAAAABAAAA+EEA4RhJj+XoQQDmCEmP4CAAQALgABAAAAAgIBAAAAAAAA AAAAAAAAAAAAAAAAEAAAD4TgEBGETP9ehOAQYIRM/wIABQAuAAEAAAAAAAEAAAAAAAAAAAAAAAAA AAAAAAAQAAAPhLATEYSY/l6EsBNghJj+AgAGAC4AAQAAAAQAAQAAAAAAAAAAAAAAAAAAAAAAABAA AA+EgBYRhJj+XoSAFmCEmP4CAAcALgABAAAAAgIBAAAAAAAAAAAAAAAAAAAAAAAAEAAAD4RQGRGE TP9ehFAZYIRM/wIACAAuAAEAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAMQAAAPhNACEYSY/l6E0AJg hJj+bygAAgAAAC4AAQAAAAQAAQAAAAAAAAAAAAAAAAAAAAAAABAAAA+EoAURhJj+XoSgBWCEmP4C AAEALgABAAAAAgIBAAAAAAAAAAAAAAAAAAAAAAAAEAAAD4RwCBGETP9ehHAIYIRM/wIAAgAuAAEA AAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAQAAAPhEALEYSY/l6EQAtghJj+AgADAC4AAQAAAAQAAQAA AAAAAAAAAAAAAAAAAAAAABAAAA+EEA4RhJj+XoQQDmCEmP4CAAQALgABAAAAAgIBAAAAAAAAAAAA AAAAAAAAAAAAEAAAD4TgEBGETP9ehOAQYIRM/wIABQAuAAEAAAAAAAEAAAAAAAAAAAAAAAAAAAAA AAAQAAAPhLATEYSY/l6EsBNghJj+AgAGAC4AAQAAAAQAAQAAAAAAAAAAAAAAAAAAAAAAABAAAA+E gBYRhJj+XoSAFmCEmP4CAAcALgABAAAAAgIBAAAAAAAAAAAAAAAAAAAAAAAAEAAAD4RQGRGETP9e hFAZYIRM/wIACAAuAAYAAABNdaAuAAAAAAAAAAAAAAAATDzmSQAAAAAAAAAAAAAAAJw//lEAAAAA AAAAAAAAAAAFLHR9AAAAAAAAAAAAAAAAEgqtBAAAAAAAAAAAAAAAAC9yLGYAAAAAAAAAAAAAAAD/ /////////////////////////////////wYAAAAAAAAAAAAAAAAAAAD//wYAAAASAAEAGQQZABkE GwAZBA8AGQQZABkEGwAZBA8AGQQZABkEGwAZBBIAAQAZBAMAGQQFABkEAQAZBAMAGQQFABkEAQAZ BAMAGQQFABkEEgABABkEAwAZBAUAGQQBABkEAwAZBAUAGQQBABkEAwAZBAUAGQQSAA8AGQQZABkE GwAZBA8AGQQZABkEGwAZBA8AGQQZABkEGwAZBBIADQAZBBkAGQQbABkEDwAZBBkAGQQbABkEDwAZ BBkAGQQbABkEEgCu+wzpGQAZBBsAGQQPABkEGQAZBBsAGQQPABkEGQAZBBsAGQQCACp9N1EAAAAA AAAAAAAAK303UQAAAAAAAAAAAAA1AAAABAAAAAgAAADlAAAAAAAAAAIAAAAsdAQAZUgFAGcTCQCV FgkAFxUNALd0EADHNBEAEzAaAJ9KHwBNWx8ABmshAJB9JwD/NDAAzEQzAGgUOAB2KT0AQwg+AP9C PwBuUz8A8GFCANAXQwBNc0gAPk5RAJp8VADJDVYADUNfAOZHXwAIX2UAJhBmANdqaQDfGWsA4llv AIVgcwCTK3cAsBx8ANsijACsGJ8A8SqgABgdpACgAagAeQqqANgLsABVM7MAkR66AIVzvwCTcsIA L2/EAI56zAA2EOEA4EvqADwV9AD4LP0Ahmj9AAAAAADNCQAAzwkAAAAAAAABAAAA/0AMgAEAAAAA AAAAAAAAAAAAAQABAAAAAAAAAAAAAAAAAAAAAAACHAAAAAAAAAC+BAAA2wkAAGAAAAgAAAAAYAAA HgAAAAD//wEAAAAHAFUAbgBrAG4AbwB3AG4A//8BAAgAAAAAAAAAAAAAAP//AQAAAAAA//8AAAIA //8AAAAA//8AAAIA//8AAAAACAAAAEcekAHMAAICBgMFBAUCAwT/KgDgQXgAwAkAAAAAAAAA/wEA AAAAAABUAGkAbQBlAHMAIABOAGUAdwAgAFIAbwBtAGEAbgAAADUekAECAAUFAQIBBwYCBQcAAAAA AAAAEAAAAAAAAAAAAAAAgAAAAABTAHkAbQBiAG8AbAAAADMukAHMAAILBgQCAgICAgT/KgDgQ3gA wAkAAAAAAAAA/wEAAAAAAABBAHIAaQBhAGwAAAA3LpABzAACDwUCAgIEAwIE/wIA4f+sAEAJAAAA AAAAAJ8BAAAAAAAAQwBhAGwAaQBiAHIAaQAAADUikAEAAAILBgQDBQQEAgQDAAAAAAAAAAAAAAAA AAAAAQAAAAAAAABUAGEAaABvAG0AYQAAAD89kAHMAAIHAwkCAgUCBAT/KgDgQ3gAwAkAAAAAAAAA /wEAAAAAAABDAG8AdQByAGkAZQByACAATgBlAHcAAAA7DpABAgAFAAAAAAAAAAAAAAAAAAAAABAA AAAAAAAAAAAAAIAAAAAAVwBpAG4AZwBkAGkAbgBnAHMAAABBEpABAQACBAUDBQQGAwIEAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAQwBhAG0AYgByAGkAYQAgAE0AYQB0AGgAAAAiAAQAMQCIGADwxAIA AGgBAAAAANPtKSfT7SknpFMkhwIAAAAAAHYBAABXCAAAAQAFAAAABAADEBEAAAB2AQAAVwgAAAEA BQAAABEAAAAAAAAAIQMA8BAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApQYcArQAtACBgRIw AAAAAAAAAAAAAAAAAADICQAAyAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAQoMRAPAQAAgA/P8BAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAACEgAAAAAAAjw/w8ACSRQAADjBAAA////f////3////9/////f////3// //9/////f/BhQgAABAAAMgAAAAAAAAAAAAAAAAAAAAAAAAAAACEAAAAAAAAAAAAAAAAAAAAAAAAA EBwAAAcAAAAAAAAAAAB4AAAAeAAAAAAAAAAAAAAAoAUAAAAAAAALAAAAAAAAANwAAAD//xIAAAAA AAAAAAAAAAAAAAANAEEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIABgB2AGkAYwB0AG8AcgAAAAAA AAAAAAAAAAAAAAAAAAAAACQAAAAGAAAABgAAAAAADAABAAwAAgAMAAMADAAEAAwABQAMAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+/wAABgECAAAAAAAA AAAAAAAAAAAAAAABAAAA4IWf8vlPaBCrkQgAKyez2TAAAAA4AQAADgAAAAEAAAB4AAAABAAAAIAA AAAHAAAAmAAAAAgAAACsAAAACQAAALwAAAASAAAAyAAAAAoAAADoAAAACwAAAPQAAAAMAAAAAAEA AA0AAAAMAQAADgAAABgBAAAPAAAAIAEAABAAAAAoAQAAEwAAADABAAACAAAA4wQAAB4AAAAQAAAA QWRtaW5pc3RyYXRvcgAAAB4AAAAMAAAATm9ybWFsLmRvdG0AHgAAAAgAAAB2aWN0b3IAAB4AAAAE AAAAMgAAAB4AAAAYAAAATWljcm9zb2Z0IE9mZmljZSBXb3JkAAAAQAAAAAAAAAAAAAAAQAAAAABQ vguxVM8BQAAAAABSu5oi3M8BQAAAAABSu5oi3M8BAwAAAAEAAAADAAAAdgEAAAMAAABXCAAAAwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v8AAAYBAgAAAAAAAAAAAAAAAAAA AAAAAQAAAALVzdWcLhsQk5cIACss+a4wAAAA7AAAAAwAAAABAAAAaAAAAA8AAABwAAAABQAAAHwA AAAGAAAAhAAAABEAAACMAAAAFwAAAJQAAAALAAAAnAAAABAAAACkAAAAEwAAAKwAAAAWAAAAtAAA AA0AAAC8AAAADAAAAMkAAAACAAAA4wQAAB4AAAAEAAAAKgAAAAMAAAARAAAAAwAAAAUAAAADAAAA yAkAAAMAAAAAAA4ACwAAAAAAAAALAAAAAAAAAAsAAAAAAAAACwAAAAAAAAAeEAAAAQAAAAEAAAAA DBAAAAIAAAAeAAAACQAAAM3g5+Lg7ejlAAMAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAI AAAACQAAAAoAAAALAAAADAAAAA0AAAAOAAAADwAAABAAAAARAAAAEgAAABMAAAAUAAAAFQAAABYA AAAXAAAAGAAAABkAAAAaAAAAGwAAABwAAAAdAAAAHgAAAB8AAAAgAAAAIQAAACIAAAAjAAAAJAAA ACUAAAAmAAAAJwAAACgAAAApAAAAKgAAACsAAAAsAAAALQAAAC4AAAAvAAAAMAAAADEAAAAyAAAA MwAAADQAAAA1AAAANgAAADcAAAA4AAAAOQAAADoAAAA7AAAAPAAAAD0AAAA+AAAAPwAAAEAAAABB AAAAQgAAAEMAAABEAAAARQAAAEYAAABHAAAASAAAAEkAAABKAAAASwAAAEwAAABNAAAATgAAAE8A AABQAAAAUQAAAFIAAABTAAAAVAAAAFUAAABWAAAAVwAAAFgAAABZAAAAWgAAAFsAAABcAAAAXQAA AF4AAABfAAAAYAAAAGEAAABiAAAAYwAAAGQAAABlAAAAZgAAAGcAAABoAAAAaQAAAGoAAABrAAAA bAAAAG0AAABuAAAAbwAAAHAAAABxAAAAcgAAAHMAAAB0AAAAdQAAAHYAAAB3AAAAeAAAAHkAAAB6 AAAAewAAAHwAAAB9AAAAfgAAAH8AAACAAAAA/v///4IAAACDAAAAhAAAAIUAAACGAAAAhwAAAIgA AACJAAAAigAAAIsAAACMAAAAjQAAAI4AAACPAAAAkAAAAJEAAACSAAAAkwAAAJQAAACVAAAAlgAA AJcAAACYAAAAmQAAAJoAAACbAAAAnAAAAJ0AAACeAAAAnwAAAP7///+hAAAAogAAAKMAAACkAAAA pQAAAKYAAACnAAAAqAAAAKkAAACqAAAAqwAAAKwAAACtAAAArgAAAK8AAACwAAAAsQAAALIAAACz AAAAtAAAALUAAAC2AAAA/v///7gAAAC5AAAAugAAALsAAAC8AAAAvQAAAL4AAAD+////wAAAAMEA AADCAAAAwwAAAMQAAADFAAAAxgAAAP7////9/////f///8oAAAD+/////v////7///////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////9SAG8AbwB0ACAARQBuAHQAcgB5AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFgAFAf//////////AwAAAAYJAgAAAAAA wAAAAAAAAEYAAAAAAAAAAAAAAAAg6RyvItzPAcwAAACAAAAAAAAAAEQAYQB0AGEAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAIB//////// ////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgQAAACE8AAAAAAAAMQBU AGEAYgBsAGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAA4AAgEBAAAABgAAAP////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACg AAAAsiwAAAAAAABXAG8AcgBkAEQAbwBjAHUAbQBlAG4AdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAGgACAQIAAAAFAAAA/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAADHAAEAAAAAAAUAUwB1AG0AbQBhAHIAeQBJAG4AZgBvAHIAbQBhAHQA aQBvAG4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAIB////////////////AAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtwAAAAAQAAAAAAAABQBEAG8AYwB1AG0AZQBuAHQA UwB1AG0AbQBhAHIAeQBJAG4AZgBvAHIAbQBhAHQAaQBvAG4AAAAAAAAAAAAAADgAAgEEAAAA//// //////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/AAAAABAAAAAAAAABAEMA bwBtAHAATwBiAGoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAEgACAP///////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAByAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAP7///////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////8BAP7/AwoAAP////8GCQIAAAAAAMAAAAAAAABGIAAAAMTu 6vPs5e3yIE1pY3Jvc29mdCBXb3JkIDk3LTIwMDMACgAAAE1TV29yZERvYwAQAAAAV29yZC5Eb2N1 bWVudC44APQ5snEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== ------=_NextPart_000_05E1_01CFDC77.C7E84260-- From david@fromorbit.com Mon Sep 29 23:39:21 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6DA3C7FC6 for ; Mon, 29 Sep 2014 23:39:21 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4D0B1304059 for ; Mon, 29 Sep 2014 21:39:21 -0700 (PDT) X-ASG-Debug-ID: 1412051956-04bdf003a0669220001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id YTXzNC5svUZUnE1D for ; Mon, 29 Sep 2014 21:39:17 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AusjAP0yKlR5LDjwPGdsb2JhbABggw6BKoIyhQeuZQEBAQaVWIVrBAICgQ0XAQYBAQEBODmEBAEBBDocIxAIAxgJJQ8FJQMHGhOIPb84GIV6igwHhEsBBJ0nmVMrL4JKAQEB Received: from ppp121-44-56-240.lns20.syd6.internode.on.net (HELO dastard) ([121.44.56.240]) by ipmail06.adl2.internode.on.net with ESMTP; 30 Sep 2014 14:09:15 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XYpDV-0004oP-CM; Tue, 30 Sep 2014 14:39:13 +1000 Date: Tue, 30 Sep 2014 14:39:13 +1000 From: Dave Chinner To: "Ma, Jianpeng" Cc: "xfs@oss.sgi.com" Subject: Re: Question: How to use systemtap count the total inode read from disk Message-ID: <20140930043913.GP4758@dastard> X-ASG-Orig-Subj: Re: Question: How to use systemtap count the total inode read from disk References: <6AA21C22F0A5DA478922644AD2EC308C8C986B@SHSMSX101.ccr.corp.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <6AA21C22F0A5DA478922644AD2EC308C8C986B@SHSMSX101.ccr.corp.intel.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1412051956 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10052 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header On Tue, Sep 30, 2014 at 02:39:28AM +0000, Ma, Jianpeng wrote: > Hi all, > I want to count the total read inode from disk. XFS already does that for you: $ pminfo -tf xfs.inode_ops.ig_missed xfs.inode_ops.ig_missed [number of failed in memory inode lookup operations] value 1835354 $ And that's the number read from disk as reported by PCP. If you don't have PCP: $ awk '/ig/ {print $5}' /proc/fs/xfs/stat 1835354 $ Cheers, Dave. -- Dave Chinner david@fromorbit.com From iusty@k1024.org Tue Sep 30 00:55:35 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 78AA27F7C for ; Tue, 30 Sep 2014 00:55:35 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 16A6EAC004 for ; Mon, 29 Sep 2014 22:55:31 -0700 (PDT) X-ASG-Debug-ID: 1412056529-04bdf003a166b340001-NocioJ Received: from mail-wg0-f41.google.com (mail-wg0-f41.google.com [74.125.82.41]) by cuda.sgi.com with ESMTP id d5vH8bisgAvG6EQE (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Mon, 29 Sep 2014 22:55:30 -0700 (PDT) X-Barracuda-Envelope-From: iusty@k1024.org X-Barracuda-Apparent-Source-IP: 74.125.82.41 Received: by mail-wg0-f41.google.com with SMTP id k14so14766836wgh.24 for ; Mon, 29 Sep 2014 22:55:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id :mail-followup-to:references:mime-version:content-type :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=Bm3KftC+XZnDxjhDAh+Ul0RX+5Yni3veBHH/Au2Qa7s=; b=TFZuDaTt8Nl72utRVgN2HZ/AYVsSxjBm9Lpdv81u62b1na6qAhauxp4CqP+q3/LmB8 f2cEb87NOagnTK6jk2WCIifP1AyQq+QRjI5105pT0lhkA2RKBURMQpx0876qMlP9WkaL EEj/huf2bsoIe2guehr1YyKQzc4oeOQ6IJpLSgSc4KH5ut2MCG1XERZYM/yI+/p9PR5O nUHC1/dHVvV6LLpSvbdW+ww4n4M8XSoN5mEyToHa7myJQlf/juEH2sBJhEjd46xsvGCM XprxGbUKXokGWaKmoKTTcwb30KmzA12se99sZqYY72Uf7tXBh0hj8c/H4T1KF0H9Owim JJ1A== X-Gm-Message-State: ALoCoQnfE9DwwPqWk5m1SrlSVijgq26qr9Q+7jnuluaHFbP/ZKVneXxBqinAgeeyqFbICqdpqSVf X-Received: by 10.181.27.132 with SMTP id jg4mr3152201wid.28.1412056529291; Mon, 29 Sep 2014 22:55:29 -0700 (PDT) Received: from teal.hq.k1024.org (178-83-234-80.dynamic.hispeed.ch. [178.83.234.80]) by mx.google.com with ESMTPSA id k10sm17970153wjb.28.2014.09.29.22.55.28 for (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 29 Sep 2014 22:55:28 -0700 (PDT) Received: by teal.hq.k1024.org (Postfix, from userid 4004) id AC0802057D7; Tue, 30 Sep 2014 07:55:27 +0200 (CEST) Date: Tue, 30 Sep 2014 07:55:27 +0200 From: Iustin Pop To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 0/2] xfs: cleanup XFS_IOC_SETXATTR behaviour Message-ID: <20140930055527.GA15186@teal.hq.k1024.org> X-ASG-Orig-Subj: Re: [PATCH 0/2] xfs: cleanup XFS_IOC_SETXATTR behaviour Mail-Followup-To: Dave Chinner , xfs@oss.sgi.com References: <1412041565-18873-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <1412041565-18873-1-git-send-email-david@fromorbit.com> X-Linux: This message was written on Linux X-Header: /usr/include gives great headers User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: mail-wg0-f41.google.com[74.125.82.41] X-Barracuda-Start-Time: 1412056530 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10054 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 30, 2014 at 11:46:03AM +1000, Dave Chinner wrote: > Hi folks, > > A while back Iustin Pop sent a patch to fix a problem with being > unable to set extent size hint values on directories. That patch - > along with new xfstests functionality to always check the scratch > device after a test - has pointed out that we allow certain > directory only inode flags to be set on other types of inodes (e.g. > regular files). It also pointed out that we could set extent size > hints on inodes that don't have extent size hint flags set. […] > Thoughts, comments, flames? Thanks for sending these - I didn't forget about my patches, just was busy with other stuff. I was planning to update those patches based on your comments and resend them in the next week or so. iustin From iusty@k1024.org Tue Sep 30 00:58:36 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C7F1A7F55 for ; Tue, 30 Sep 2014 00:58:36 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8C7B38F8033 for ; Mon, 29 Sep 2014 22:58:33 -0700 (PDT) X-ASG-Debug-ID: 1412056710-04bdf003a166b4a0001-NocioJ Received: from mail-wi0-f170.google.com (mail-wi0-f170.google.com [209.85.212.170]) by cuda.sgi.com with ESMTP id kAdFs7OzIQ5o9T2O (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Mon, 29 Sep 2014 22:58:32 -0700 (PDT) X-Barracuda-Envelope-From: iusty@k1024.org X-Barracuda-Apparent-Source-IP: 209.85.212.170 Received: by mail-wi0-f170.google.com with SMTP id n3so784680wiv.3 for ; Mon, 29 Sep 2014 22:58:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id :mail-followup-to:references:mime-version:content-type :content-disposition:in-reply-to:user-agent; bh=wQKJjepHkRjfyg4EC1w0ACplEYHlFzMgYhL4AJoInGI=; b=SEQX5qHM/ORQgf0GWmxjxEe1i0gV475vgB6r/dn97ckszmAHeskaUA/JRRb+/SVo3w 8NSsK9/XEkkNVbmxPKvGWh4m3pUEKjlvKkpEtIJ4vj94h1lze4nQSMYbGZdA7llfKoV8 E91G3fLcMasmsJQyWILu9vjVSsHXei2QOtdnIpuRPui0ufwVEcVivbfDuejZn9CibCx3 LKNQX68A9PIPhF8j8Oa9tfZnvmAsnyvotrHR1Us/7DWNn9OBRZISn14IRFKgW+In9fzP Y9t1DPryt4rB8NPvxu0fMH05LRL54QAOWSrBLLFQxX3/12tGDLf1l7IAyTe24r6rNmKO 8VoA== X-Gm-Message-State: ALoCoQkprJTb3TRSEo9HMVd7Av8EIlw498b+ghJaM9lv7cZJVjuHFOyK+yET61W3sr6mkycc6QXX X-Received: by 10.194.120.200 with SMTP id le8mr51184535wjb.43.1412056710289; Mon, 29 Sep 2014 22:58:30 -0700 (PDT) Received: from teal.hq.k1024.org (178-83-234-80.dynamic.hispeed.ch. [178.83.234.80]) by mx.google.com with ESMTPSA id x6sm14579271wif.0.2014.09.29.22.58.29 for (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 29 Sep 2014 22:58:29 -0700 (PDT) Received: by teal.hq.k1024.org (Postfix, from userid 4004) id 13DC82057D7; Tue, 30 Sep 2014 07:58:29 +0200 (CEST) Date: Tue, 30 Sep 2014 07:58:29 +0200 From: Iustin Pop To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/2] xfs: only set extent size hint when asked Message-ID: <20140930055829.GB15186@teal.hq.k1024.org> X-ASG-Orig-Subj: Re: [PATCH 2/2] xfs: only set extent size hint when asked Mail-Followup-To: Dave Chinner , xfs@oss.sgi.com References: <1412041565-18873-1-git-send-email-david@fromorbit.com> <1412041565-18873-3-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1412041565-18873-3-git-send-email-david@fromorbit.com> X-Linux: This message was written on Linux X-Header: /usr/include gives great headers User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: mail-wi0-f170.google.com[209.85.212.170] X-Barracuda-Start-Time: 1412056711 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10054 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 30, 2014 at 11:46:05AM +1000, Dave Chinner wrote: > From: Dave Chinner > > Currently the extent size hint is set unconditionally in > xfs_ioctl_setattr(), even when the FSX_EXTSIZE flag is not set. This > means we can set values from uninitialised stack variables. Hence > only set the extent size hint from userspace when both the mask > falg is set and the inode has the XFS_DIFLAG_EXTSIZE flag set to > indicate that we should have an extent size hint set on the inode. > > Signed-off-by: Dave Chinner > --- > fs/xfs/xfs_ioctl.c | 16 ++++++++++++++-- > 1 file changed, 14 insertions(+), 2 deletions(-) > > diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c > index 87c3bd1..24c926b 100644 > --- a/fs/xfs/xfs_ioctl.c > +++ b/fs/xfs/xfs_ioctl.c > @@ -1231,13 +1231,25 @@ xfs_ioctl_setattr( > > } > > - if (mask & FSX_EXTSIZE) > - ip->i_d.di_extsize = fa->fsx_extsize >> mp->m_sb.sb_blocklog; > if (mask & FSX_XFLAGS) { > xfs_set_diflags(ip, fa->fsx_xflags); > xfs_diflags_to_linux(ip); > } > > + /* > + * Only set the extent size hint if we've already determined that the > + * extent size hint should be set on the inode. If no extent size flags > + * are set on the inode then unconditionally clear the extent size hint. > + */ > + if (mask & FSX_EXTSIZE) { > + int extsize = 0; > + > + if (ip->i_d.di_flags & > + (XFS_DIFLAG_EXTSIZE | XFS_DIFLAG_EXTSZINHERIT)) > + extsize = fa->fsx_extsize >> mp->m_sb.sb_blocklog; > + ip->i_d.di_extsize = extsize; Quick question: this sounds sane, but it will have the following effect (if I understand things correctly): updating other flags on the inode (e.g. XFS_XFLAG_NOATIME) might change the recorded extent size. True, it will correct the size if not appropriate and it will have a noop impact, but still it will be an unrelated inode change. Would it make sense to document this in the xfsctl man page then? thanks, iustin From serg.gorel@ubtanet.com Tue Sep 30 03:14:30 2014 Return-Path: X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 9DE967F72 for ; Tue, 30 Sep 2014 03:14:29 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7850FAC004 for ; Tue, 30 Sep 2014 01:14:25 -0700 (PDT) X-ASG-Debug-ID: 1412064860-04cb6c50e65ec700001-NocioJ Received: from mail.proxen.kiev.ua (mail.proxen.kiev.ua [87.76.66.186]) by cuda.sgi.com with ESMTP id Nj2AMurKewO0SXRv (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 30 Sep 2014 01:14:21 -0700 (PDT) X-Barracuda-Envelope-From: serg.gorel@ubtanet.com X-Barracuda-Apparent-Source-IP: 87.76.66.186 Received: from Unknown ([193.238.111.14]) (authenticated bits=0) by mail.proxen.kiev.ua (8.14.9/8.14.9) with ESMTP id s8U8ECmF072818; Tue, 30 Sep 2014 11:14:13 +0300 (EEST) (envelope-from serg.gorel@ubtanet.com) Message-ID: <3A3F89DAD1052122FEFBB238BCF716BE@thxwct> From: =?windows-1251?Q?=C2=E5=E4=F3=F9=E8=E9_=F1=EF=E5=F6=E8=E0?= =?windows-1251?Q?=EB=E8=F1=F2_=EF=EE_=F0=E0=E7=E2=E8=F2?= =?windows-1251?Q?=E8=FE_=EF=E5=F0=F1=EE=ED=E0=EB=E0?= To: , , , Subject: =?windows-1251?Q?=CD=EE=E2=E0=FF_=F1=E8=F1=F2=E5=EC=E0_?= =?windows-1251?Q?=D1=ED=E8=EF_?= Date: Tue, 30 Sep 2014 10:14:12 +0200 X-ASG-Orig-Subj: =?windows-1251?Q?=CD=EE=E2=E0=FF_=F1=E8=F1=F2=E5=EC=E0_?= =?windows-1251?Q?=D1=ED=E8=EF_?= MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0AE8_01CFDC97.48577FA0" X-Priority: 3 X-Barracuda-Connect: mail.proxen.kiev.ua[87.76.66.186] X-Barracuda-Start-Time: 1412064860 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: -1001.00 X-Barracuda-Spam-Status: No, SCORE=-1001.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 This is a multi-part message in MIME format. ------=_NextPart_000_0AE8_01CFDC97.48577FA0 Content-Type: text/html; charset="windows-1251" Content-Transfer-Encoding: quoted-printable
=CC=E5=F2=EE=E4=E8=F7=E5=F1=EA=E8=E5 =F0=E5=EA=EE=EC=E5=ED=E4=E0=F6=E8= =E8 =E4=EB=FF =F1=EF=E5=F6=E8=E0=EB=E8=F1=F2=EE=E2, =EE=F1=F3=F9=E5=F1=F2= =E2=EB=FF=FE=F9=E8=F5 =F1=F2=F0=EE=E8=F2=E5=EB=FC=ED=FB=E9=20 =EA=EE=ED=F2=F0=EE=EB=FC!
 
l=E7-l=D7=20 =EE=EA=F2=FF=E1=F0=FF, =CF=C5=D2=C5=D0=C1=D3=D0=C3: =C1=E5=E7=EE=EF=E0=F1= =ED=EE=F1=F2=FC =F1=F2=F0=EE=E8=F2=E5=EB=FC=F1=F2=E2=E0. =D1=F2=F0=EE=E8=F2= =E5=EB=FC=ED=FB=E9 =EA=EE=ED=F2=F0=EE=EB=FC
 
=CD=E0 =EF=EE=E2=E5=F1=F2=EA=E5:
 
- =E2=F5=EE=E4=ED=EE=E9 =EA=EE=ED=F2=F0=EE=EB=FC =EF=F0=EE=E5=EA=F2=ED= =EE=E9 =E8 =E8=F1=EF=EE=EB=ED=E8=F2=E5=EB=FC=ED=EE=E9 =E4=EE=EA=F3=EC=E5=ED= =F2=E0=F6=E8=E8
- =EF=F0=E8=ED=F6=E8=EF=FB=20 =EE=F0=E3=E0=ED=E8=E7=E0=F6=E8=E8 =F1=F2=F0=EE=E8=F2=E5=EB=FC=ED=EE=E3=EE= =EA=EE=ED=F2=F0=EE=EB=FF
- =EF=EE=E4=E3=EE=F2=EE=E2=EA=E0 =EE=E1=FA=E5= =EA=F2=E0 =EA =F1=F2=F0=EE=E8=F2=E5=EB=FC=F1=F2=E2=F3
-=20 =F2=F0=E5=E1=EE=E2=E0=ED=E8=FF =EA =EB=E8=F6=E0=EC, =EE=F1=F3=F9=E5=F1=F2= =E2=EB=FF=FE=F9=E8=EC =EA=EE=ED=F2=F0=EE=EB=FC
- =EF=EE=F1=EB=E5=E4=ED= =E8=E5 =E8=E7=EC=E5=ED=E5=ED=E8=FF=20 =E7=E0=EA=EE=ED=EE=E4=E0=F2=E5=EB=FC=F1=F2=E2=E0, =EA=EE=F2=EE=F0=FB=E5 =ED= =E5=EE=E1=F5=EE=E4=E8=EC=EE =F3=F7=E8=F2=FB=E2=E0=F2=FC =EF=F0=E8 =EE=F1=F3= =F9=E5=F1=F2=E2=EB=E5=ED=E8=E8=20
=EA=E0=EF=E8=F2=E0=EB=FC=ED=EE=E3=EE =F1=F2=F0=EE=E8=F2=E5=EB=FC=F1=F2= =E2=E0 =E8 =F0=E5=EA=EE=ED=F1=F2=F0=F3=EA=F6=E8=E9, =EE=E1=E7=EE=F0 =ED=EE= =F0=EC=E0=F2=E8=E2=ED=FB=F5 =E0=EA=F2=EE=E2 =E4=EB=FF=20 =F6=E5=EB=E5=E9 =EA=EE=ED=F2=F0=EE=EB=FF
- =E0=EB=E3=EE=F0=E8=F2=EC =E4= =EE=EA=F3=EC=E5=ED=F2=EE=EE=E1=EE=F0=EE=F2=E0 =EC=E5=E6=E4=F3 =F3=F7=E0=F1= =F2=ED=E8=EA=E0=EC=E8 =F0=E5=E0=EB=E8=E7=E0=F6=E8=E8=20 =F1=F2=F0=EE=E8=F2=E5=EB=FC=ED=EE=E3=EE =EF=F0=EE=E5=EA=F2=E0 =E8 =EF=EE=E4= =E3=EE=F2=EE=E2=EA=E8 =EE=E1=FA=E5=EA=F2=E0 =EA =F1=E4=E0=F7=E5
- =E3=EE= =F1=F3=E4=E0=F0=F1=F2=E2=E5=ED=ED=FB=E5=20 =ED=E0=E4=E7=EE=F0=ED=FB=E5 =EE=F0=E3=E0=ED=FB: =F2=EE=F7=EA=E8 =F1=EE=EF= =F0=E8=EA=EE=F1=ED=EE=E2=E5=ED=E8=FF =E8 =E7=EE=ED=FB =EE=F2=E2=E5=F2=F1=F2= =E2=E5=ED=ED=EE=F1=F2=E8
- =EA=E0=F7=E5=F1=F2=E2=EE=20 =F1=F2=F0=EE=E8=F2=E5=EB=FC=F1=F2=E2=E0: =EC=E5=F2=EE=E4=E8=F7=E5=F1=EA=E8= =E5 =F0=E5=EA=EE=EC=E5=ED=E4=E0=F6=E8=E8 =EF=EE =E2=E8=E4=E0=EC =F0=E0=E1= =EE=F2; =E2=EE=E4=EE=F1=ED=E0=E1=E6=E5=ED=E8=E5 =E8=20 =EA=E0=ED=E0=EB=E8=E7=E0=F6=E8=FF, =FD=EB=E5=EA=F2=F0=EE=F1=ED=E0=E1=E6=E5= =ED=E8=E5, =E2=E5=ED=F2=E8=EB=FF=F6=E8=FF, =E3=E0=E7=EE=F1=ED=E0=E1=E6=E5= =ED=E8=E5, =F2=E5=EF=EB=EE=F1=ED=E0=E1=E6=E5=ED=E8=E5
 
=DD=EA=F1=EA=EB=FE=E7=E8=E2=ED=EE =E4=EB=FF =F3=F7=E0=F1=F2=ED=E8=EA= =EE=E2 =EA=EE=ED=F1=F3=EB=FC=F2=E0=F6=E8=E8 =E2=FB=E4=E0=E5=F2=F1=FF =EC=E5= =F2=EE=E4=E8=F7=E5=F1=EA=E8=E9 =EC=E0=F2=E5=F0=E8=E0=EB.=20
 
=D3=F1=EB=EE=E2=E8=FF =F3=F7=E0=F1=F2=E8=FF =F3=F2=EE=F7=ED=FF=E9=F2= =E5 =EF=EE =F2=E5=EB=E5=F4=EE=ED=E0=EC:=20 8 ( =CF=E5=F2=E5=F0=E1=F3=F0=E3 ) 98--=F7 * 5=C7 .. 6=C7=
 
=C1=CE=CB=C5=C5 =CF=CE=C4=D0=CE=C1=CD=D3=DE =C8=CD=D4=CE=D0=CC=C0=D6= =C8=DE =CE =CC=C5=D0=CE=CF=D0=C8=DF=D2=C8=C8 =C2=DB =CD=C0=C9=C4=A8=D2=C5= =C2=CE=20 =C2=CB=CE=C6=C5=CD=C8=C8.
------=_NextPart_000_0AE8_01CFDC97.48577FA0 Content-Type: application/msword; name="=?windows-1251?Q?=EF=EE=E4=F0=EE=E1=ED=E0=FF_=E8=ED=F4=EE?= =?windows-1251?Q?=F0=EC=E0=F6=E8=FF=2Edoc?=" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="=?windows-1251?Q?=EF=EE=E4=F0=EE=E1=ED=E0=FF_=E8=ED=F4=EE?= =?windows-1251?Q?=F0=EC=E0=F6=E8=FF=2Edoc?=" e1xydGYxXGFuc2lcYW5zaWNwZzEyNTFcdWMxXGRlZmYwXHN0c2hmZGJjaDM3XHN0c2hmbG9jaDBc c3RzaGZoaWNoMFxzdHNoZmJpMFxkZWZsYW5nMTA0OVxkZWZsYW5nZmUxMDQ5e1xmb250dGJse1xm MFxmcm9tYW5cZmNoYXJzZXQyMDRcZnBycTJ7XCpccGFub3NlIDAyMDIwNjAzMDUwNDA1MDIwMzA0 fVRpbWVzIE5ldyBSb21hbjt9DQp7XGYyXGZtb2Rlcm5cZmNoYXJzZXQyMDRcZnBycTF7XCpccGFu b3NlIDAyMDcwMzA5MDIwMjA1MDIwNDA0fUNvdXJpZXIgTmV3O317XGYzXGZyb21hblxmY2hhcnNl dDJcZnBycTJ7XCpccGFub3NlIDA1MDUwMTAyMDEwNzA2MDIwNTA3fVN5bWJvbDt9e1xmMTBcZm5p bFxmY2hhcnNldDJcZnBycTJ7XCpccGFub3NlIDA1MDAwMDAwMDAwMDAwMDAwMDAwfVdpbmdkaW5n czt9DQp7XGYzN1xmc3dpc3NcZmNoYXJzZXQyMDRcZnBycTJ7XCpccGFub3NlIDAwMDAwMDAwMDAw MDAwMDAwMDAwfUNhbGlicmk7fXtcZjM4XGZzd2lzc1xmY2hhcnNldDIwNFxmcHJxMntcKlxwYW5v c2UgMDAwMDAwMDAwMDAwMDAwMDAwMDB9VmVyZGFuYTt9e1xmMzlcZnJvbWFuXGZjaGFyc2V0MjA0 XGZwcnEye1wqXHBhbm9zZSAwMDAwMDAwMDAwMDAwMDAwMDAwMH1UaW1lczt9DQp7XGY0M1xmcm9t YW5cZmNoYXJzZXQwXGZwcnEyIFRpbWVzIE5ldyBSb21hbjt9e1xmNDFcZnJvbWFuXGZjaGFyc2V0 MjM4XGZwcnEyIFRpbWVzIE5ldyBSb21hbiBDRTt9e1xmNDRcZnJvbWFuXGZjaGFyc2V0MTYxXGZw cnEyIFRpbWVzIE5ldyBSb21hbiBHcmVlazt9e1xmNDVcZnJvbWFuXGZjaGFyc2V0MTYyXGZwcnEy IFRpbWVzIE5ldyBSb21hbiBUdXI7fQ0Ke1xmNDZcZnJvbWFuXGZjaGFyc2V0MTc3XGZwcnEyIFRp bWVzIE5ldyBSb21hbiAoSGVicmV3KTt9e1xmNDdcZnJvbWFuXGZjaGFyc2V0MTc4XGZwcnEyIFRp bWVzIE5ldyBSb21hbiAoQXJhYmljKTt9e1xmNDhcZnJvbWFuXGZjaGFyc2V0MTg2XGZwcnEyIFRp bWVzIE5ldyBSb21hbiBCYWx0aWM7fXtcZjQ5XGZyb21hblxmY2hhcnNldDE2M1xmcHJxMiBUaW1l cyBOZXcgUm9tYW4gKFZpZXRuYW1lc2UpO30NCntcZjYzXGZtb2Rlcm5cZmNoYXJzZXQwXGZwcnEx IENvdXJpZXIgTmV3O317XGY2MVxmbW9kZXJuXGZjaGFyc2V0MjM4XGZwcnExIENvdXJpZXIgTmV3 IENFO317XGY2NFxmbW9kZXJuXGZjaGFyc2V0MTYxXGZwcnExIENvdXJpZXIgTmV3IEdyZWVrO317 XGY2NVxmbW9kZXJuXGZjaGFyc2V0MTYyXGZwcnExIENvdXJpZXIgTmV3IFR1cjt9e1xmNjZcZm1v ZGVyblxmY2hhcnNldDE3N1xmcHJxMSBDb3VyaWVyIE5ldyAoSGVicmV3KTt9DQp7XGY2N1xmbW9k ZXJuXGZjaGFyc2V0MTc4XGZwcnExIENvdXJpZXIgTmV3IChBcmFiaWMpO317XGY2OFxmbW9kZXJu XGZjaGFyc2V0MTg2XGZwcnExIENvdXJpZXIgTmV3IEJhbHRpYzt9e1xmNjlcZm1vZGVyblxmY2hh cnNldDE2M1xmcHJxMSBDb3VyaWVyIE5ldyAoVmlldG5hbWVzZSk7fXtcZjQxM1xmc3dpc3NcZmNo YXJzZXQwXGZwcnEyIENhbGlicmk7fXtcZjQxMVxmc3dpc3NcZmNoYXJzZXQyMzhcZnBycTIgQ2Fs aWJyaSBDRTt9DQp7XGY0MTRcZnN3aXNzXGZjaGFyc2V0MTYxXGZwcnEyIENhbGlicmkgR3JlZWs7 fXtcZjQxNVxmc3dpc3NcZmNoYXJzZXQxNjJcZnBycTIgQ2FsaWJyaSBUdXI7fXtcZjQxOFxmc3dp c3NcZmNoYXJzZXQxODZcZnBycTIgQ2FsaWJyaSBCYWx0aWM7fXtcZjQxOVxmc3dpc3NcZmNoYXJz ZXQxNjNcZnBycTIgQ2FsaWJyaSAoVmlldG5hbWVzZSk7fXtcZjQyM1xmc3dpc3NcZmNoYXJzZXQw XGZwcnEyIFZlcmRhbmE7fQ0Ke1xmNDIxXGZzd2lzc1xmY2hhcnNldDIzOFxmcHJxMiBWZXJkYW5h IENFO317XGY0MjRcZnN3aXNzXGZjaGFyc2V0MTYxXGZwcnEyIFZlcmRhbmEgR3JlZWs7fXtcZjQy NVxmc3dpc3NcZmNoYXJzZXQxNjJcZnBycTIgVmVyZGFuYSBUdXI7fXtcZjQyOFxmc3dpc3NcZmNo YXJzZXQxODZcZnBycTIgVmVyZGFuYSBCYWx0aWM7fXtcZjQyOVxmc3dpc3NcZmNoYXJzZXQxNjNc ZnBycTIgVmVyZGFuYSAoVmlldG5hbWVzZSk7fQ0Ke1xmNDMzXGZyb21hblxmY2hhcnNldDBcZnBy cTIgVGltZXM7fXtcZjQzMVxmcm9tYW5cZmNoYXJzZXQyMzhcZnBycTIgVGltZXMgQ0U7fXtcZjQz NFxmcm9tYW5cZmNoYXJzZXQxNjFcZnBycTIgVGltZXMgR3JlZWs7fXtcZjQzNVxmcm9tYW5cZmNo YXJzZXQxNjJcZnBycTIgVGltZXMgVHVyO317XGY0MzZcZnJvbWFuXGZjaGFyc2V0MTc3XGZwcnEy IFRpbWVzIChIZWJyZXcpO30NCntcZjQzN1xmcm9tYW5cZmNoYXJzZXQxNzhcZnBycTIgVGltZXMg KEFyYWJpYyk7fXtcZjQzOFxmcm9tYW5cZmNoYXJzZXQxODZcZnBycTIgVGltZXMgQmFsdGljO317 XGY0MzlcZnJvbWFuXGZjaGFyc2V0MTYzXGZwcnEyIFRpbWVzIChWaWV0bmFtZXNlKTt9fXtcY29s b3J0Ymw7XHJlZDBcZ3JlZW4wXGJsdWUwO1xyZWQwXGdyZWVuMFxibHVlMjU1O1xyZWQwXGdyZWVu MjU1XGJsdWUyNTU7XHJlZDBcZ3JlZW4yNTVcYmx1ZTA7DQpccmVkMjU1XGdyZWVuMFxibHVlMjU1 O1xyZWQyNTVcZ3JlZW4wXGJsdWUwO1xyZWQyNTVcZ3JlZW4yNTVcYmx1ZTA7XHJlZDI1NVxncmVl bjI1NVxibHVlMjU1O1xyZWQwXGdyZWVuMFxibHVlMTI4O1xyZWQwXGdyZWVuMTI4XGJsdWUxMjg7 XHJlZDBcZ3JlZW4xMjhcYmx1ZTA7XHJlZDEyOFxncmVlbjBcYmx1ZTEyODtccmVkMTI4XGdyZWVu MFxibHVlMDtccmVkMTI4XGdyZWVuMTI4XGJsdWUwO1xyZWQxMjhcZ3JlZW4xMjhcYmx1ZTEyODsN ClxyZWQxOTJcZ3JlZW4xOTJcYmx1ZTE5Mjt9e1xzdHlsZXNoZWV0e1xxbCBcbGkwXHJpMFx3aWRj dGxwYXJcYXNwYWxwaGFcYXNwbnVtXGZhYXV0b1xhZGp1c3RyaWdodFxyaW4wXGxpbjBcaXRhcDAg XGZzMjRcbGFuZzEwNDlcbGFuZ2ZlMTA0OVxjZ3JpZFxsYW5nbnAxMDQ5XGxhbmdmZW5wMTA0OSBc c25leHQwIE5vcm1hbDt9e1wqXGNzMTAgXGFkZGl0aXZlIFxzc2VtaWhpZGRlbiBEZWZhdWx0IFBh cmFncmFwaCBGb250O317XCoNClx0czExXHRzcm93ZFx0cmZ0c1dpZHRoQjNcdHJwYWRkbDEwOFx0 cnBhZGRyMTA4XHRycGFkZGZsM1x0cnBhZGRmdDNcdHJwYWRkZmIzXHRycGFkZGZyM1x0cmNicGF0 MVx0cmNmcGF0MVx0c2NlbGx3aWR0aGZ0czBcdHN2ZXJ0YWx0XHRzYnJkcnRcdHNicmRybFx0c2Jy ZHJiXHRzYnJkcnJcdHNicmRyZGdsXHRzYnJkcmRnclx0c2JyZHJoXHRzYnJkcnYgDQpccWwgXGxp MFxyaTBcd2lkY3RscGFyXGFzcGFscGhhXGFzcG51bVxmYWF1dG9cYWRqdXN0cmlnaHRccmluMFxs aW4wXGl0YXAwIFxmczIwXGxhbmcxMDI0XGxhbmdmZTEwMjRcbG9jaFxmMFxoaWNoXGFmMFxkYmNo XGFmMzdcY2dyaWRcbGFuZ25wMTAyNFxsYW5nZmVucDEwMjQgXHNuZXh0MTEgXHNzZW1paGlkZGVu IE5vcm1hbCBUYWJsZTt9fQ0Ke1wqXGxhdGVudHN0eWxlc1xsc2RzdGltYXgxNTZcbHNkbG9ja2Vk ZGVmMHtcbHNkbG9ja2VkZXhjZXB0IE5vcm1hbDtoZWFkaW5nIDE7aGVhZGluZyAyO2hlYWRpbmcg MztoZWFkaW5nIDQ7aGVhZGluZyA1O2hlYWRpbmcgNjtoZWFkaW5nIDc7aGVhZGluZyA4O2hlYWRp bmcgOTt0b2MgMTt0b2MgMjt0b2MgMzt0b2MgNDt0b2MgNTt0b2MgNjt0b2MgNzt0b2MgODt0b2Mg OTtjYXB0aW9uO1RpdGxlO0RlZmF1bHQgUGFyYWdyYXBoIEZvbnQ7U3VidGl0bGU7U3Ryb25nO0Vt cGhhc2lzO1RhYmxlIEdyaWQ7fX0NCntcKlxsaXN0dGFibGV7XGxpc3RcbGlzdHRlbXBsYXRlaWQt MTAxMzUxOTA2NFxsaXN0aHlicmlke1xsaXN0bGV2ZWxcbGV2ZWxuZmMyM1xsZXZlbG5mY24yM1xs ZXZlbGpjMFxsZXZlbGpjbjBcbGV2ZWxmb2xsb3cwXGxldmVsc3RhcnRhdDFcbGV2ZWxzcGFjZTM2 MFxsZXZlbGluZGVudDB7XGxldmVsdGV4dFxsZXZlbHRlbXBsYXRlaWQxMDM2MTc0Nzc0XCcwMVx1 LTM5MTMgPzt9e1xsZXZlbG51bWJlcnM7fVxmM1xmczIyXGZiaWFzMCANClxmaS0zNjBcbGk3MjBc amNsaXN0dGFiXHR4NzIwXGxpbjcyMCB9e1xsaXN0bGV2ZWxcbGV2ZWxuZmMyM1xsZXZlbG5mY24y M1xsZXZlbGpjMFxsZXZlbGpjbjBcbGV2ZWxmb2xsb3cwXGxldmVsc3RhcnRhdDFcbGV2ZWxzcGFj ZTM2MFxsZXZlbGluZGVudDB7XGxldmVsdGV4dFxsZXZlbHRlbXBsYXRlaWQ2ODc0NzI2N1wnMDFv O317XGxldmVsbnVtYmVyczt9XGYyXGZiaWFzMCBcZmktMzYwXGxpMTQ0MFxqY2xpc3R0YWJcdHgx NDQwXGxpbjE0NDAgfQ0Ke1xsaXN0bGV2ZWxcbGV2ZWxuZmMyM1xsZXZlbG5mY24yM1xsZXZlbGpj MFxsZXZlbGpjbjBcbGV2ZWxmb2xsb3cwXGxldmVsc3RhcnRhdDFcbGV2ZWxzcGFjZTM2MFxsZXZl bGluZGVudDB7XGxldmVsdGV4dFxsZXZlbHRlbXBsYXRlaWQ2ODc0NzI2OVwnMDFcdS0zOTI5ID87 fXtcbGV2ZWxudW1iZXJzO31cZjEwXGZiaWFzMCBcZmktMzYwXGxpMjE2MFxqY2xpc3R0YWJcdHgy MTYwXGxpbjIxNjAgfXtcbGlzdGxldmVsXGxldmVsbmZjMjMNClxsZXZlbG5mY24yM1xsZXZlbGpj MFxsZXZlbGpjbjBcbGV2ZWxmb2xsb3cwXGxldmVsc3RhcnRhdDFcbGV2ZWxzcGFjZTM2MFxsZXZl bGluZGVudDB7XGxldmVsdGV4dFxsZXZlbHRlbXBsYXRlaWQ2ODc0NzI2NVwnMDFcdS0zOTEzID87 fXtcbGV2ZWxudW1iZXJzO31cZjNcZmJpYXMwIFxmaS0zNjBcbGkyODgwXGpjbGlzdHRhYlx0eDI4 ODBcbGluMjg4MCB9e1xsaXN0bGV2ZWxcbGV2ZWxuZmMyM1xsZXZlbG5mY24yM1xsZXZlbGpjMA0K XGxldmVsamNuMFxsZXZlbGZvbGxvdzBcbGV2ZWxzdGFydGF0MVxsZXZlbHNwYWNlMzYwXGxldmVs aW5kZW50MHtcbGV2ZWx0ZXh0XGxldmVsdGVtcGxhdGVpZDY4NzQ3MjY3XCcwMW87fXtcbGV2ZWxu dW1iZXJzO31cZjJcZmJpYXMwIFxmaS0zNjBcbGkzNjAwXGpjbGlzdHRhYlx0eDM2MDBcbGluMzYw MCB9e1xsaXN0bGV2ZWxcbGV2ZWxuZmMyM1xsZXZlbG5mY24yM1xsZXZlbGpjMFxsZXZlbGpjbjBc bGV2ZWxmb2xsb3cwXGxldmVsc3RhcnRhdDENClxsZXZlbHNwYWNlMzYwXGxldmVsaW5kZW50MHtc bGV2ZWx0ZXh0XGxldmVsdGVtcGxhdGVpZDY4NzQ3MjY5XCcwMVx1LTM5MjkgPzt9e1xsZXZlbG51 bWJlcnM7fVxmMTBcZmJpYXMwIFxmaS0zNjBcbGk0MzIwXGpjbGlzdHRhYlx0eDQzMjBcbGluNDMy MCB9e1xsaXN0bGV2ZWxcbGV2ZWxuZmMyM1xsZXZlbG5mY24yM1xsZXZlbGpjMFxsZXZlbGpjbjBc bGV2ZWxmb2xsb3cwXGxldmVsc3RhcnRhdDFcbGV2ZWxzcGFjZTM2MFxsZXZlbGluZGVudDANCntc bGV2ZWx0ZXh0XGxldmVsdGVtcGxhdGVpZDY4NzQ3MjY1XCcwMVx1LTM5MTMgPzt9e1xsZXZlbG51 bWJlcnM7fVxmM1xmYmlhczAgXGZpLTM2MFxsaTUwNDBcamNsaXN0dGFiXHR4NTA0MFxsaW41MDQw IH17XGxpc3RsZXZlbFxsZXZlbG5mYzIzXGxldmVsbmZjbjIzXGxldmVsamMwXGxldmVsamNuMFxs ZXZlbGZvbGxvdzBcbGV2ZWxzdGFydGF0MVxsZXZlbHNwYWNlMzYwXGxldmVsaW5kZW50MHtcbGV2 ZWx0ZXh0DQpcbGV2ZWx0ZW1wbGF0ZWlkNjg3NDcyNjdcJzAxbzt9e1xsZXZlbG51bWJlcnM7fVxm MlxmYmlhczAgXGZpLTM2MFxsaTU3NjBcamNsaXN0dGFiXHR4NTc2MFxsaW41NzYwIH17XGxpc3Rs ZXZlbFxsZXZlbG5mYzIzXGxldmVsbmZjbjIzXGxldmVsamMwXGxldmVsamNuMFxsZXZlbGZvbGxv dzBcbGV2ZWxzdGFydGF0MVxsZXZlbHNwYWNlMzYwXGxldmVsaW5kZW50MHtcbGV2ZWx0ZXh0XGxl dmVsdGVtcGxhdGVpZDY4NzQ3MjY5DQpcJzAxXHUtMzkyOSA/O317XGxldmVsbnVtYmVyczt9XGYx MFxmYmlhczAgXGZpLTM2MFxsaTY0ODBcamNsaXN0dGFiXHR4NjQ4MFxsaW42NDgwIH17XGxpc3Ru YW1lIDt9XGxpc3RpZDUxMjQ5NDQ0N319e1wqXGxpc3RvdmVycmlkZXRhYmxle1xsaXN0b3ZlcnJp ZGVcbGlzdGlkNTEyNDk0NDQ3XGxpc3RvdmVycmlkZWNvdW50MFxsczF9fXtcKlxwZ3B0Ymwge1xw Z3BcaXBncDBcaXRhcDBcbGkwXHJpMFxzYjBcc2EwfXtccGdwXGlwZ3AwXGl0YXAwDQpcbGkwXHJp MFxzYjBcc2EwfX17XCpccnNpZHRibCBccnNpZDQyNTkyOVxyc2lkNjg1MDA5XHJzaWQ5OTUyNTlc cnNpZDE1MzQ1OTNccnNpZDE1NzYzMTBccnNpZDE2NDU0NjZccnNpZDE4NTY3NDFccnNpZDIwNDcy NzdccnNpZDIxMDA3MDFccnNpZDIyMzAyNDVccnNpZDIzMjA1NjBccnNpZDI2OTc5MjdccnNpZDI4 OTYzOTFccnNpZDI5Njk5NDFccnNpZDMwMTUyNzhccnNpZDMxNzExNDZccnNpZDM2MDcyMDlccnNp ZDM3NjEwMzhccnNpZDQwMjY1OTgNClxyc2lkNDI4OTMwMVxyc2lkNDU0MTEwN1xyc2lkNDYxODA1 OFxyc2lkNDgwNzY3MVxyc2lkNTA3MDU4NVxyc2lkNTI3MTUwMFxyc2lkNTg2MjAxN1xyc2lkNTk5 NDMwN1xyc2lkNjU3NzI3NVxyc2lkNjc3NjA2MFxyc2lkNzQzNzcwMlxyc2lkNzQ5Nzk0NFxyc2lk Nzc1NzU0MFxyc2lkODEzNDQ0OFxyc2lkODIyMTQyN1xyc2lkODI4MzA4OVxyc2lkODMyNDcyMlxy c2lkODkyNTMxN1xyc2lkOTE5MDYwNlxyc2lkOTMxMTA5N1xyc2lkOTQ2MjEzNQ0KXHJzaWQ5ODU0 OTczXHJzaWQxMDExMDIwOFxyc2lkMTA0OTY3NTNccnNpZDEwNTA2MDYwXHJzaWQxMDYzNTg5NFxy c2lkMTEzNTQzMzNccnNpZDExODkxMTAyXHJzaWQxMTkyODc1Nlxyc2lkMTMxODQ4ODZccnNpZDEz Mzk3ODIzXHJzaWQxMzU3NDU0M1xyc2lkMTQwNDg2NzlccnNpZDE0MDkwMzY5XHJzaWQxNDYzODI1 NFxyc2lkMTUwNzU4NThccnNpZDE1NjY4NTgxXHJzaWQxNjEyNjQzNlxyc2lkMTYyNzczMTJccnNp ZDE2MzI1MDYzDQpccnNpZDE2NTQ1MDQ1fXtcKlxnZW5lcmF0b3IgTWljcm9zb2Z0IFdvcmQgMTEu MC41NjA0O317XGluZm97XGF1dGhvciBVc2VyfXtcb3BlcmF0b3IgVXNlcn17XGNyZWF0aW1ceXIy MDEzXG1vMVxkeTIyXGhyMTFcbWluNDl9e1xyZXZ0aW1ceXIyMDE0XG1vOVxkeTI5XGhyMTVcbWlu Mzh9e1xwcmludGltXHlyMjAxNFxtbzVcZHkxOFxocjIzXG1pbjJ9e1x2ZXJzaW9uNDh9e1xlZG1p bnMxMDJ9e1xub2ZwYWdlczF9e1xub2Z3b3JkczMxNn0NCntcbm9mY2hhcnMxODA3fXtcbm9mY2hh cnN3czIxMTl9e1x2ZXJuMjQ2ODl9fVxwYXBlcncxMTkwMFxwYXBlcmgxNjg0MFxtYXJnbDEyNzZc bWFyZ3I4MzlcbWFyZ3QxNDJcbWFyZ2IxMTM0IFx3aWRvd2N0cmxcZnRuYmpcYWVuZGRvY1xub3hs YXR0b3llblxleHBzaHJ0blxub3VsdHJsc3BjXGRudGJsbnNiZGJcbm9zcGFjZWZvcnVsXGh5cGhj YXBzMFxob3J6ZG9jXGRnaHNwYWNlMTIwXGRndnNwYWNlMTIwXGRnaG9yaWdpbjE3MDENClxkZ3Zv cmlnaW4xOTg0XGRnaHNob3cwXGRndnNob3czXGpleHBhbmRcdmlld2tpbmQxXHZpZXdzY2FsZTEw MFxub2xuaHRhZGp0YmxccnNpZHJvb3Q2Nzc2MDYwIFxmZXQwXHNlY3RkIFxzYmtub25lXGxpbmV4 MFxzZWN0ZGVmYXVsdGNsXHNlY3Ryc2lkMzAxNTI3OFxzZnRuYmoge1wqXHBuc2VjbHZsMVxwbnVj cm1ccG5zdGFydDFccG5pbmRlbnQ3MjBccG5oYW5nIHtccG50eHRhIC59fXtcKlxwbnNlY2x2bDIN ClxwbnVjbHRyXHBuc3RhcnQxXHBuaW5kZW50NzIwXHBuaGFuZyB7XHBudHh0YSAufX17XCpccG5z ZWNsdmwzXHBuZGVjXHBuc3RhcnQxXHBuaW5kZW50NzIwXHBuaGFuZyB7XHBudHh0YSAufX17XCpc cG5zZWNsdmw0XHBubGNsdHJccG5zdGFydDFccG5pbmRlbnQ3MjBccG5oYW5nIHtccG50eHRhICl9 fXtcKlxwbnNlY2x2bDVccG5kZWNccG5zdGFydDFccG5pbmRlbnQ3MjBccG5oYW5nIHtccG50eHRi ICh9e1xwbnR4dGEgKX19e1wqXHBuc2VjbHZsNg0KXHBubGNsdHJccG5zdGFydDFccG5pbmRlbnQ3 MjBccG5oYW5nIHtccG50eHRiICh9e1xwbnR4dGEgKX19e1wqXHBuc2VjbHZsN1xwbmxjcm1ccG5z dGFydDFccG5pbmRlbnQ3MjBccG5oYW5nIHtccG50eHRiICh9e1xwbnR4dGEgKX19e1wqXHBuc2Vj bHZsOFxwbmxjbHRyXHBuc3RhcnQxXHBuaW5kZW50NzIwXHBuaGFuZyB7XHBudHh0YiAofXtccG50 eHRhICl9fXtcKlxwbnNlY2x2bDlccG5sY3JtXHBuc3RhcnQxXHBuaW5kZW50NzIwXHBuaGFuZyAN CntccG50eHRiICh9e1xwbnR4dGEgKX19XHBhcmRccGxhaW4gXHFyIFxsaTBccmkwXG5vd2lkY3Rs cGFyXG5vb3ZlcmZsb3dcZmFhdXRvXHJpbjBcbGluMFxpdGFwMFxwYXJhcnNpZDc3NTc1NDAgXGZz MjRcbGFuZzEwNDlcbGFuZ2ZlMTA0OVxjZ3JpZFxsYW5nbnAxMDQ5XGxhbmdmZW5wMTA0OSB7XGxh bmcxMDI0XGxhbmdmZTEwMjRcbm9wcm9vZlxpbnNyc2lkMjIzMDI0NSANCntcc2hwe1wqXHNocGlu c3Rcc2hwbGVmdDIxODFcc2hwdG9wNjRcc2hwcmlnaHQ0OTQxXHNocGJvdHRvbTIwMThcc2hwZmhk cjBcc2hwYnhwYWdlXHNocGJ4aWdub3JlXHNocGJ5cGFnZVxzaHBieWlnbm9yZVxzaHB3cjNcc2hw d3JrMFxzaHBmYmx3dHh0MVxzaHB6MFxzaHBsaWQxMDI2e1xzcHtcc24gc2hhcGVUeXBlfXtcc3Yg NzV9fXtcc3B7XHNuIGZGbGlwSH17XHN2IDB9fXtcc3B7XHNuIGZGbGlwVn17XHN2IDB9fXtcc3B7 XHNuIHBpYn17XHN2IA0Ke1xwaWN0XHBpY3NjYWxleDYyXHBpY3NjYWxleTQ0XHBpY2Nyb3BsMFxw aWNjcm9wcjBccGljY3JvcHQwXHBpY2Nyb3BiMFxwaWN3NzkxMVxwaWNoNzkxMVxwaWN3Z29hbDQ0 ODVccGljaGdvYWw0NDg1XGpwZWdibGlwXGJsaXB0YWctMjA1NjA5NzQ3NHtcKlxibGlwdWlkIDg1 NzI3MTNlMTllNzNhYzNkNDc2MDNiNDBhNjE3NWQwfQ0KZmZkOGZmZTAwMDEwNGE0NjQ5NDYwMDAx MDEwMDAwMDEwMDAxMDAwMGZmZGIwMDQzMDAwODA2MDYwNzA2MDUwODA3MDcwNzA5MDkwODBhMGMx NDBkMGMwYjBiMGMxOTEyMTMwZjE0MWQxYTFmMWUxZDFhMWMxYzIwMjQyZTI3MjANCjIyMmMyMzFj MWMyODM3MjkyYzMwMzEzNDM0MzQxZjI3MzkzZDM4MzIzYzJlMzMzNDMyZmZkYjAwNDMwMTA5MDkw OTBjMGIwYzE4MGQwZDE4MzIyMTFjMjEzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMy MzIzMjMyDQozMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIz MjMyMzIzMjMyMzJmZmMwMDAxMTA4MDEyYjAxMmIwMzAxMjIwMDAyMTEwMTAzMTEwMWZmYzQwMDFm MDAwMDAxMDUwMTAxMDEwMTAxMDEwMA0KMDAwMDAwMDAwMDAwMDAwMTAyMDMwNDA1MDYwNzA4MDkw YTBiZmZjNDAwYjUxMDAwMDIwMTAzMDMwMjA0MDMwNTA1MDQwNDAwMDAwMTdkMDEwMjAzMDAwNDEx MDUxMjIxMzE0MTA2MTM1MTYxMDcyMjcxMTQzMjgxOTFhMTA4MjMNCjQyYjFjMTE1NTJkMWYwMjQz MzYyNzI4MjA5MGExNjE3MTgxOTFhMjUyNjI3MjgyOTJhMzQzNTM2MzczODM5M2E0MzQ0NDU0NjQ3 NDg0OTRhNTM1NDU1NTY1NzU4NTk1YTYzNjQ2NTY2Njc2ODY5NmE3Mzc0NzU3Njc3Nzg3OTdhDQo4 Mzg0ODU4Njg3ODg4OThhOTI5Mzk0OTU5Njk3OTg5OTlhYTJhM2E0YTVhNmE3YThhOWFhYjJiM2I0 YjViNmI3YjhiOWJhYzJjM2M0YzVjNmM3YzhjOWNhZDJkM2Q0ZDVkNmQ3ZDhkOWRhZTFlMmUzZTRl NWU2ZTdlOGU5ZWFmMQ0KZjJmM2Y0ZjVmNmY3ZjhmOWZhZmZjNDAwMWYwMTAwMDMwMTAxMDEwMTAx MDEwMTAxMDEwMDAwMDAwMDAwMDAwMTAyMDMwNDA1MDYwNzA4MDkwYTBiZmZjNDAwYjUxMTAwMDIw MTAyMDQwNDAzMDQwNzA1MDQwNDAwMDEwMjc3MDANCjAxMDIwMzExMDQwNTIxMzEwNjEyNDE1MTA3 NjE3MTEzMjIzMjgxMDgxNDQyOTFhMWIxYzEwOTIzMzM1MmYwMTU2MjcyZDEwYTE2MjQzNGUxMjVm MTE3MTgxOTFhMjYyNzI4MjkyYTM1MzYzNzM4MzkzYTQzNDQ0NTQ2NDc0ODQ5DQo0YTUzNTQ1NTU2 NTc1ODU5NWE2MzY0NjU2NjY3Njg2OTZhNzM3NDc1NzY3Nzc4Nzk3YTgyODM4NDg1ODY4Nzg4ODk4 YTkyOTM5NDk1OTY5Nzk4OTk5YWEyYTNhNGE1YTZhN2E4YTlhYWIyYjNiNGI1YjZiN2I4YjliYWMy YzNjNA0KYzVjNmM3YzhjOWNhZDJkM2Q0ZDVkNmQ3ZDhkOWRhZTJlM2U0ZTVlNmU3ZThlOWVhZjJm M2Y0ZjVmNmY3ZjhmOWZhZmZkYTAwMGMwMzAxMDAwMjExMDMxMTAwM2YwMGJmZjBiN2UxNmY4Mzdj NDdmMGUzNDlkNWI1NmQxYmVkMTcNCmQzZjlkZTY0YmY2YTk5Mzc2ZDk5ZDQ3MGFlMDBlMDAxYzBh ZWMzZmUxNDk3YzNjZmZhMTdiZmYyNzZlM2ZmMDA4ZTUxZjA0YmZlNDkwZTg1ZmYwMDZmMWZmYTUx MjU3YTA1MDA3OWZmMDBmYzI5MmY4NzlmZjQyZjdmZTRlZGM3DQpmZjAwMWNhM2ZlMTQ5N2MzY2Zm YTE3YmZmMjc2ZTNmZjAwOGU1N2EwNTE0MDFlN2ZmZjAwMGE0YmUxZTdmZDBiZGZmOTNiNzFmZjAw YzcyOGZmMDA4NTI1ZjBmM2ZlODVlZmZjOWRiOGZmMDBlMzk1ZTgxNDUwMDc5ZmZmMDBjMg0KOTJm ODc5ZmYwMDQyZjdmZTRlZGM3ZmYxY2EzZmUxNDk3YzNjZmYwMGExN2JmZjAwMjc2ZTNmZjhlNTdh MDUxNDAxZTdmZjAwZjBhNGJlMWU3ZmQwYmRmZjAwOTNiNzFmZmM3MjhmZjg1MjVmMGYzZmU4NWVm ZjAwYzlkYjhmZmUNCjM5NWU4MTQ1MDA3OWZmMDBmYzI5MmY4NzlmZjQyZjdmZTRlZGM3ZmYwMDFj YTNmZTE0OTdjM2NmZmExN2JmZjI3NmUzZmYwMDhlNTdhMDUxNDAxZTdmZmYwMDBhNGJlMWU3ZmQw YmRmZjkzYjcxZmYwMGM3MjhmZjAwODUyNWYwDQpmM2ZlODVlZmZjOWRiOGZmMDBlMzk1ZTgxNDUw MDc5ZmZmMDBjMjkyZjg3OWZmMDA0MmY3ZmU0ZWRjN2ZmMWNhM2ZlMTQ5N2MzY2ZmMDBhMTdiZmYw MDI3NmUzZmY4ZTU3YTA1MTQwMWU3ZmYwMGYwYTRiZTFlN2ZkMGJkZmYwMA0KOTNiNzFmZmM3Mjhm Zjg1MjVmMGYzZmU4NWVmZjAwYzlkYjhmZmUzOTVlODE0NTAwNzlmZjAwZmMyOTJmODc5ZmY0MmY3 ZmU0ZWRjN2ZmMDAxY2EzZmUxNDk3YzNjZmZhMTdiZmYyNzZlM2ZmMDA4ZTU3YTA1MTQwMWU3ZmZm MDANCjBhNGJlMWU3ZmQwYmRmZjkzYjcxZmYwMGM3MjhmZjAwODUyNWYwZjNmZTg1ZWZmYzlkYjhm ZjAwZTM5NWRlZWVlNzE5ZWJkMzI2OWUzYTUwMDc5ZmZmMDBjMjkyZjg3OWZmMDA0MmY3ZmU0ZWRj N2ZmMWNhM2ZlMTQ5N2MzY2ZmDQowMGExN2JmZjAwMjc2ZTNmZjhlNTdhMDUxNDAxZTdmZjAwZjBh NGJlMWU3ZmQwYmRmZjAwOTNiNzFmZmM3MjhmZjg1MjVmMGYzZmU4NWVmZjAwYzlkYjhmZmUzOTVl ODE0NTAwNzlmZjAwZmMyOTJmODc5ZmY0MmY3ZmU0ZWRjNw0KZmYwMDFjYTNmZTE0OTdjM2NmZmEx N2JmZjI3NmUzZmYwMDhlNTdhMDUxNDAxZTdmZmYwMDBhNGJlMWU3ZmQwYmRmZjkzYjcxZmYwMGM3 MjhmZjAwODUyNWYwZjNmZTg1ZWZmYzlkYjhmZjAwZTM5NWU4MTQ1MDA3OWZmZjAwYzINCjkyZjg3 OWZmMDA0MmY3ZmU0ZWRjN2ZmMWNhM2ZlMTQ5N2MzY2ZmMDBhMTdiZmYwMDI3NmUzZmY4ZTU3YTA1 MTQwMWU3ZmYwMGYwYTRiZTFlN2ZkMGJkZmYwMDkzYjcxZmZjNzI4ZmY4NTI1ZjBmM2ZlODVlZmYw MGM5ZGI4ZmZlDQozOTVlODE0NTAwNzlmZjAwZmMyOTJmODc5ZmY0MmY3ZmU0ZWRjN2ZmMDAxY2Ez ZmUxNDk3YzNjZmZhMTdiZmYyNzZlM2ZmMDA4ZTU3YTA1MTQwMWU3ZmZmMDAwYTRiZTFlN2ZkMGJk ZmY5M2I3MWZmMDBjNzJiZTU4ZjE2NThkYg0KZTk5ZTMyZDcyYzJjZTNmMmVkNmQ3NTBiODg2MTRk YzRlZDQ1OTE4MjhjOWU0ZTAwMWQ2YmVlN2FmODgzYzc3ZmYyNTBmYzRiZmYwMDYxNWJhZmZkMWFk NDAxZjRmZjAwYzEyZmY5MjQzYTE3ZmRiYzdmZTk0NDk1ZTgxNWU3ZmYNCjAwMDRiZmU0OTBlODVm ZjZmMWZmMDBhNTEyNTdhMDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ5 NDAwYjQ1MjUzNGIwMWM5MzhmN2NkMDAzZThhNjA3MDQ3MDc3N2QyOTAzMzkzYzUwMDQ5NDk5MWVh DQoyYTNmOThmMWYzN2UxYzUzNGFmNWU4MzFjZTQ5Y2ZkNzM0MDBmMmZjZTM5MjdkMDU3MjdlMmRm MTkwZDAyY2FlNWVjZTNmYjU1Y2MwMTRiYzZhYzA5NTJjNzAxNDBlYTVmOTA3NjhlZDlmNjA2Yjc4 OGZjNWMyMTQ5NmRmNGQ5OQ0KMTg0NmRiNjdiODY2ZWJmMjkzYjIyMDAxMDVmOGM2NDgwYTNkY2Yw MmE3ODY3YzI0ZDc5MzhkNGY1Mjg1ZTNiNjU5MzdjMTY0N2EzMzZlMzg3OTM5M2I5YjFkYzkyN2Rj ZDAwMmY4NjQ2YTlhZmYwMDg4MWY1YWQ0NjVkNGEyODINCmM5OGM1Njk2ZjIyMThhMzliMmFiYmE0 ZGEwNjRhZjNmMjg2YzkxOWFmNDIxZDA1Njc1ZjJjNDY1NGYzYjAyMzU0MmVjYzQ4MTlkYTQxYzcz NWEwMzgwMDYzMWVkNDAwZWEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwDQphMjhhMjgw MGEyOGEyODAwYTI4YTI4MDBhZjg4M2M3N2ZmMDAyNTBmYzRiZmY2MTViYWZmMDBkMWFkNWY2ZmQ3 YzQxZTNiZmYwMDkyODdlMjVmZmIwYWRkN2ZlOGQ2YTAwZmE3ZmUwOTdmYzkyMWQwYmZlZGUzZmYw MDRhMjRhZg0KNDBhZjNmZjgyNWZmMDAyNDg3NDJmZjAwYjc4ZmZkMjg5MmJkMDI4MDBhMjhhMjgw MGEyOGEyODAwYTI4YTI4MDBhMjhhNGEwMDA5YzU3MTVhZTc4ZjA2OTllMzVkMzNjMzM2OTYyZDc3 NzM3ODM3MzMwN2RhMTA2NGZlN2QwZmUNCjU1ZDE2YWI3ZmYwMDYxYjczODI3Y2M5MDkwOThlNDhl ZDljN2I3MDNlYTQ3YTlhZjI4ZjFkZDg5ZDIzYzU5ZTE4ZDYzNmI5ZDRhZGMzZGNjYzQzZmRlNTEy MjBmMmYzZjQ2NjFlZTU4ZmFkMDA3YWZjMjk3NTIyMGZiNDMwNTNmDQplY2YxNTM3OTBhNTgxNjNi ODhlODQ4Y2QzZDE5NjQ0NTc1MjE5NTg2NDExZDA4YTdkMDAzNGFlNDYwZjNmNWEwMDAzYTAwMjk2 YTI5MjQzODIxMzE5MWQ0OTNjMGEwMDczMzZkMDRmMjRmYTBlZjVlN2JlMmJmMTM1ZWNiNzUyNg0K OWI2MmJlNTQ0OTk1YjliOGRkYjgyZTc4ZGFiOGU1OWIyNDAyM2I1NWVkN2JjNTA4OGYzNDY4ZmU1 NWFjNjBhYzk3NjczOTkxOGVlZjkyMjBhMDkzZjcxYjI3ODA3MTgwNzM5MjIyZjBiZjg3ZWU2ZTY1 ODJmYjU1OGUxNGI2ODkNCjdmZDBlY2UzNTE4OGNiNjE4YjEzY2U0ZjFkNzljZmFkMDA2NDc4M2Jj MDg1ZWU3ZmI0ZjU1ODcxMGVlZGYwZGFiMmUwODYzZDRiN2FmNWM2M2ZjOWY1MjAwNzVlMzNlYjQw MDAyODAwMGMwMWM3MTRlYTAwZTFiZTI2Njk1YWE2DQpiM2EyNWJkYWU5ZWM5MTQwNmUxMDVlY2Ri ZDgzYzcwMTNmMzZjYzBlYmM1NzZiMTIwOGExNDhjNzQ1NTBhM2YwYTgyZmM0ODZjNjdmMjgwMmZi NGUwMWVmZDMzNTY1NGU0NjQ5YzllZmY1YTAwNzUxNDUxNDAwNTE0NTE0MDA1MQ0KNDUxNDAwNTE0 NTE0MDA1MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1N2M0MWUzYmZmMDA5Mjg3ZTI1ZmZiMGFkZDdm ZThkNmFmYjdlYmUyMGYxZGZmMDBjOTQzZjEyZmZkODU2ZWJmZjQ2YjUwMDdkM2ZmMDAwNGJmZTQ5 MGU4NWYNCmY2ZjFmZjAwYTUxMjU3YTA1NzlmZmMxMmZmMDA5MjQzYTE3ZmRiYzdmZTk0NDk1ZTgx NDAwNTE0NTE0MDA1MTQ1MTQwMDUxNDUxNDAwOTUwZGM0ZTk2ZDAzY2NlN2U1NWY3ZWE2YTUyNDAz OTI3YjdlNTU4MTM5M2FkZGY3ZDk5DQo3ZmUzY2UzMjBiYjExZjc4ZmYwMGY1ZjkxZjk5ZWE1Njgw MGQzZWRkZWZhZTliNTJiOGU5OTNlNDgyM2E3NTFiYmYwZTgzZjNhZTFiZTI3ZWU2ZjEzNWEyYWJl ZGYyYjRjOTY3N2RjMzcwYzI0OGIyOGNmZjAwZGZhNmZkMmJkNQ0KZDExMTIzNTU1NTAxNTQwYzAw MzE4YWYzMGYxYjIxOTdjNzYyMmQ5MTk4ZTRkMmZjYTkwMzEyMGIyYjc5ZTBhODFkYzlmZjAwZTI0 NzcxODAwZWQzYzI1NzI2ZTdjMzE2Mzk2ZGNkMGExODE4ZTMwMGI0NmM1MDkxZWM3NmU0NTYNCmUx NjBhM2FkNzhlNjgzZTJlOTc0MGYwNmVhNDBjNjdlZDllNTQ3MzVhNDY3ZTYzYjllMjA3ZTZmYTNh YmIxMWY1MWRlYmQ2ODE2NThjMzRjZWE1OTU3MmM3YTJhZmE5MzQwMTIzYmU3MjQ5ZGE4MzkyNzM4 YWUxZmM0ZGUyNThlDQo1NGI4ODYxOTI3MTY5MWJhYzEyMzQzMWIyYjVjNDhjZDgxMWM2YzQ2MGY3 YzkxZjQwNzM5MjFiZTI0ZjEzODU4ZTI2Yjc2ZGY2YWVlNTU1MDAyYWY3NThlYTAzNzQ0NTFmN2Iy NzhjMjljZTE0ZWUyZWYwZTc4NWM2YTEzYzdhZA0KZWE4YWQyMDJkZTY1YmRiYmEwMDIzMDMzYjQ4 MTgxOGNmMDcxODFjYWFmYTBhMDAzYzNmZTFjNmQ0NmYwNmIxYWJkYmM3MTYxNTEyZDZkYjFjMjA1 MTkxOTFkZmE4MWNmMjc2OGVkYzU3N2EwMDJhMzIzMjcxNDAwMDc0MDNmMGENCjcwZTk0MDA1MTQ1 MTQwMGQ2MDA4M2Y0YTZjNDQxMTkwMzgzY2Q2NzZiYmFkZGFlODFhNTVjNmE1N2NkMjhiNzgwNjVm Y2E4Y2JiN2U0MDdmNGZjNmI4OGYwNGZjNTEzZTM0ZjEzNGI2NTYzYTI1ZDQzYTVhNDQ0YWRkYzg3 YWIwDQozYzAzOGUwNjQ2N2Q3YTUwMDdhNjUxNDgzZWU4Y2U3MzhlZjRiNDAwNTE0NTE0MDA1MTQ1 MTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQwMDUxNDUxNDAwNTdjNDFlM2JmZjAwOTI4N2UyNWZm YjBhZGQ3ZmU4ZDZhZmI3ZWJlMg0KMGYxZGZmMDBjOTQzZjEyZmZkODU2ZWJmZjQ2YjUwMDdkM2Zm MDAwNGJmZTQ5MGU4NWZmNmYxZmYwMGE1MTI1N2EwNTc5ZmZjMTJmZjAwOTI0M2ExN2ZkYmM3ZmU5 NDQ5NWU4MTQwMDUxNDUxNDAwNTE0NTE0MDA1MjUyZDI1MDANCjczN2UyMmQ3ZWRlY2FlNjBkMzE2 NmNkZGRjYjA1MTE0NzkyZDgzOTM4ZTNhNjQwMjczZThhN2RhYjUyZGEzODJjNmQwMjZmMThjODBj YzQ2MzcxMjc2ZjRlZGRiOGFmMzU4M2UxYTJlYTdlMzFkNWY1ZWI4ZDY3NTBiNjdiZjlhDQo3ODU1 NmQxODQ2ZjFhYWM5OGM2ZjIxYjgyMTczZDA2MzhlNjkyZWZlMWM3OGNlMjU1NGIyZjFkZGZjZjZj MzA1NTI1NDBhZTMwNzIzYWU0NzFjN2E1MDA3YWMxOTU0NjBiMzI4MDdhNzNkNmJjOGZlMjI1Yzk4 YmUyMDY5YThkZQ0KNmFjMTI0NzEyYjQ5MTI2ZTMxOTFmNjhlNGUzM2QwMzM5ZTllZDU5NTc3YTdm YzQwZDNmMjI3ZDRkYTdmMjQwNjg4ZGY4OTU1NjUyNDkwN2Y3OTBjODU1NzE4MWY3OGFmNWU4MmJj ZWQ3NTJkN2ZjNTVlMjc5MmRmNTk5ZTRiODANCmJiYzM0MTE1ZDEwYTQ0NmIyNjAyYjgxMjFlMDk3 YzFlNzM5M2ViNDAxZDZjNzMzNWI2YjlhNjY5YjNjZjI0NmFmN2IzNDEyN2NlMDE5ODQ3MzZlMDRm ZjcwNzk2ZWMzZjBjZDdhMWY4ODdjNjUwNWQ0NzczMGM0YzNlYzg5MTkxDQoxYTA2MDFhZTY0YzY3 MjA2NDFkOGEwYTkzOWRiOWNmNzUxZjM3ODI0OTA2OTE3N2FlMjY5OTZkYWFlYTUwNWUwYmFmMjYz OTY1OWM0YjBhMjZkZGFjNzM4MGRjODE4YzEwMzhlMzFkYWJkZjNjMTNlMTFiOWZiMzJlYTFhZjRl ZA0KNzczYmI4NjQzMjhjMTk4MGMxMGNjYmQzMWJiMjQwMWQ3ZTUyZGM4YTAwYjllMWJmMGRjYjJj YTM1M2Q1NGYwOGFjOTE0M2I0ODU1NWRkOTAwMDZlNTUwNzY1M2Q0N2NjZDVkZGQyMjgwNTQxMjA2 NzAzOWViZmFkM2E4MDBhMjgNCmEyODAwYTI4YTI4MDFhYzhhZWE1NTk0MzI5MDQxMDQ2NDExNGM4 NmRlMWI2ODUyMTgyMThlMjhhMzE4NDQ0NTBhYWJmNDAzYTU0YjQ1MDAwMzgxNDUyNTJkMDAxNDUx NDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0DQo1MDAxNDUxNDUwMDE1ZjEwNzhlZmZl NGExZjg5N2ZlYzJiNzVmZjAwYTM1YWJlZGZhZjg4M2M3N2ZmMDAyNTBmYzRiZmY2MTViYWZmMDBk MWFkNDAxZjRmZmMxMmZmMDA5MjQzYTE3ZmRiYzdmZTk0NDk1ZTgxNWU3ZmYwNGJmZQ0KNDkwZTg1 ZmYwMDZmMWZmYTUxMjU3YTA1MDAxNDUxNDUwMDE0NTE0NTAwMTRkNmUzOWVkOWE3NTM3OGU3ZDI4 MDMwZWMxMjM3Yjk4MzczMTczMjJkZDMwMGZjZjA2NDQyNDdkMmI2Nzk0M2VhM2E2N2JkNjBlOWYy MTlhZmY0YTkNCjE3ZWU3ZDlhZTc5ZjQzYmQyYmEyYzYzOGEwMDg4OGRjNzgxODE5ZTRmYjYyYmU1 NmY4YzkzNDlhN2ZjNDc3OWVjYWUyNWI3OTlhZGQyNGRkMTM5NGMwMjFiMTgyM2Q4OWZjZWJlYWQ2 MDBhOTFkYmJkN2M5ZmYwMDFjMTQ0N2YxDQowNTUzMTlkYmE3YzAzZWJjMWEwMDdmODYzYzI5YTg3 ODVlZmYwMDQyZjEzNmJmNjEwMzY4MzNjZDA0ZGY2ODNiNjUyMzc4M2I1NGFmNWU3MzkzYzFlODJi ZWFjNDAwYWY0ZmJkZDcyM2FmZDZiZTZhYjJmMWJhNzhmZjAwNTVmMA0KNTc4NTU3NGI1YjNiM2Iy YmI4OWU0MGQyMDkwNGUyMzVlMzhkYTMwMzg2ZTMyN2FkN2QyYzNhMGEwMDc1MTQ1MTQwMDUxNDUx NDAwNTE0NTE0MDA1MTQ1MjUwMDczOWFlZjg4MmU3NDNkNTZkNWE2ODIyNmQyNjUxZTViNGRlNjYN CjFkMjZjOWMwYzc0YzYwMWZjNzE1Nzc0OGQ3ZWM3NWRiNjY5YjRmOWJjYzBhNGFiMDIzMDQzMGUz ZjQzOTA3ZGM1NGY3ZGE3ZDhlYTcxMzVhNmEzNmQxNWU0MGVkYmNjNzNjNjE5MDYzYTcwN2I4MzVj MzVlZTk3NzFlMTFiZThhDQo3YjViOTkyMmQxOTI0NjA5ZTVmZjAwY2IwZGVjNTk5NTkwMmZjZTk5 MzkwMDMyOTE5Y2YzNDAxZTkxOTA3YTUyZDYyZThiYWQ0N2FjNDI0YWExOGE1NTAwYmM2NDhlMDEx Zjc5NDhmYmMyYjU4MzM2MzkzY2ZkMjgwMjRhMjliYg0KYThkZGU5ZmFkMDAzYThhNGNkMTQwMGI0 NTI1MmQwMDE0NTE0NTAwMTQ1MTQ1MDAxNWYxMDc4ZWZmZTRhMWY4OTdmZWMyYjc1ZmYwMGEzNWFi ZWRmYWY4ODNjNzdmZjAwMjUwZmM0YmZmNjE1YmFmZjAwZDFhZDQwMWY0ZmZjMTINCmZmMDA5MjQz YTE3ZmRiYzdmZTk0NDk1ZTgxNWU3ZmYwNGJmZTQ5MGU4NWZmMDA2ZjFmZmE1MTI1N2EwNTAwMTQ1 MTQ1MDAxNDUxNDUwMDE0ZDNjNTNhOThkODFkNzgxNDAxODFlMWY1ZGY2M2E3NGMwMDBhMjI5YzFm YzY0NWZmDQowMDBhZThhYjI3NDI4ODQ3YTNkOTI4YzE1MzE5NmUwNzYzY2ZmNWFkNjFkMjgwMjFi OTI0NDEyOTA3MDc2MzFmZDJiZTc4Zjg4M2EzZTk5YTlmYzRhOTZlZjVhYjgxMWU5ZDEyZGJkYWIy MmJlMTg5Njg2NDZjOGMwMjdhYThlZA0KZmM1ZWQ1ZjQzZGQxYzViNGE3OGZiODQ3M2Y0YWY5ZWJj Nzk2ZGFiY2ZmMDAxMWFlNjVkMmNjNDkyNDZmMGEyYjRjNjM1NGRkZTRjODAxM2U2MmVkMjA2Yzdl YTc4MTlmNWEwMGNjZjA3NjhkNmZhN2Y4ZDZjMmVmNDg5MTVhYzENCjI1ODVjYjQ5MjIzMzkyNjVk ODA3Y2E0OTVjZTRmMGMxNGY0YzgwNmJlOWMxY2E4MjJiZTQ5ZjA3ZTg1Nzc2YmUzNGIwYmZiZGNj ODEyZjJkZGM5ODcxMjQ0ZGJlNjAwNjU5NzhjNmUwNDhjNjdhMDM1ZjViMmY0MTQwMGVhMjhhDQoy ODAwYTI4YTI4MDBhMjhhMjgwMGE0YTVhNGEwMGU1YmMzZWRhYmFmODhiYzQzNjM3ZDIwOWFjNjJi ODEyNTljZDlmOWQ1NjQxYmQ5MTg3YTAyNzAzZGFiYTQ5YTE4ZWUyMDc4YTU4ZDY0OGRkNGFiMjkx OTBjMGQ2NWU5ODA3Zg0KYzI0N2FlZjFmYzcwN2ZlOGIxNWIyMDBjMGUyODAzY2QzNTNkMWFlYmMy ZmFjYzVhODQxN2FkMTY5ZmJjZTI1NjY3MjYzY2YyNDM4ZmJiYjdhZjI3ZmJkZmVjOGFlYWI0MGYx MGE2YTk2ZmU1ZGMxNTgyZjIzNWRkMmM1YmMxMDUNCjdhNmY0MjM4Mjk5ZThkZTlkNzlhZGM5ZTA4 YWUyMjY4YTU4ZDVlMzcxODY1MjM4Yzc2YWYzOGQ1NzQ5OWZjMmZhOWMxNzY5YmRiNGY0NzczMDRl OTE4MzJkYjMzMmI3YzgzOTFiOTQ5MjM4Y2UwZmQ3OWEwMGY0YjAzOGU3MTlmDQphNTFiNDFhZTZi YzNkZTI0MWE4NDUxYzM3M2U1MmRjZWNkYzNjODcwZDE0Y2EzOGNjNjczZjk4ZWQ1ZDIyMzAyMzE5 MTkxZDY4MDA2NTM4ZTI5MDA3MWRlYTRhNjM3NWM3ZTk5ZjVhMDBlNmFkN2M2OTYzNzNlMzdiZGYw YTk4ZQ0KNThhZmFkYTE1OTgzM2ZkZDk1NGUzYTdhN2RlMTVkMzgyMDgwNDc0MzVlNDFlMWRiNTVk NjNlMjdmODg3NTM4YzhmYjViNDQxZWRlNGNlNDZjNTdkODA3ZDNlNWZjZmU5NWVhMWE2NWYwYmRi NzA0ZTQ0YTljMzA2ZTBmZTU0MDENCmExNDUwMzkxNDUwMDE0NTE0NTAwMTVmMTA3OGVmZjAwZTRh MWY4OTdmZWMyYjc1ZmZhMzVhYmVkZmFmODgzYzc3ZmYyNTBmYzRiZmYwMDYxNWJhZmZkMWFkNDAx ZjRmZjAwYzEyZmY5MjQzYTE3ZmRiYzdmZTk0NDk1ZTgxNWU3DQpmZjAwMDRiZmU0OTBlODVmZjZm MWZmMDBhNTEyNTdhMDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNTFjODMyYWMzM2I3MjNhZmE1NDk0ZDZl MDEzZjlkMDA2NmU5ZTNjOGIyZDM2MTU2MmMzZWNjMDZlZjVjMjhhZDRhYzg2OTQ0NTczYQ0KNDJh OGMyYzhhYzMxZTgzY2JjZTNmNGFkN2EwMGFmNzYwMWI1OTAxZjRhZjE1ZjEzNThjMzc5ZTNiOGEz NmMzY2IzNWYyZTIyOTBlNjMyYWIxNGNlMGUzOTE5ZTQ3NmU3YTYwOGFmNjhiZTIxNmRmOWU4NWQw N2U2YzMzNWUxZmUNCjJlYjFiOTk3YzViNmQzNWJiZTRjYTYwOGRhMGMwNTMyMTE2ZjMzNjc3OTIw ZTMwNWI4ZjUyM2FkMDA0ZGE4NmE4Zjc3ZTJkZDIyZDc1MjIwNGQxNDc2NjliMjM4Y2UzY2NmYjVh ZWMyZGI3MjAxZGE1ZjgwNzA3Yjk1M2M1N2I5DQoyZTc2OGNmNWM1Nzg4MDdkM2U2ZDczNGJiNGIw ODFhYzk5MmQ2ZDFlNjU2NzI1ZmU1YmM0ZTMzOGY5YjNiOTc4MzhlMDc0MTVlZGVhNDk1MDRmNWM1 MDAzYThhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjkyOTY4YTAwYzVkMmZmZQ0KNDYzZDczZmRmODdm ZjQ1OGFkYTFkMmIwYjRkNjZmZjg0YTc1YzVjNjE3ZjcwN2ZmMDAxYzM1YmEzYTUwMDE4Y2Q0MzNk YmM1NzMwYmM1MmM0YjI0NmUzNmIyYjBjODIyYTZhMzE0MDFlNWZlMjNkMDI2ZDFlZTNjZTVjYmU5 YWQNCjcxODUyYjlkZjBiM2U3YTYzZmRhMmJjMGUwZjNmYzVmN2I0M2MzN2UyMzk1ZTA0NGI4OTU0 YjI5MzgyYTcyMTk3ZmJjYmVhYmViZGM3NjA0NzM1ZGRjYjBhNGYxM2M1MjIwNjU2MWI1ODExZGFi Y2M3NWRmMGRkYzY4OWE5N2RiDQo2MDY1M2E1YWNjYWVhMTA2ZDMxMzEyYTE4ZTQ3N2UwZmZiMjcz OGM2ZWZiYzAxZTkzNmQ3NmI3MTEyYjA2MDczZDE5NGU0MWFhYmFmNWRjYjY1YTBkZWRjZGJlZDE3 MDIyNjU4MDNlMzA2NTNjMjY3ZGI3MTE1YzdlOTNhOWIwNw0KNTEwY2E4NTlmMjIzOTNmZTU4ZGRm ZjAwYjU4ZmUwNzFlOWRmZDBmNWFlNmI1ZWYxMzVkZGIzNmFkYTZiYmVkNTRiYmZiNTZkNzM5Nzhk NDQ2NjQyYjhlOGNiYmMyOGZjNGQwMDZhN2MzODhhZGQ3YzUxMzFiNzU2ZmIzYmU5NjANCmMzYjhl N2Y3NjZlNjYyYmZhMWFlZWFmZTM3YjRiYTViZjgxMzIwN2ZhZTUwM2FlN2I4ZmYwMDNkZjNkOGQ3 MDFmMGYxYTM4M2M1OWY2NzQ2MmNmMDY5MzFjMGM4MGYxOThkYjI0ODFlODRiOGZkNmJkNWQ4MDc1 MjE4NjQxMTgyDQoyODAxOTZmM2E1YzQyYjIyMzY0MTE1MzU2MTQ0NWI0OWJlMzA5M2ZlOGIyOWY5 MDkxZjc0ZmE2N2ZjZjVmZjAwNjRkNmUwMzkwMGU3MzQwMGI0NTE0NTAwMTVmMTA3OGVmZjAwZTRh MWY4OTdmZWMyYjc1ZmZhMzVhYmVkZmFmOA0KODNjNzdmZjI1MGZjNGJmZjAwNjE1YmFmZmQxYWQ0 MDFmNGZmMDBjMTJmZjkyNDNhMTdmZGJjN2ZlOTQ0OTVlODE1ZTdmZjAwMDRiZmU0OTBlODVmZjZm MWZmMDBhNTEyNTdhMDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNTBkY2M4MjINCjgyNTkwOWM2YzUyZGY5 MGE5YWE5ZWE0YWE3NGRiYWRjZGI0MTg1YzE2Y2Y0MTgzY2QwMDU1Yjk4YzJkZGU5MDU4ZmNjOGVj MTQ3YWZlZTlhYjVhYjIyZmQ0OGQ1MzQ1YzllNDRjZTBlM2ZlYjhiZDZiZDAwNTNkNDY0MTFkYjY0 DQo4MDQ5NzE4ZmMzOWZlOTVmM2VmYzRmZDY2ZWJjMzdlMzNiN2I4Yjc4ZTMzMzQ3MWMwNjFkZWUz MDlmYmE3NTczYjNmZTA2YmNmYjU3YmRlYjU4MTY4MWIwMGUxYmZmMDA2NTM1ZTJiZjEyZjQ2ZDJi NTNmMWVhYWVhMjkyYzg3Mw0KMDQyYjFjNTJlYzI0MThlNDI3Zjg1OGU3NzA0ZThhZGM2NzhlZjQw MWNkNDdlMmZkMjc1NmYxOTY5ZjMyYTVkNWM1ZTJjOTAyMmM5Mjg1NjA2NDE3MTFiMWRiYjA4MDE3 NjgyMDY0NzVhZmE4MDc0MWM2M2RhYmU2ZmQzZmMxNzYNCmZlMWFmMTFlOWY3NjA0ZDY4NWUyOGVl NDJjYTA0YTdmZTNlYTE1YzBlOTgxODI0ZTczOWY2YWZhNDE3ZWU4ZWRjNTAwM2E4YTI4YTAwMjhh MjhhMDAyOGEyOGEwMDI5Mjk2OTI4MDMxYjRmMjA3ODhmNTk1ZWY4ODRmZmUzYTZiDQo2YWIxMzRl MjFiYzRmYWMwZWUxNjBmZTRkNWI3NDAwNTE0NTE0MDAxMDBmNTE1MGNmMDQ3NzExNDkwY2E4MWUz OTE0YWJhOTFjMTA2YTZhMjgwM2NhZmM1NWUxZmJjZDFjY2QyNTlhM2M5YTZjYTA0OGUxMGVjNzg5 ZDdmODgzNw0KNTBmZWZkMGY3YzlmYmRlNjU3N2UyMGZlZGJkNzY1OTJkZWRiNTA5YTAxMDhiNzkx ZDYxMzljOTZjMWNlNGUwNjU0MTA3ZGMxYWZhNzI2ODYzOWUyNzhlNTQwZThjYTU1OTRmNDIwZDdj YzdmMTVlYzVmNDJmMWU0NzZmNmI3ZDINCmJhYjVhMjM0NTAzMmZkZDVkZjIzNjBmNjM4M2M4Y2Y2 NmM1MDA2ZDc4NGZjNjVhNzY4NWUzNmJiZDUzNTk4ZWUyZDFlZTYyZDg5MWJhMjYxMTdlNTIwMTZl MDBlZmQ0OGVhNmJkMDJlM2UzMDc4NzYwOGNlNGNkMjM4MjU3ZmQxDQo0MjRmOTFkMTRmYzhjN2E5 ZmViNWUyZmUxYzg2Y2JjNjNlM2Q4NTI3YjU4ZTA4MGMyYWQyMDUwOGY5NjVlNDkyMzgxODYzYzYz MDZiZThjZDNiYzIzYTQ1OGFlM2M4MzJiMDUwODU1Y2ZjODAyZjQxYjA2MTM4ZWM3MTQwMWNhNA0K ZmYwMDEzMzQ5ZDc2MTdiMWQzZjRlZDc2N2I4M2MwMjlhNzMxMzExYzhmOWM4ZjQ1ZWUzYmU2YjU3 ZTFiZjhiMmZiYzRmYTU1ZTJlYTNhNmNiNjc3NTYxMzBiNzYwYzBhODdlM2FlMGY0ZTczYzU3NWYx YzUwYzMwZjk1NmYxMjINCjI4MDMwMTE0MDFjN2E2MmIxN2MzYjMyM2M5MWEwZGMxYmVjMzA0ODE3 YjAxOTc1ZmNmOGEwMGU5MDc0YTI4MWQwNjI4YTAwMmJlMjBmMWRmZmM5NDNmMTJmZjAwZDg1NmVi ZmYwMDQ2YjU3ZGJmNWYxMDc4ZWZmZTRhMWY4OTdmDQplYzJiNzVmZjAwYTM1YTgwM2U5ZmY4MjVm ZjAwMjQ4NzQyZmYwMGI3OGZmZDI4OTJiZDAyYmNmZjAwZTA5N2ZjOTIxZDBiZmVkZTNmZjRhMjRh ZjQwYTAwMjhhMjhhMDAyOGEyOGEwMDJiMzc1OTU1N2QxZWYxNWYzYjFlMzJhZA0KY2UzYWYxNWE1 NWNmZjhjZjU0YjFkMjNjMzM3NTc5YTgzMzJkYmEzMjZlMDg3MGNkZjMwM2I0NTAwNWNiZjVmZjAw ODk4ZTkxYjczODU5ZGZmZjAwNDRiZDZhNTUxOWQxMjY5ZWM2NDU2MDQyNDg1YzExZGM3OTZjM2Zh OGFiYzMNCmE1MDA2NjZhZTU3NjQ2YTQ2NDMxYzYzZGM5MGJmZDZiY2JmYzcxZjY1OWZjNzkxYzM3 OWM1OWE1Y2RiYzk3MDQ5MjMyMGMzMjg1YzExY2U0N2NkZDNiZTJiZDRmNTA4OTY2OTYwNTJjNDYx ODM2MDFmNDkxMmJjYTdjNzE2Y2Y3DQo3ZjEwNjA4ZWRhNzU4YWY1ZWUyMzhlMTI0YjYwMDE2ZjMz OWRkYjRlNDczODE5MTgyMDMwM2Q2ODAzMGI1ODk2NTg2ZmFjYTI4Y2RjNWU1YmMxYTdmZWVjY2Q4 NDc0NGYzNjE2YzkxZDcxOGNlMDkzODNjNjMxNWY0MDhmYmEzZg0KYzJiYzA3YzQxNzU2ZDAyNDU2 MGM5MTY5ZjM0N2E1Y2QyNGFhY2VhNTY2YzNjNmUxZDFiMzg3ZGM1NDcwZGYzMDAwZjdjNTdiZjJm NGU2ODAxZDQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ5NGI0OTQwMThmNjExODFlMjFkNWUNCjQw NDE2NjEwOGM3ZDE0ZDZjZDYxZTljODQ3ODliNTc2ZjMzMjhjMjJjMmZhMWRiNWI4M2E1MDAxNDUx NDUwMDE0NTE0NTAwMjYyYmM4NmZmMDA1Y2QxZmMyN2YxN2Y1YThmNWQ5NjM0YjVkNGVjYTE5ZWRl NDc1ZGM2MzYwNGEzDQoyODNkNDY3MGM3MWQyYmQ3YWJjMGZlMzFlODkyNWZmOGUyMWI4NjQyOTEx YjU4ZTJmM2Q0NjU5MDBmMzU4ZmNiZGM1MDA3MWRmMGM4YWI3YzQ2ZGQxM2IzYTBiNjdkOGM0NjA5 MTlmZDJiZWFiMGFiODFmMjhlOWU5NWYzOTc4MQ0KYjQwODM0Y2Y4OGQwNGY2MTdhOTdkNjMyYzZl OGIyMjhjMWNmOTAyNDIzMWY1YzhhZmEzOTdlZTBjOGMxYzdhZDAwMjYzMTljNzFkZWIyMzQ2ZjI5 YmM5NzhkMTEzNzU5Yzc4ZmVmNjM3MzYzZmNmYmQ2YzFlOWZlN2QyYjFlYzQNCjJhNmFhMjM1OGY2 ODM2NTFlMWJkMzBjZGZlMjI4MDM2YmI1MTQwZTk0NTAwMTVmMTA3OGVmZjAwZTRhMWY4OTdmZWMy Yjc1ZmZhMzVhYmVkZmFmODgzYzc3ZmYyNTBmYzRiZmYwMDYxNWJhZmZkMWFkNDAxZjRmZjAwYzEy ZmY5DQoyNDNhMTdmZGJjN2ZlOTQ0OTVlODE1ZTdmZjAwMDRiZmU0OTBlODVmZjZmMWZmMDBhNTEy NTdhMDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNTg3ZTI2ZjBlNjk5ZTI2ZDMwNThlYWQ2ZmU3NWIwOTA0 YmI3N2VkMjA4ZTg3MzViOTUwNQ0KYzFjNDcyNjNkMGZmMDAyYTAwYWNiMTQ1MDQzYTc0NTZlMzZj MmE0MjIwMDdmODQyMWMwZmQwNTY4MGU4MmE5NDg3MWY2MzE4ZmUyMWY4NzE1NzI4MDI5Y2U4MGVh MzZlZDllNDAyMGZiZmY5YzBhZjBkZjhhNTc3N2Q2M2UzNzYNCjdkMmQxMmU2ZmRhNTgxOTZkZTM1 MjY1NjU0OGE0Y2Y0ZWQ4NjNkMDBjMWVmYzU3Yjg5MjVmNTRkYTQ3ZGQ0NTIzZmYxZWFmMWFmMWVk ODU5NmExZjEyOWUyYmM4NDRlOGNmNmU4NjE2OTlhMTUyM2M4OWQ4M2IxZTlmMmUwZmZlDQozZGVi NDAxYzZlYTdlM2JkMWI1MGI1OTJkY2M1MjI1YzBiMzc4N2Y3NzEyZjk1ZTZiM2M0YzFiMjFiMjc4 NDZjYjMxNmM5YzFjMmQ3ZDQ3MTkyNTAxMjM2OWVlM2QyYmU3NTlmYzJmYTZlOGQxY2JhOTY5OTZh MzdmZDg2ZjMxMg0KMzJmZWU4YTg3ODk0MTg4MzdjY2M0Nzk4N2U2ZTljZTQ1N2QxNDk4ZGEzMDcy M2Q2ODAxZDQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ5NDAxODc2N2I4NzhhZjUyZmVlOTQ0 ZTdkZjBiNWI4M2VlOGZhNTYxZGFiMTFlMjcNCmJkOGZmYmNhNGU3ZTgyM2ZmZTJhYjc2ODAwYTI4 YTI4MDBhMjhhMjgwMTJiZTdkZjhjYmExZGZlYTdlMzFjNTg4OTQ5OTIyODk1YjZlNTk0MWM0YWRi OGFhZTViYTI5MTlkYTQ2MzNkMmJlODNhZjIwZjE2ZGY0ZjZkZjE1MmQ2DQo1ODk2NDUwODA0NjY1 MGI5MDMzMDRiOGY1MzkxYjliOWM2N2QwMzUwMDcyN2YwZjZjMmZhMmYxZWRiNWNkY2NmNjcyYzYz N2M2NWVjOTg2ZDA0YzAzMzkwMzljZTFjNzNlYjVmNDNjNGMxYTE0NjVjNmQyYTA4Yzc0YWYxN2Yw NQ0KOTg1ZmUyMDNiYWRjMWI5OGZjYTU5MDVjOGM5MDU4YzExOTM5MjQ5ZTg3ZjFmN2FmNjViNDU2 NGIyODE1YzAwZWIxYTgzOGNlMzM4ZjdlNjgwMjUyMzIzMWViNTk3YjYzOGI1ZGI1NGRlNDMzNWE0 YTAyZjYyMTVlMzM5ZmMzNzcNCmViNWE4YzQyYTEyNzgwMDY3MzU5Y2FiMWM5YThkOTRkODI1YmVj YjJlMWJiNjBiNDQ3ZmEwZmM4ZDAwNjkwZTgzMjMwNjk2ODFkMjhhMDAyYmUyMGYxZGZmYzk0M2Yx MmZmMDBkODU2ZWJmZjAwNDZiNTdkYmY1ZjEwNzhlZmZlDQo0YTFmODk3ZmVjMmI3NWZmMDBhMzVh ODAzZTlmZjgyNWZmMDAyNDg3NDJmZjAwYjc4ZmZkMjg5MmJkMDJiY2ZmMDBlMDk3ZmM5MjFkMGJm ZWRlM2ZmNGEyNGFmNDBhMDAyOGEyOGEwMDI4YTI4YTAwMmFhNWY0ODIyODI0OTA5ZQ0KMTUxZDhm ZTBhNmFkZDUyYmYwYTYxOTU2NTFiYTMzMDQ5Yjk0NzUzYzc2ZmMzM2ZhNTAwMjVkMzA4ZTViNjVl ZGJjMDFmOTgxNTc2YThkZTJhYjVjZGI4NjNjMDZjOGZmMDBiZTkyYWY3NmEwMGE2Yjg3ZDQ5Yzgz Y2E4MDBmZTQNCjRmZmVjYzJiY2FmYzVlZDY5MzdjNDU4YWQ2ZThlMTE2ZTYyOWE0NzA3MDUxNDVi YzliNGU3YjFkZDgzZmYwMWY2YWY1NDg5MzZkZmNjNDdmMTY0ZmU4YjVlNDllMzhiNzlkN2UyMjI1 Y2RiMjI1YzRjZjc1MDQ3ZjY0NzAwODk0DQoyZGJjYWRiODAyYzAxMmEwYjc1Yzc1ZWFiZGMwMjNk NmFlMmUyNDgyZGZlZDBmNzM3NzY3MWU5YmE5MThlZTE5MzY5OTBiMmE2Mzc2Mzg2NWM5MDQzMDFj ZTQxYzcxOWFmNjk0M2I5NDFjZTcyMzM5YWYxMmQ3ZWUyZGVmNmNlYw0KZmNhOWFlMmUzNTI2ZDJm NTA1OWJjZmMyYmRiMTA5MWJmZGMzYzJlNTQ2M2U1NWMxZGM0OTI3YWQ3YjNkODM5OTM0ZmI2OTBm NTY4OTQ5YzdiODE0MDE2NjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjkyOTY4YTAwZTcyZGE3NTEN CmUzNTllMGZlMjc4NjU3MWY4NzkwM2ZhZDc0NzVjY2MwYTNmZTEzOTllNWZlMzRiNzk5NTQ3YWU3 ZWNlNGZmMDAyMWY5ZDc0YzM4MTQwMDUxNDUxNDAwNTE0NTE0MDA5NWUzNWUyMWQ2MWVjYmUyYTVj Nzk2YTRjODhlNTAzY2FhDQo3Y2E1MDZkNTM2ZTRmNGVhZjI3NWY1YWY2NWFmOWFiZTI5NWU2Yjk2 M2YxMjM1NTlmNDliOGNhMmJhNzlhOTEyMjk3OGZmMDBkMWUzMjRiMTJhNDAwNTQ4YzFlNDUwMDc0 YmUxMGI0OGVkM2UyNWRjNDY4ZmU3M2ZkOWMyZjllYQ0KYjg1NzVmMjU1OTg4MDNlNTIzODFjODFk ZWJkYTZjZGI3NWIyZmEyZWU1MWVlMDFjMGFmOWQzZTEwNWI2YWY2NWUzODlhM2Q0NmM2ZWUwMzJh NGVjMzc4MzgwYzUxNGUwOGZhMTVlN2FmMzVmNDVkYWJhYjQ0NzBkYjg4NjM5YzcNCjRlYjQwMGZi ODVjZGI0YTA3NTI4NDdlOTU0MmNkOTkyM2IwODE5MGVkNmI1NmNiN2ExMWIwNjNmMWM5ZmNhYWY0 ZmI4NWI0OThmYmZiMGUyYTk1YmI5NTg3NGRkZWUzNzNhZTA4ZjUzYjMyN2Y5MWEwMGQzYTI4MWQy OGEwMDJiDQplMjBmMWRmZjAwYzk0M2YxMmZmZDg1NmViZmY0NmI1N2RiZjVmMTA3OGVmZjAwZTRh MWY4OTdmZWMyYjc1ZmZhMzVhODAzZTlmZjAwODI1ZmYyNDg3NDJmZmI3OGZmMDBkMjg5MmJkMDJi Y2ZmZTA5N2ZjOTIxZDBiZmVkZTNmZg0KMDA0YTI0YWY0MGEwMDI4YTI4YTAwMjhhMjhhMDAyYTk1 ZjFjMjQ4NTQwMmMyMDkzMWVkZDJhZTU1MGJlNzFmYmQ0NjUyNDc5NDdmZjAwMWUzOGEwMDkyZTU1 NWU3ODM3ZTA2MGU0N2Q3MmI1NmVhYTVjYTA3NzgzMWQ5ODdmMzUNCmFiNjc4MDY4MDI5NWE5NjM3 NTc0NThmMDFiMDNkNmJjNTdlMjQ3ODg2NGYwZGZjNDUxYTgzYjM3OTMwNGIwMzg1MTE4NjUwYzYy NzUyN2VmNzVjMTRlYjhlZmQ2YmRiMmNmZTc5Mjc5M2ZkYjJiZjkxYWYxNGY4OTVhNWNmYTlmDQo4 ZjY3MzE1Y2RhMmFjMmQ2ZTRmZGFkNTlhMzhjYjQ1MjYzMmJkMWY3ZWRjN2I2YzNlYjQwMTU3YzQz YTllOTlhOWM1YTdjZGE2NWZjOTc3MzBkMzJmNTY1OWU2N2YyYzgwNjM1YzIwOGQ3YjY0OTFiNzE4 M2VhNmJkY2I0NTkxYQ0KNmQwZjRmOTViZWYzZGI0NmM3ZWE1NDdkNmJlNjFmZjg1NjkyYzFhYjVh ZGM2YWQ3NmY3MTY1NzAyZTE5NjRiNjQyMTljYzQwZmRkY2YyMTc4MTkzZDdkMDExY2Q3ZDMzZTFh YzdmYzIyZmE0ZTNhN2Q4YTFjNzE4ZmUwMWRhODANCjM1MjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAw MjhhMjkyODAzOWViNjQ1M2UzM2I4NzNkNTYyN2ZkN2M5ZmYwMTVkMTc2YWU2YWRmN2ZmYzI2Zjcw NDYzNjc5MzI2N2YyODZiYTVhMDAyOGEyOGEwMDI4YTI4YTAwNGFmMjBkNzI0DQpiNzhiZTI1ZGY3 ZGEwM2RkMTJkMzE4ZWQyMTNiOWMzZmQ5MmRjMDIwMGU1NDEwNDgyN2I4MTVlYmY1ZTRkYWM0NTY5 ZmYwYjE3NTA5YWZhNjhhY2EzNDc5NGE1Y2JhNzA1YmM4YjQwMTQ5M2Q0ZmNjNzAxNzA3YWYzNDAx NWJjMQ0KOTE0ZDBmOGY2NGI1Yjk1ZjJlNDU2OTMxNmEwZTU1NDFiNzg3MTgzZWI4MTgyN2U5NWVh ZjYyNGY5MjQ5MjA4NjZjYWUzZDMxNWU0ZGUwNWI4YmI5N2M3ODkxZGNjMmQxMmUwYmM2YjI4M2U2 YjZlYjY4YmU2ZjliMjQyOWRiYzANCjI3M2ViNWVhZjYzOTUxMjQ3YjAyODQ2YzAyM2E3NDE0MDEz ZGM5MjJkMjUzZGM0NjdmOTU2N2RiNmQ2YjVkMWU0NzAzNzZkNWU0ZmYwMGQ3MjM1YTUzZjE2ZjI5 YzY0NmQzYzU2NTQ5MmMwOTZmYTMyYmJmOTY2NDkxNTYyMDRlDQowOTZmMmQ4ZWRmYzgxZmNhODAz NmE4YTI4YTAwMmJlMjBmMWRmZjAwYzk0M2YxMmZmZDg1NmViZmY0NmI1N2RiZjVmMTA3OGVmZjAw ZTRhMWY4OTdmZWMyYjc1ZmZhMzVhODAzZTlmZjAwODI1ZmYyNDg3NDJmZmI3OGZmMDBkMg0KODky YmQwMmJjZmZlMDk3ZmM5MjFkMGJmZWRlM2ZmMDA0YTI0YWY0MGEwMDI4YTI4YTAwMjhhMjhhMDA0 YWNiYmY5NGE1YzNlZDA0ZjEwZTcyNzhlNjVjNTZhNTY1ZWEyYmJiY2RlMDFmOWExZWJmZjAwNWQw NTAwNWJiYTUzODgNCjg4ZTA4NzVjZmYwMGRmNDJhYzY3OGNmNmFhNzdlY2MyMjVkYmQ3OGU5ZmVm MmQ1YjI3MDA4Yzc2ZTgyODAyYjU4MGRhOTMxZWM2NDYzZjk5YWYyM2YxYzJkY2MzZjEwNTZmNmQ3 NmNjZmYwMDZlYjQ4NGQ5YzhhNTg0OWZiYTkwDQo4NjE4ZTg0MDJkZmE1N2FkNTg3MzYxMTkzOTUy YzgzOTI0ZjVjNzI2YmU3M2YxN2Y4ZjFlNWY4YWJmNjhkMDk0ZWExMGM3MjQ1YjYyMjQ4MDY3NTA0 NjU3MDNhODA0OGEwMGVjMzUxOTE3YzQ1N2ZhMjQ3MmRjYmNiMzRlZDdhYg0KM2M0ZDFhYTI1Yjg2 NWM5NjUwN2E5ZGI5YzFjOTIwZTMzYjRmMTVlYWRlMWEyNGY4NWY0OTI3OTI2Y2UxZWY5ZmUwMTVm MzhlYTdlM2M5MjI5ZjRmZDQ2ZWZjM2ZhYWQ4ZGY1YjQ5MjA2YmQxMzYzN2U1NzFiMDI5NDBhMzlj NjQNCjcyNDczY2Q3YjFmYzI4ZjE4N2ZjMjU3ZTE1NTNmNjU0YjZmYjA4NGI0ZDgyNjBlNGVkNDFm MzcwMDYzMzQwMWRmZDE0MGU5NDUwMDE0NTE0NTAwMTQ1MTQ1MDAyNTc5N2ZjNDhmOGI1MmY4MDM1 Y2I2ZDM5NzQ3NWJlMTNjMDI3DQpkYzY3MzFlMzJjYzMxZDBmZjc2YmQ0MmJjOGJlMmFmYzJjZDU3 Yzc1ZTIwYjRkNDJjNmY2Y2FkZTM4NmQ3YzgyMmUxOTgxMjQzMzFlMzBiZmVkNTAwNzEzMWZlZDA3 M2M3YWNjOWE4MGYwZTQ1ZjNhYjJlY2ZiNTEyNzkwOWRmNg0KZmYwMGIwM2YzYWY1OGY4NmJmMTA2 NWY4ODFhNzVmNWQ5ZDM4NTg4YjU5NDQ2MTdjZmYwMDMzNzY1NzNmZGQxZmNlYmM4ZmZlMTljN2M0 YmRiNThkMmJmMzkzZmYwMDg4YWY1M2Y4NTFlMDNkNDNjMDNhNWVhMTY5YTg1ZDViZGMNCjNkYzRl YjIyOWI2MmM0MDAxNzFjZTQwYTAwZjQ1YTI5MDc0MTRiNDAwNTE0NTE0MDA4N2E1Nzg0Zjg4ZmM0 MWEwNTg3YzQ4ZDQyN2JhZDQyNDhlZTYyOWU0NDExMTEyMWQ4N2NhODE0MTUwYTBlMDkyMjRjOTIz OWMwZTBmNWFmDQo3NmFmMDNmMTZmODU2YzNjNDVlMmZkNWE1YmE4NWRjNDEyZGNjOWJhZGJlNzdj MmFkYjhjYmE4YzMxNTA1OTg3MDc4YTAwOWJlMTk2YmFkYWY3OGZlNGJhOTYwNzRjZWY1MGQyNzBj ZWJlNTIwNTI0MDAwNjcwYjljZTNmODhmYQ0KZDdiNWRhNjE0Y2M5YjcwNzc5NjNmOGQ3OGVmODBi NGJiMmQzYmUyNGI0NzZiM2M4ZWQwYTMyNmRmYjRmOWMzNjg4MjNjNjBmNWM3MjcwM2I2MDU3YjA1 YjJiN2RiNmUwOTI3NjEwYTAwMjdkMGI1MDA1YTk4ZWQ4NWNmYTI5YWUNCjQzYzQ5YTIwZDZhNGYw ZGRkMWJkYmFiNjViMGI5NWJhNTViNjE5ZjMxYjAwMDUzZjgxNjFmODlmNWFlYmU1MDFhMjcwZGMw MmE3MjZiMWVlZTYxNmUzNGJmMmY5NjJkYjEwZmEwMDg3YWZlNTQwMWI5NDUyMGM2ZDE4ZTA1MmQw DQowMTVmMTA3OGVmZmU0YTFmODk3ZmVjMmI3NWZmMDBhMzVhYmVkZmFmODgzYzc3ZmYwMDI1MGZj NGJmZjYxNWJhZmYwMGQxYWQ0MDFmNGZmYzEyZmYwMDkyNDNhMTdmZGJjN2ZlOTQ0OTVlODE1ZTdm ZjA0YmZlNDkwZTg1ZmYwMA0KNmYxZmZhNTEyNTdhMDUwMDE0NTE0NTAwMTQ1MTQ1MDAyNTYzNWVj Y2NiMmRkZWM1MTIxNDc4MDZjYzdhYjc1ZmU3Zjk1NmQ1NjViYzRjOTdkNzMyYTFjMzQ4ZjBhOWM5 ZTMwMjgwMjZiZTYyODAxMDM3MTBiZDNkN2U2NWFiMzINCmNhMjI4ZTQ5MGZmMGE5NmZjYWFhNmEw ZmU1ZWM3MDNmODRmZjAwZTg0YjU2MmU0MDM2ZDMwMjA2M2NiNjE4ZmMyODAyMzgzMzE1OTJmM2I4 YTgzYzFmYWQ3Yzc5YTg2OTkwNDllMjZiNjg2NmIzMGFiMmM4ZjczMzc5NzIxY2JjDQoxOTJjZDhm NDYwYWFjMzFlZDVmNjEzNjIyYjU1MmU3MmI5YzkwN2YxMzVmMjk0NTcxNmQ2M2UyZGQxZjUzZDQz MGZhN2M1MmM5NmQzODU1MmM0MGNiMWM5MThlNzg5NDBmYzI4MDI0ZDYzYzMxYTJlOTM3NWE2NDcz MmNhMmRhZQ0KNjYxMjliOTkxYzg0NzgzMjM3N2M4NzA0MGU0N2NjMGZhZTM4YWY1ZmY4MmQwMmRi NDVhZTQwMWY3OGNkYTRhY2Q5ZWVmNmNhNDhmYzBmMTVlMmZlMjRkNmUwZDRmNGE1OTQ0ZjE3ZGFl MGYyYWM4NDIwN2NlZTExMTgzNDg3M2QNCjE0ZmNiYzdkM2QyYmQ3M2UwMmNjNmViNDhkNWFlNTky NDQ2OTVhMjA0MzhlYTAyYjI4MjNkYjZhYThmYTgzNDAxZWM2M2EwY2Y1YTI4YTI4MDBhMjhhMjgw MGEyOGEyODAwYTMwMDc2YTI4YTAwMzE0NTE0NTAwMTQ1MTQ1MDAxDQo0NTE0NTAwMjU3OGNiM2Rj Y2JlMmRkNTEyZDgzYTQ4OWZkYTZhZWMzMDU4YWY5YjBiN2M4MGYxOWM3N2NlNzk2ZTM4MTVlY2Q1 ZTMzMzRmNmIwZjhjNmVlMTExNWJkYzk5YzZhNGIyNDUyNDgxNTYyOThkYzQ2MTU5Y2UzMmJmMg0K YWFmYjljMGMwM2Q2ODAyYzc4NTBjNWZmMDAwYjRlZWEzYjVmMzdjOTI1Y2U2NmZmMDA1ODFmYzk0 ZGM1YmQ3MjVhYmQ0YTM3MWZkYTA2MzU1ZTM2OTM5ZmMxNzAzZjUzZjlkNzk0ZjgzZWRhNmIzZjg5 NzJhZGNjZTY3OWNhNmYNCjMyMGNlZDA4ZDZmMTlkYTMyNDllMzAwNzI0OWFmNWEwMDI1ZDllNzk3 MTQwMGViOTIwNWJjYTQ5ZTAyMzdmMmFjZWJhNTQ1YjdiM2Y5MDdjYmY3NThmNDVjMjkyNzhmYTAz NTdlZjUzY2NiMzlkMDFlNWEzMjA3ZDcwNmIzZjU1DQo3MTE0MzY2MDAwZGYzYjBkYTdhMTFlNTM1 MDA2YzJmZGQxY2U3OGViNGI0ODg3MjhhNDczOTE0YjQwMDU3YzQxZTNiZmY5Mjg3ZTI1ZmYwMGIw YWRkN2ZlOGQ2YWZiN2ViZTIwZjFkZmZjOTQzZjEyZmYwMGQ4NTZlYmZmMDA0Ng0KYjUwMDdkM2Zm MDRiZmU0OTBlODVmZjAwNmYxZmZhNTEyNTdhMDU3OWZmMDBjMTJmZjkyNDNhMTdmZGJjN2ZlOTQ0 OTVlODE0MDA1MTQ1MTQwMDUxNDUxNDAwODRlMDY2YmNmNzUxZjFiYzMxN2M0YmI3ZjA4YWU5Yjcy ZjNjYWYNCjFjYzZlNTVjMmEyOGRiOWU4NzkyMDczOWY3YWY0MjNkMmIyM2ZiMjJkY2Y4YWM2YWY4 N2ZiNDI1YTdkOWM2MDcxODY2YzkzZjVmOTQwZmM2ODAyZDVlMDBlY2FhYzc4ZDg0ZmUzYjk2YTdi YmUyZDI1ZmE1NDE3OTg1NzVjZjIwDQoyMzdmMzVhOTZmODgxNjcyNjRlMzM4MWZhZDAwNjNlYWI3 ZGU1NGQ2ZDZlY2QxYWM2ZDAzNGFlZWVkOGM2ZDI5OWU3YjcxYmJlYjVmMThlYWQzYTVjZWE1NzBk MTI4MGE2NTczYzMxMjE4OTNjYjdlMzVmNDdmYzYzYjUzM2I0MA0KOTFlYTc3YjY4NWExYzQ5MTQy NDA0Nzg4MTNiOThmMTk2YzY1NTcxZDA5NzVhZTIzZTFmNzg1NmQ1YWYzNGExNzBhZDE3ZGFhMmI4 MzNhNGI2YjFjOWIzNjg4Y2FmZGY0MzllMWE4MDNjNzFhMzI4YmI4OTA0MGY0NjFkZWJlODcNCmY4 MDVhZTA5ZjRiYmNiMWJkYmM4YmNmNTY4ZTBiNTg5ZDk0M2IyOGRlYzQyOGVhZDgyZWQ5Y2ZhOGE5 ZjVkZjAyZGFkYWViZGE2ZTljOTM2OWE5NmY3MGVkMzg5YTRkMmEwZGM4OTFhOTI3MjU1NTcyYTU4 YThlYmQyYmJiZjg3DQo1YTVhNTk3ODQyY2U1NzU4ZGE3YjlkZjcyZjIyYzQxMzNiOGYxYzBlOWYy ODAzMWU4MDBlZDQwMWQ4MGZiYTMzZTk0YjQ4M2EwYzUyZDAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0 NTAwMTQ1MTQ5NDAwYjQ1MTQ1MDAxNDUxNDUwMA0KMzRmZDMzNWYzOTZiM2UzZTFlMTlmMWQ1ZmE0 OTYzMjM0YzI1YmM4ODg5ZGZmNzEyMDk2NTVjNjQxMDRlZDFiMWIyNDc3ZmExY2ZkMWM0NTc4YTVk NThkODZhMWUyY2JhNmQ0NmNhNmI5NGI3OGY1MTkxNzYyZjk4NTMxNzJiODYNCmYyYzhlOTk2M2M4 MGRmODYyODAzMWZlMTE1YzVmNWQ3OGU0NGZhODE4ZmNmNjg5Y2FhYzIzMmExM2NiOGYwMDExOTU1 ZTMwMzZmMDQ2N2RhYmRkY2EzMWJmODlmY2MxODI5ZDJiYzkzYzFmMDY5MTY5ZjEzYTY4NmM0NTkw OTIzDQo5NjU1NDdiNjgxNjM0MjBjMzE2MDAwYTAwMDdlZjkzOGZjYWJkNmU2NjYxNzU2YzQyZTcz OTA0OTFjOGEwMDllZTAxNmI3OTAyOWMzMTUyNDFmYzJiM2I1NjUwNTZjZTM3ODRjOWU2NDhjOWI4 MWU1MDk0NjE5YWJkNzliODU5Yw0KZTUzOTYxMWI2ZGZhZTBkNTVkNGRjYWFkOTkwMDczNzI4MGZl NDY4MDJmNWI2M2VjYjE2MDYwNmMxODFmODU0YjUwNWEwMGI2NzAyYWY0MTFhODFmOTU0ZjQwMDU3 YzQxZTNiZmY5Mjg3ZTI1ZmYwMGIwYWRkN2ZlOGQ2YWZiN2ENCmJlMjFmMWRmZmM5NDJmMTJmZjAw ZDg1NmViZmYwMDQ2YjUwMDdkM2ZmMDRiZmU0OTBlODVmZjAwNmYxZmZhNTEyNTdhMDU3OWZmMDBj MTJmZjkyNDNhMTdmZGJjN2ZlOTQ0OTVlODE0MDA1MTQ1MTQwMDUxNDUxNDAwODZiOTExDQphZDRh ZmYwMDE0OGU4YWIyYjg4MjJkMjFhZTVhMjE4ZGFjZGU3MjhjZTdlODZiYWVhZjFmZjE0ZWIyOWEy ZmM2MmIyZDYzY2U5OWUyODk1MzRjYjg4ZDFiODQ1OTE0YjgzZjgxYzEzZjg1MDA3YTk1ZjJlZjBh MDFlNGM2YzcyMw0KZWFiNGJhOTRhYjE1OGJjOGRiNzAwOGZiZmQwNzM4YzlmNjFkN2YwYWM1YmVm MTFkYmIyZmVlNTI0N2ZkY2M5ZjMyOTFmMmZkZGVmNWNmNzhmYmM1NzY4YmE0YTY5YzIyOTI1NmJh ZTY1NDEyMDUyNjEwNzBjYTA4ZWVmOWQ4M2YNCmRlY2Y2YTAwYzgzMjI3OGFmYzYxMmRmNWQ0MTNj OTY0MTU0MjJmOTY3MGQxN2ZjYjI1ZmE5Yzk5OGZmYmQxOGFjY2YwMmU5NjI1ZjEzNjhhZDI0YTk4 NWQzNjQ3MDkyYzc5MDEzNjQwMzM4MmRkNzM5MTllYTcxNWIxNmJhZDY5DQo5ZTE4ZDM5NWI1Mzll MDg2ZTI0NzY5NmU3N2M5ODJjNGUwNjEzMGJmNzQ2MzY4ZjQwMDBhZjNjYjFmODkzYTNlOTJkYTRi ZGIyNWNjOGY2YjY1MzQ1MjEwN2VmYmIxNTcwMDY1N2EwMjA4MWZlMTQwMWU4ZGE4ZTlhOTc3YThl Yg0KZWY2NGM1MjJmYjM0NWE3NWIzOTk1ODJjNzI0Y2RjZTA2N2EwMjUwOGY0MTVlYTM2OTZmMTVi NWE0MzZmMGE4NTg2MjQ1NDQ1ZWI4NTAzMDA1N2NmNWE1N2M2NWQwNjA4YTM0YjlkM2I1MjU2ZmI3 YjVmY2U1NWQxY2M4NDI5MDgNCjMyNDhlOTg0ZmYwMGJlNmJkZTc0NGQ2MmQzNWVkMWVkZjUzYjE3 NjZiNzlkMDNhZWVjNmUxZWEwZTNiZDAwNjlkMTQ3NDE0NTAwMTQ1MTQ1MDAxNDUyNTM3MjczZmQz YmQwMDA1YmFmNWZjM2I1NjU1Zjc4YTc0MGQyZTQwOTdmDQphZTY5ZDZjZTQ5YzI0Yjc0ODhjN2I3 NDI2YmNmM2UzYzZiZmE4ZTg5ZTFhYjAxNjE3ZDczNmJmNmJiODY4ZTUxMDM4NDJjYTE3YTZlYzY0 N2UxNWYzMmJjYjFiY2E2NTczMmJiMzEyY2NjY2UwOTI3MzljOWM4ZTY4MDNlZjI4ZQ0KNTQ5NjI0 OTExZDVkMTgwNjU2NTM5MDQxZWUwZmE1NzljZjhjYmUzMWU5M2UwYmYxMDNlOGY3OWE2ZGY0ZjMy YzZiMjZlODRhNjMwN2E3NTM1ZTM3MTdjNzNmMTVkYmU5ZjE1OWMyZDZmMTQ3MGM2YjFhM2FjNDBi MDAwNjA2NzMNCmMxM2M1NzEzYWY3ODhhZjdjNTFhOWI2YTFhYjRmMjVjNWRiMjg0ZjMzMGFiOTUx ZDA2MTU2ODAzZTlhZjBlZmM2YmYwYTZiZjNjNzZkMjRkM2U5ZjczMmI4NDQ4ZWU1M2VmMTI3MDAw MjMyMmJkMjM5YWY4M2UwYjg1YjViODQ5DQphMTEzYzcyNDRlMTkxODMwZjk1ODFjOGUzNmY2MzVk MGM5ZjEyN2M1OTIzOTY2ZjEyZWIzOTI3Mzg0YmMyYTNmMjAyODAzZWNmYTJiZTUyZDA3ZTM4Zjhh ZjQ5NjhlM2I5YmE2ZDQ2ZGQ0ODA1NmU3Njk2YzdmYmMxNzI3ZWE2Yg0KZDE3ZTI3NzhmZjAwNWVk MmZjMzNlMTZkNWY0N2JkMzYxZmRhNTA5OTY2NDU1NDZlYWE4NDBmZGUyOWU5YjhmM2RmMTQwMWVi ZjdkNzkwZTlmNjUzZGU1Y2M4MjM4MjA4ZGE0OTFjZjQ1MDM5MzlmY2FiYzExZmM1M2E2NWNlYjEN CjczMmM3YWM1OGRiZGFmOTE3NGE2NDM3MGFiMjVjODZiODY3ZGEzOWNhODIwZmYwMDE3NWFlMGVl YmUyZTc4YmY1MGIxYjliM2JkZDU2NGI5YjZiOTg1ZTE5NjM2ODIyMDMwYzMxZDU1MDFmNWFjNWQx NjJiMzY5NjRjNWNjMzZhDQpkMjJlMjNmM2UzOGU0MDRlN2IxNzFmMmZhNjdiZDAwN2IxNzgyNzVh ZDIyZjNlMmI3ZDhmNGE5MzM2YWFmMmRjYzZjNzNmN2JjODQ4ZjkyNGYyNGUxOGZlMWVmNWVlMzJj OGIxYmM3Yzc1ZTA2NmJlMzc4MmU2Y2VkM2M1ZjFkZA0KY2Q3Njc3YzE3NTFlZDZiNjU0OGQxOTQz MGNmZGQwMDc0ZmNlYmRkMzU4ZjhlM2UxYmI3ZDRiNGM4MmQ0N2RiMjA5OWM3ZGEyZTA0OWIzZWNj MzcwZTQ4ZGJmMzcwNGY0ZjRhMDBmNTZiOGY5MjA3MjA2N2RhYjJiNWFiY2I3YjINCmQzMjBiZWJk NzExYzExNDhhZjJjYWRkMjMwM2JkNzFiN2JmMWMzYzE5MTQ0ZTEyZjVlNjNlODkxMzU3MmJlMzdm OGM3ZTE5ZDZmYzEzN2JhNWQ4NDk3NDJlNmUyM2Q4NDE4YjY4MjNiOGM5YTAwZjRiZDNiYzdiZTEx M2E3ZGJlDQo3YzUzYTQwNmQ4MzNiZWY2MzUzZDNkMGI2NDdkMmJhNGI2YmE4MmY2ZGEzYjliNTll MzllMDk1Nzc0NzI0NmMxOTVjMWU4NDExYzExNWYwODY2ZDgzMGY5NjVlMGZmMDA3YzdmODU3YmVm ODU3ZTM5Zjg2MzQwZjBiZTk3YTVjYg0KYTdlYTkyNGQ2ZDZlYjEzOThlMzhjODJkZDNhOTcxNDAx ZDc3ODliZTM1Zjg3N2MzMWFkNWQ2OTczZGJkZjVjNWRkYjM2YzkxNjI0NWRhMGUzM2Q0OWFmOTdm YzQ3YThjN2FjNzhhMzU2ZDRlMTQ3NDhhZjJmNjZiODQ1N2ZiY2ENCmFlZTU4MDNlZmNkNmFmOGQz NWNkM2ZjNDllMmVkNGI1OWI1ODZlNjM4MmVlNDBlMTY1MmExODdjYTA3NmNmYTU3MzBkOGRjNzE5 YzY3OGNkMDA3ZDdkZjA0YmZlNDkwZTg1ZmYwMDZmMWZmYTUxMjU3YTA1NzlmZjAwYzEyZmY5DQoy NDNhMTdmZGJjN2ZlOTQ0OTVlODE0MDA1MTQ1MTQwMDUxNDUxNDAxYzVmYzQyZjg4MTY3ZTAzZDM2 MGI4OWUxNmI5OWVlMjQyOTE1YmFjOWIxOTgwZWFjMzIwOGMwMjQ3ZTc1ZjI5NmJiZTI1YmNmMTBl YTk3NzdiN2IzY2VlNg0KZTY2ZjM1ZDM3MDUxYzJlZDE5MDM4MjcxYzY3ZDJiZDViZjY5M2I4NjNh YzY4NTZmOGMwNDgyNTcwN2Q3NzMyZmZmMDAxMzVlMTg3YTljNzRhMDBmNGRmODQzNzFlNjZiN2E5 YzBmM2RjODhjNjk5MzM4MWJjNmQ0Mzk1ZjljZmENCjAxZGNmNWFmNGJkMmI0ZTFlMjZmMTJjNTdi M2VmNjgwNGIxY2NhMDBmOTU1NGU3Yzk0ZTdhZmNiOTk0ZmE3OWE4M2I1NzhjN2MzZDk2NjRkNGY1 MzUxYmJjODkzNGU5MTZlMzYzNjFjYTE3OGZlNTVmNzc2ZDg5ZWRiYzllZDVmDQo0NjY5ZDczYTdl ODlhN2Q4YzU3OWE4ZGE3ZGI5NjQ5NjRiYzc2OWQ1NGZkYTU5MDg2MDQ2N2E2NzAwN2I2MjgwM2Nk M2UzYWY4N2FjZWM2YzM0N2Q0ZmNkOTllNzllNDc4YzgyYzM2ZWMyNTlmMjA3YWYyMmJjNGIzMDll NzEyNw0KM2ZlZDBhZjdhZmRhMDM1NGQzNmY3YzNkYTJjMzYzN2Y2YjcwZDFjZWRiOTYyOTk1Y2E4 ZGJjNjcxNWUwMGM0OTYyNzNkZTgwMjZjYzQwNjNmNzk4ZmYwMDc4NTdkODlmMGFhZDIxYjRmODY5 YTI3OTViOTg0YjA3OWFjNThlNGUNCmU3MzkzZmE5YWY4ZDJiZWQyZjg2NWZmMjRkM2MzYmZmMDA1 ZTUxZmYwMDJhMDBlYjY4YTI4YTAwMjhhMjhhMDA0YWY5OTNlMzg2YjVhOGU5ZmYwMDExNjU4MmQ3 NTJiZWI3OGJlY2IxOWQ5MGRjMTQ1YzljZTc4MTVmNGU1N2NhDQo1ZjFmOGZmYzVjZjkzZmViY2Uy ZmViNDAxZTdkNzVhYTVkNWY0NjEyZWVmNmY2ZTEwMWM4NTk2NzJjMDFmNWMxYWFiOTg3OWUyNGU3 ZmRhMTUwNjY4YTAwOWJmNzNlOGZmZjAwN2QwYTNmNzNlOTI3ZmRmNDJhMWEyODAyNmZkYw0KN2Ez ZmZkZjQyOGZkY2ZhM2ZmMDBkZjQyYTFhMjgwMjZmZGNmYTQ5ZmY3ZDBhOWU0YmM3OTYzMTFjYjNk Y2JhMjhjMDU2OTMyMDBhYTU0NTAwNGM0YzQ0ZTcxMjY3ZDczNGEwYzU4ZmYwMDk2OWNmZjAwYjQy YTBhMjgwMjcwNjENCjFkMDQ4M2ZlMDQyOGNjM2U5MjdmZGY0MmEwYTI4MDI2ZmRjZmEzZmYwMGRm NDI5NzMwZmYwMGQzNGZmYmU4NTQxNDUwMDRkZmI5ZjQ3ZmZiZTg1MmU2MWZmYTY5ZmYwMDdkMGE4 MjhhMDA5YmY3M2U5MjdmZGY0MmEyMzhkYzcxDQpkMzNjNTI1MTQwMWY1ZmZjMTJmZjAwOTI0M2Ex N2ZkYmM3ZmU5NDQ5NWU4MTVmMGM1OGY4YjNjNDlhNjU5Yzc2NzYxZTIwZDU2ZDJkNjNjZWM4NjBi ZDkyMzQ1YzkyNGUxNDFjMGM5MjRmZTM1NjNmZTEzYmYxODdmZDBkN2FlNw0KZmUwYzY2ZmYwMGUy YTgwM2VkZmEyYmUyMGZmODRlZmM2MWZmMDA0MzVlYjlmZjAwODMxOWJmZjhhYTNmZTEzYmYxODdm ZDBkN2FlN2ZlMGM2NmZmMDBlMmE4MDNlZGZhNGFmODg3ZmUxM2JmMTg3ZmQwZDdhZTdmZTBjNjZm ZmUNCjJhOGZmODRlZmM1ZmZmMDA0MzVlYjlmZjAwODMxOWJmZjhhYTAwZjUwZmRhNDM5ZjExNjhi OGU3MTZhZjljN2ZiZjVlMjNiN2U5ZjlkNmFkY2Y4YWJjNDU3OGMxYWViNWZkNTI3NjAzMDBjYjc5 MjMxMDNkMzkzNTA3ZjZmNmIxDQpmZjAwNDE2YmVmZmMwODdmZjFhMDA2NjliYTk1ZGU5MzdiMTVl NThjY2QwY2YxOWM4NzFjZTNmMGE1ZDRiNTNiY2Q1ZWZlN2JlYmU5Y2NiNzMzYjZmOTFjZTA2ZTNl YmY1YTc3ZjZlZWIxZmYwMDQxNWJlZmZjMDg3ZmYxYTNmYg0KNzc1OGM2M2ZiNTZmYmZmMDIxZmYw MGM2ODAyOTczOWUwZmViNDk4ZmE3ZTc1N2JmYjdiNThmZmEwYjVmN2ZlMDQzZmYwMDhkMWZkYmRh YzdmZDA1YWZiZmYwMjVmZjAwYzY4MDI4NjM5ZWRmOWQ3ZGExZjBjYmZlNDlhZjg3ODYNCjRmZmM3 OTI3NTFlZDVmMWY3ZjZmNmIxZmY0MTZiZmZmMDBjMDk3ZmYwMDFhYmIxNzhkYmM1NzBjNmIxYzVl MjdkNmEzOGQ0NjE1NTJmZTUwMDBmNjFiYTgwM2VlMjFkMjhhZjg4M2ZlMTNiZjE4N2ZkMGQ3YWU3 ZmUwYzY2ZmZlDQoyYThmZjg0ZWZjNjFmZjAwNDM1ZWI5ZmYwMDgzMTliZmY4YWEwMGZiN2U4YWY4 ODNmZTEzYmYxODdmZDBkN2FlN2ZlMGM2NmZmZTJhOGZmODRlZmM2MWZmMDA0MzVlYjlmZjAwODMx OWJmZjhhYTAwZmI3YWJlNTNmOGZhMzc3Yw0KNGQ5NGY0ZmYwMDQ0OGI5ZWEzYmQ3MWJmZjA5ZGY4 YmZmZTg2YmQ3M2ZmMDAwNjMzN2ZmMTU1NTJlM2M0ZGFmZGRjYTY1YjlkNzM1MjlhNDIwMGRmMjVk YzhjNzFlOTkyNjgwMzMwOGU3YjdlNzQ2M2U5ZjlkNWVmZWRlZDYzZmUNCjgyZDdkZmY4MTBmZjAw ZTM0N2Y2ZjZiMWZmMDA0MTZiZWZmYzA5N2ZmMWEwMGEzOGZhN2U3NDYzZTlmOWQ1ZWZlZGVkNjNm ZTgyZDdkZmY4MTJmZjAwZTM0N2Y2ZjZiMWZmMDA0MTZiZWZmYzA5N2ZmMWEwMGEzOGZhN2U3NDYz DQplOWY5ZDVlZmVkZWQ2M2ZlODJkN2RmZjgxMmZmMDBlMzQ3ZjZmNmIxZmYwMDQxNmJlZmZjMDk3 ZmYxYTAwYTM4ZmE3ZTc0NjNlOWY5ZDVlZmVkZWQ2M2ZlODJkN2RmZjgxMmZmMDBlMzQ3ZjZmNmIx ZmYwMDQxNmJlZmZjMDk3Zg0KZjFhMDBhMzhmYTdlNzQ2M2U5ZjlkNWVmZWRlZDYzZmU4MmQ3ZGZm ODEyZmYwMGUzNDdmNmY2YjFmZjAwNDE2YmVmZmMwOTdmZjFhMDBhMzhmYTdlNzQ2M2U5ZjlkNWVm ZWRlZDYzZmU4MmQ3ZGZmODEyZmYwMGUzNDdmNmY2YjENCmZmMDA0MTZiZWZmYzA5N2ZmMWEwMGEz OGZhN2U3NDYzZTlmOWQ1ZWZlZGVkNjNmZTgyZDdkZmY4MTJmZjAwZTM0N2Y2ZjZiMWZmMDA0MTZi ZWZmYzA5N2ZmMWEwMGEzOGZhN2U3NDYzZTlmOWQ1ZWZlZGVkNjNmZTgyZDdkZmY4MTJmZjAwZTM0 N2Y2ZjZiMWZmMDA0MTZiZWZmYzA5N2ZmMWEwMGEzOGZhN2U3NGRhZDBmZWRlZDYzZmU4MmQ3ZGZm MDA4MTJmZmUzNTQ2NDkxZTU5MWE0OTFkOWRkYzk2NjY2MzkyYzRmNTI0ZDAwN2ZmZDl9DQp9fXtc c3B7XHNuIHBpY3R1cmVUcmFuc3BhcmVudH17XHN2IDE2Nzc3MjE1fX17XHNwe1xzbiBmUHJlZmVy UmVsYXRpdmVSZXNpemV9e1xzdiAxfX17XHNwe1xzbiBwb3NyZWxofXtcc3YgMX19e1xzcHtcc24g cG9zcmVsdn17XHN2IDF9fXtcc3B7XHNuIGZMYXlvdXRJbkNlbGx9e1xzdiAxfX17XHNwe1xzbiBm QmVoaW5kRG9jdW1lbnR9e1xzdiAxfX17XHNwe1xzbiBmTGF5b3V0SW5DZWxsfXtcc3YgMX19fXtc c2hwcnNsdFxwYXJccGFyZA0KXHFsIFxsaTBccmkwXHdpZGN0bHBhclxwdnBnXHBocGdccG9zeDIx ODBccG9zeTYzXGR4ZnJ0ZXh0MTgwXGRmcm10eHR4MTgwXGRmcm10eHR5MFxhc3BhbHBoYVxhc3Bu dW1cZmFhdXRvXGFkanVzdHJpZ2h0XHJpbjBcbGluMFxpdGFwMCB7XHBpY3RccGljc2NhbGV4NjJc cGljc2NhbGV5NDRccGljY3JvcGwwXHBpY2Nyb3ByMFxwaWNjcm9wdDBccGljY3JvcGIwDQpccGlj dzc5MTFccGljaDc5MTFccGljd2dvYWw0NDg1XHBpY2hnb2FsNDQ4NVx3bWV0YWZpbGU4XGJsaXB0 YWctMjA1NjA5NzQ3NFxibGlwdXBpLTk2e1wqXGJsaXB1aWQgODU3MjcxM2UxOWU3M2FjM2Q0NzYw M2I0MGE2MTc1ZDB9DQowMTAwMDkwMDAwMDM3OGIxMDAwMDAwMDA1M2IxMDAwMDAwMDAwNDAwMDAw MDAzMDEwODAwMDUwMDAwMDAwYjAyMDAwMDAwMDAwNTAwMDAwMDBjMDIyYzAxMmMwMTAzMDAwMDAw MWUwMDA0MDAwMDAwMDcwMTA0MDA1M2IxMDAwMA0KNDEwYjIwMDBjYzAwMmIwMTJiMDEwMDAwMDAw MDJiMDEyYjAxMDAwMDAwMDAyODAwMDAwMDJiMDEwMDAwMmIwMTAwMDAwMTAwMDgwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDBmZmZmZmYw MDAzMDMwMzAwMDQwNDA0MDAwNjA2MDYwMDAxMDEwMTAwMDgwODA4MDAwZDBkMGQwMDBlMGUwZTAw MDUwNTA1MDAxNjE2MTYwMDBiMGIwYjAwMTIxMjEyMDBmYmZiZmIwMGYzZjNmMzAwZThlOGU4MDBm YWZhDQpmYTAwZjVmNWY1MDBmY2ZjZmMwMGY4ZjhmODAwMDIwMjAyMDBmN2Y3ZjcwMGVlZWVlZTAw ZjRmNGY0MDBmZGZkZmQwMGYwZjBmMDAwMDkwOTA5MDBlZmVmZWYwMGZlZmVmZTAwZjlmOWY5MDBm MmYyZjIwMGYxZjFmMTAwZjZmNg0KZjYwMGViZWJlYjAwZGZkZmRmMDBjN2M3YzcwMGI3YjdiNzAw ZTllOWU5MDBlMWUxZTEwMGUwZTBlMDAwYzZjNmM2MDAwYTBhMGEwMDMwMzAzMDAwZTZlNmU2MDBl YWVhZWEwMGQxZDFkMTAwZDZkNmQ2MDBhMWExYTEwMDQ4NDgNCjQ4MDA0OTQ5NDkwMDI0MjQyNDAw OTA5MDkwMDBkN2Q3ZDcwMGI4YjhiODAwOTM5MzkzMDA2MzYzNjMwMDg0ODQ4NDAwNWY1ZjVmMDA5 ZTllOWUwMGUyZTJlMjAwNmM2YzZjMDA3YTdhN2EwMDYwNjA2MDAwOGI4YjhiMDBkZGRkDQpkZDAw ZTVlNWU1MDBiZmJmYmYwMDc0NzQ3NDAwZDJkMmQyMDAxZDFkMWQwMDI5MjkyOTAwYzFjMWMxMDBi MmIyYjIwMDgxODE4MTAwYzJjMmMyMDBlNGU0ZTQwMDVhNWE1YTAwNDc0NzQ3MDA1MDUwNTAwMGM4 YzhjODAwZGFkYQ0KZGEwMGNlY2VjZTAwYjZiNmI2MDA4Nzg3ODcwMDQzNDM0MzAwYTlhOWE5MDBl N2U3ZTcwMGNkY2RjZDAwZWRlZGVkMDBjNWM1YzUwMDU4NTg1ODAwNTY1NjU2MDBiNGI0YjQwMDZi NmI2YjAwNTc1NzU3MDBhN2E3YTcwMGRlZGUNCmRlMDBkNWQ1ZDUwMGUzZTNlMzAwY2NjY2NjMDA0 YzRjNGMwMGFhYWFhYTAwZDRkNGQ0MDA3MzczNzMwMDRhNGE0YTAwYTRhNGE0MDBiM2IzYjMwMDY5 Njk2OTAwNWU1ZTVlMDA1ZDVkNWQwMDlhOWE5YTAwNjY2NjY2MDBhM2EzDQphMzAwNzY3Njc2MDA3 ODc4NzgwMGFkYWRhZDAwZGNkY2RjMDBlY2VjZWMwMDFlMWUxZTAwOGU4ZThlMDA4ODg4ODgwMGNi Y2JjYjAwYzljOWM5MDA2NTY1NjUwMGJhYmFiYTAwZDlkOWQ5MDBhMmEyYTIwMGQwZDBkMDAwNzk3 OQ0KNzkwMDYxNjE2MTAwYWJhYmFiMDA2ZTZlNmUwMDgyODI4MjAwOTc5Nzk3MDA2ZjZmNmYwMDdm N2Y3ZjAwYzNjM2MzMDBhZWFlYWUwMDQ0NDQ0NDAwNTM1MzUzMDA4NTg1ODUwMGJkYmRiZDAwNTk1 OTU5MDBjNGM0YzQwMDg2ODYNCjg2MDA3ZTdlN2UwMDViNWI1YjAwOTU5NTk1MDA0MTQxNDEwMDk0 OTQ5NDAwNzU3NTc1MDAzYjNiM2IwMDcxNzE3MTAwOWY5ZjlmMDA4OTg5ODkwMDIwMjAyMDAwMjcy NzI3MDBkYmRiZGIwMDY4Njg2ODAwNDI0MjQyMDA0YjRiDQo0YjAwYmNiY2JjMDA0ZDRkNGQwMGMw YzBjMDAwMjgyODI4MDA5OTk5OTkwMGJlYmViZTAwNjI2MjYyMDA5Njk2OTYwMDU1NTU1NTAwNTI1 MjUyMDBhNmE2YTYwMDRlNGU0ZTAwOWI5YjliMDA4MDgwODAwMDM4MzgzODAwMjYyNg0KMjYwMDlj OWM5YzAwOGE4YThhMDA3MDcwNzAwMGIwYjBiMDAwMjEyMTIxMDAxNzE3MTcwMGIxYjFiMTAwZDNk M2QzMDAxMTExMTEwMGI1YjViNTAwNjc2NzY3MDBjYWNhY2EwMDBjMGMwYzAwMGYwZjBmMDBhY2Fj YWMwMDFhMWENCjFhMDAxZjFmMWYwMDMxMzEzMTAwOGY4ZjhmMDBhZmFmYWYwMDgzODM4MzAwNmQ2 ZDZkMDAzNDM0MzQwMDQ1NDU0NTAwMzczNzM3MDBjZmNmY2YwMGE1YTVhNTAwYThhOGE4MDAyNTI1 MjUwMDdkN2Q3ZDAwOWQ5ZDlkMDAzOTM5DQozOTAwMmUyZTJlMDA3Nzc3NzcwMDY0NjQ2NDAwYTBh MGEwMDBiOWI5YjkwMDNmM2YzZjAwYmJiYmJiMDAxOTE5MTkwMDRmNGY0ZjAwOGQ4ZDhkMDA2YTZh NmEwMDNhM2EzYTAwNWM1YzVjMDA3YjdiN2IwMDcyNzI3MjAwMmYyZg0KMmYwMDk4OTg5ODAwM2Uz ZTNlMDA3YzdjN2MwMDU0NTQ1NDAwOGM4YzhjMDA5MTkxOTEwMDJhMmEyYTAwMzYzNjM2MDAxMzEz MTMwMDMzMzMzMzAwMmMyYzJjMDAyZDJkMmQwMDFjMWMxYzAwNTE1MTUxMDA0NjQ2NDYwMDM1MzUN CjM1MDAyYjJiMmIwMGQ4ZDhkODAwMTgxODE4MDAzZDNkM2QwMDQwNDA0MDAwM2MzYzNjMDAxYjFi MWIwMDMyMzIzMjAwMTQxNDE0MDAwNzA3MDcwMDIyMjIyMjAwMTAxMDEwMDAyMzIzMjMwMDE1MTUx NTAwOTI5MjkyMDAwNTA3DQowMDAwMDMwMDAwMDAxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0 MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MDIwMjAyMDIwMjAyMDIwMjAwMDAw MDAyZmEwMDAwMDAwNTA1MDUwNTA1MDUwNTA1MDUwNQ0KMDUwNTA1MDUwNTA1MDAwNTE0MDIwMjE0 MDUwMDA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDAwMDAwMDAwMDAwMDAwMDA4MDYw MDAwMDAwMjAwMDAxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQNCjE0MTQxNDE0 MTQxNDE0MTQxNDE0MTQxNDE0MTQwMjAyMDIwMjAyMDIwMjAyMDAwMDAwMDJiZDAyMDAwMDA1MDUw NTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1 MDUwNTA1DQowNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUw NTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1 MDUwNTA1MDUwNTA1MDUwNTA1MDUwNQ0KMDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUw NTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTAwMDAwNDAwZmEwMGQ4 MDAwMDAwMGIwNDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDFhMWEwMDAwMDAwMjA1MDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDUxNDE0MDUwMDAwMDAwMDAwMDAwMDAwDQow MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA1MDQwMDAwMDNmYTA1MDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMA0KMDAwMDA1MWEwMDAwMDAwOTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwYTAwMDAwMDAwMDkwZDAxMDExMzAxMTMwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMWQwMTE2NDhiMjlhNTM3MjQ5NDk0OTQ5NDk0OTQ5NDk4Nzg3ODc4 Nzg3ODc4Nzg3ZTM5MWFlNDk0OWFlOTFlMzQ5NDk0OTQ5NDk0OTQ5NDk4NDg0ODQ4NDg0ODQ4NDg0 YzVjNWM1YzVjNWM1YzVjNWMzN2ENCjEwMDExMzBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MTgxMzhmYzU2N2M1Mzg4MDQ5NDk0OTQ5NDk0OTQ5NDk4NDg0DQo4NDg0ODQ4NDg0ODQ4NDg0ODQ4 NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0 ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NA0KODQ4 NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0 ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4NDg0ODQ4 NDg0ODQ4NDQzZmMNCjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMx ODBlMWVkMjFhMDgxYWZhMTQxNDE0MTQxNDE0DQoxNDE0MDIwNTAwMDAwMzA2ZmEwMjAwMDIwOTAy MDAwMDAwMDAwNTA1MDUwNTA1MDIwMzAzMDUwNTA1MDUwNTA1MDUwNTA1MDAwMDAwMDAwMDAwMDVm YTcwMWQxODEwMGQwMTE4MTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzIwMGU3N2JkMWEyOTAyMDAw MjE0MDUwMDAwMDAwMDA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1 MDUNCjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUw NTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1 MDUwNTA1MDUwNTA1MDUwNTA1DQowNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUw NTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwMDAwMDAwMDA1 MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDExZDEzODBmYTA2MTQxNGZh ZmFmYWZhZmFmYWZhZmEwMDE0MDRmYTA0MTQwMDAwMDUxYTA2MDAwMmZjYjlmYTA0MDQNCjA5MDkw OTA0ZmFmYTA0MDQwNDA0MDQwNDA0MDQwNDA5MDkwMzAzMDkwOTA0MDBhZDBlMTMxNTFkMDExMjE4 MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDExYzFjDQoxYzFjMWMxYzFjMWMwMTBkZGEwMjAwMDMxNDAyMDZmYTA0MDkwOTA5MDQwNDA0 MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQw NDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNA0KMDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0 MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQw NDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQNCjA0MDQwNDA0MDQwNDA0 MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDQwNDA0MDAwMDAwMDAwNTAwMDEwMTBkMDExODAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMWMxYzFjMWMxYzFjMWMxYzAxMTgxOGUzMDMwMjAwMDUwMzAzMDMwMzAzMDMwMzAzMDAw NTAyMDAwMDAwMDQwNzE0MDIwMDAwMDAwOTAyMDAwOTAzMDIwMjE0MDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIxNDA1MDUxNA0KMDIwMjE0OTkxNTEyMTAxMjAxMDExODFjMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFj MWMxYzAxMjA3ODAwMDAwNDA2MGIwOTA5MDMwMjE0MTQNCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMg0KMDIwMjAwMDAwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMx YzFjMWMxMDFjZTMwMzAyMDUwNDAwMDANCjAwMDAwMDAwMDAwMDE0MTQwMjA1MDAwMDA0YmVmYTAw MTQwN2JkMDAwMDA5MDIxNDA1MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDZjYjEyMDExODE4MDExYzE4MWMwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxMzFlYjIwNDAzMWEw OTA5MDUwNTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0K MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzBkMWQxY2NlMDIwMjE0 MWExNDE0MTQxNDE0MTQxNDE0MDAwMzBiYmUwNjAwMDAwMDAwMDAwMDA2MDYwNQ0KMTQwNjA5MDkw MzE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDA1MDUwNTA1MTQxNDAyOTkxMzEyMWQxZDE4 MWQxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDExYzFjMWMxYzFjMWMxYzFjMDExMGU2MjkwMzAyMDAwMDAzMDMwMjE0MDUxNDE0 MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQx NDE0MTQxNDE0MTQxNDE0MTQxNDE0DQoxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0 MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQx NDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNA0KMTQxNDE0MTQxNDE0MTQxNDE0 MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDE0MTQxNDAwMDAwMDAwMDUwMDAxMDEwZDAxMTgw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxYzBkMWNjZTAyMTQwMDA0MTQxNDE0MTQxNDE0MTQx NDA1MDUwMzA0MTQxNDBjYjBmZGQ4MDkwMDAwMDMwMjAwMDIwMjE0MDUwNTA1MTQxNDAyMDIwMjAy MDIwMjAyMDIwMjE0DQoxNDA1MDUxNDE0MDIwMGFkMTcwZDFkMTAwMTEwMTgxYzAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFj MWMxYzFjMWMwMTEyNzcwMjAwMDUwMDAwMDkwMw0KMDIxNDE0MTQxNDAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMDAwMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMx YzFjMWMxYzAxMGQxOGUzMDMwMg0KMDAwMzAwMDAwMDAwMDAwMDAwMDAwMjAwMDAwMDAwZjdhOWIy M2E0Y2I2MDIwYjA3MDkwMDA1MDUwMDAwMDAwNTE0MDIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwM2ExMzAxMTgxODAxMTgxODFjMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDExNTlhMDAw MDAyMDIwNDE0MDUwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTFkMGRkZTA5 MDQxNDA5MDAwMDAwMDAwMDAwMDAwMDAwMDUwNDA2ZmNjOThjNzkwZDcxDQowNzBiZjcwNDAwYmQw NDA5MDkwOTA0ZmEwNjFhMDUwNTA1MDUwNTA1MDUwNTA1MDAwMDAwMDAwMDAwMDUwMzJmMTAwMTE4 MTIwMTEwMTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMTBkYTAzMDAwNTAwMDAwMjE0MDUwMDAw MDAwMDA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUw NTA1MDUwNTA1MDUwNTA1MDUNCjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1 MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUw NTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1DQowNTA1MDUwNTA1MDUwNTA1MDUwNTA1 MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwMDAwMDAwMDA1MDAwMTAxMGQw MTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWQwMTFjZGYxYTAwMDAwMjA1MDAwMDA1MDIw MjA1MDAwMjFhMDAwNDAwMmVkY2M1NzU1MzViOWE0MzVlOWY2YzNlYTdkOWU0YzIwMDAwMDAwMjAw MDAwNTE0MDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDA2OTEwMTgxYzEyMTgwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDExMDc3MDUwMDE0DQowNTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAN CjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDExMjAxDQoxNzk4MDQwMDA1MTQwMjA1MDAwMDE0MTQwNTAwMDAwYzAwMDgwMDdk ODEzMTIwMjQyNTEzNDAyNDJlMmQxNjEwMWY0MDNkZmMwNDA5MDkwMDAwMDUwMjAwMDAwNTAwMDAw MDAwMDAwMDAwMDAwMDY5MTAxODFjMTIxODAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTA3 NzA1MDAwMjE0MDUwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDA1MDAwMTAxMGQwMQ0KMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExODIx NzIwMjAzMTQwMDA5MDIwMDAwMDAwNTAwMDAwNTAwMDAwNzAwOTINCjc5ZjNhZDdmMDE1NjRmYWIx NTYzNTgxODAxMTg4NzA5MTQwOTA0MDUwMDA1MTQwMDAwMDUwMDAwMDAwMDAwMDAwMDAwMDA2OTEw MTgxYzEyMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTEwYzMxNDAwMDIxNDA1MDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNTAwMDEw MTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTA1OGRhMDUwOTAwMDBmYTAzMDAw MDAwMDAwMDAwZmEwMDFhMDAxNGZjNjEzOTY4MDEwZDUwOGY3MzAxOGY1ODc1MWQxNzcyMDIwMjAw MDQwNQ0KMDAwMDA1MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNjkxMDE4MWMxMjE4MDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMGQNCmMzMTQwMDAyMTQwNTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTEwMTM2NTE0MDkwMDAwZmEwMzAwMDAwMDAwMDAwMDAwZmEyOTAw MTRkZThlNTJlZDRhNTgxNjdkYTEwMTUxMDExODAxMTA4NzI5MDkwMDA0MDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDA2OTEwMTgxYzEyDQoxODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTBkYzMwMjAwMDMwMjE0MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwNTAwDQowMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MTAwMTU5MDJmYTAwMTQwOTAyMDAwMDAwMDUwMDAwMDBmYw0KMDBmYTAyN2ZjOTk4NmNhNzJiMDE3 NGJmMTMyYjIyNTgwZDBlZGUwNDA1MDUwNjE0MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw NjkxMDE4MWMxMjE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMjMzMDIwMDAzMDIxNDA1 MDUwNTA1MDUwNTA1MDUwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDUw MDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTEzMDE2MTAyYmQwMDA5MDIw NTAwMDAxNDE0MDUwMDFhMTQwMGZlMTRjYTk1ZWQ3Y2VlYWIwMTdhZmYxNjI1MmUxZDAxMjAzOGJk DQowNTA0MGIwMzAwMDUwNTAwMDAxNDAwMDAwMDAwMDAwMDAwMDAwMDY5MTAxODFjMTIxODAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMTIzMzAyMDAwMzAyMTQwNTA1MDUwNTA1MDUwNTA1MDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDExMTFjOWQwMmZjMDJmYTA1MDAwMDA1MDIwMjA1MDAwYzAw MjllOTAwMjZiODk3ZjIzZDhlMWM0NDk5MWMyMTQ0MWQwMTI1NDkwODAwMDUwOGZhMTQxNDAyMDUw NTAzMDAwMDAwMDAwMDAwMDAwMDAwNjkNCjEwMTgxYzEyMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDExMjMzMDIwMDAzMDIwMjA1MDUwNTA1MDUwNTA1MDUwMDAwDQowMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0K MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDANCjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDExMjBkMDE3NGZjMDQwMDA3MDUwNDAwMDAwNTAyDQoxYTAwMDMwMDI5MDAwMGI4MTFhYTQ2MjZm NTdjYjg0ZjY2MWM1OTAxMWMxYmRmMDAwOTA0MDAwMDE0MTQwMDAwMDAwNTA1MTQxNDE0MDUwMDAw MDAwM2E4MGUwMTEwMDE1ODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMWViMjFhMDAwMDAw MDAwMzAzMTQwMDA1MDMwMzAwMDAwNTE0MDUwMDAwMDAwNTAwMDAwMDAwMDAwMDAwMDAwNTA1MDUw NTA1MDUNCjA1MDUwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA1MDUwNTA1MDUwNTA1 MDUwMjAzMTQwMDAyMDYwMzAwMTQwMjAzMDkwOTAzMDIwMjAwMDAwMjAyMDAwMDA1MDIwNTA1MDUw NTAwMDAwMDAwMDUwNTA1MDUwNTA1DQowNTA1MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA1MDUwNTA1MDUwNTA1MDUwMDAwMDAw MDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDE1NjFiNTgzZGNkMDAw OGZjMDAwOTE0MDViZDAyMGIwMGU5MDcwNTBjNWY3YTU1OTQ4OTg3YWYyYjM1N2EwMTJlMWMNCjAx MWI5MDA3MDgxNDA1MDkwNjA2MDQwOTA0ZmExYTA2MDYwNmZhZmEwNDA0MDIyZjFkMDExODAxNTgx ODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDExYzFjDQoxYzFjMWMxYzFjMWMwMTEwZTZiZGZhZmExNDA1MDAwMDE0MjkwYjA5MTQw OTA0ZmFmYWZhMDQwNGZhZmEwNjA2MDYwNjA2MDYwNjA2ZmFmYWZhZmFmYWZhZmFmYWZhZmFmYWZh ZmFmYWZhZmEwNjA2MDYwNjA2MDYwNjA2ZmFmYQ0KZmFmYWZhZmFmYWZhMWEwNjA5MDUwNTAyMDIw NTA1MDAwMDAwMDAwMDA1MDUwM2ZhMWExYWZhMDQwNjFhMDQwNDA0ZmFmYWZhMDYwNmZhZmFmYWZh ZmFmYWZhZmEwNjA2MDYwNjA2MDYwNjA2ZmFmYWZhZmFmYWZhZmFmYTA2MDYNCjA2MDYwNjA2MDYw NmZhZmFmYWZhZmFmYWZhZmFmYWZhZmFmYWZhZmFmYWZhMDMwMDAwMDAwNTAwMDEwMTBkMDExODAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxNTgxNTAxMmNhYzAwMDAwMDAwYmQwYjAwMDAwNDAw MDAwMDAwMDI5Yzk1YmY4ZGUxNTQxOGVkYmZiNDQyMjA0YjYyMTA0YjlhMDAxNGZhMDAwMDAwMDAw MDAwMDAwMDA1MDAwMDAwMDAwMA0KMDAwMDAyY2MxZDAxMTAwMTIwMTgwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMx YzFjMWMxYzEyMTA5YTAwMDAwNjA5MjkyOTA5MDMwNjAyMDANCjAwMDMwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNTAwMDAxNDA1MDAwNTA5MDMwMjA1MDAwMDA1DQoxNDAy MDAwMDAwMDUwMDAwMDAwNTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMA0KMDAwMDFhMTQwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTIwMTY0MTcxOGI4YWVhZmQNCjA0YzAwNjAwZWRiZDI5MGNiNjA4OWI3NDE1OWE4 ZGZiNGZlNThlOGZjYTEzMTY3ZjAxMTczYTAwMDNmYjA4MDhiZWJlYmUwOGJlYmViOWZjYmUwODA4 YmViZWZjYjk4MjEwMTgxNTEwMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxYzAxZmYwMzA2 MDcwMzA5MGIyOTFhMWExYTBiMDdmY2ZjYmViZWJlZmNiOWZjYmUwODA4MDgwODA4MDgwODA4YmVi ZQ0KYmViZWJlYmViZWJlYmViZWJlYmViZWJlYmViZTA4MDgwODA4MDgwODA4MDhiZWJlYmViZWJl YmViZWJlMDcyOTA3ZjlmOWJlMDdmY2JlMDgwODA4MDcwNzA3MDcwNzA4YmVmY2ZjZmNmY2ZjYmVi ZWJlZmNmY2ZjZmNmY2ZjZmMNCmZjZmNmY2ZjZmNmYzA4MDgwODA4MDgwODA4MDhmY2ZjZmNmY2Zj ZmNmY2ZjMDgwODA4MDgwODA4MDgwOGZjZmNmY2ZjZmNmY2ZjZmNiZWJlYmViZWJlYmViZWJlMDcw MjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTBlMWMxMDE4MDEx OTAxMWY2ZmQ4MDA5YmVjYmRjMGZkMGFiZWZkYzFjMDlkMDE0OTQyMzNkOGNhZWVhNQ0KYTY2MmYy NDgwMWNhNTMwODBiZjdkOGYzYjZiNmI2ZjNiNmI2YjZiNjBhMGEwYWI2YjZmM2YzMzYxMTAxMTIx MjAxMTIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDExYzFjMWMxYzFjMWMxYzFjMTgwMWIxYzA3NmZkZjdmM2ZlZWQ3NmQ4ZWRm YmVkMDhjMGYzYjZiNmMwYzBkOGI2MGEwYTBhMGEwYTBhMGEwYWI2YjZiNmI2YjZiNmI2YjZiNmI2 YjZiNmI2YjZiNmI2MGEwYTBhMGEwYTBhDQowYTBhYjZiNmI2YjZiNmI2YjZiNjc2ZjNmZWYzYzBk ODBhYjYwY2U5ZjlmZWZlZTliOWZjZmVmZTBhYjZmM2YzYjYwYWMwYzBkOGQ4ZjNmM2I2YjZmM2Yz ZjNmM2YzZjNmM2YzMGEwYTBhMGEwYTBhMGEwYWYzZjNmM2YzZjNmMw0KZjNmMzBhMGEwYTBhMGEw YTBhMGFmM2YzZjNmM2YzZjNmM2YzYjZiNmI2YjZiNmI2YjZiNjA3MDIwMDAwMDUwMDAxMDEwZDAx MTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTE4MTgwMTEzMTEyMDdkZDJkMTAzMDJiZTFh MDBlOWZhMDAwMDAwMDhjYzg4ZGUzNDg4YzFlNjgwYWY4NTYzYTM3NzU5NmM0NmZhMjkwMDA0MDMx NDA1MDIwMjAyMTQwMDA1DQoxNDAyMDIwMjE0MTQwMmVlN2QwMTEyMDEwMTEwMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMx YzFjMWMxYzFjMWMwMTc1MzgwNTAwMDAwNTAwMDAxNA0KMDAwMDAwMDQwNjE0MDQwMjA1MTQwOWZh MDMxNDAyMDIwMjAyMDIwMjAyMDIxNDE0MTQxNDE0MTQxNDE0MDMwMzAzMDMwMzAzMDMwMzAyMDIw MjAyMDIwMjAyMDIxNDE0MTQxNDE0MTQxNDE0MDAwNTAwMDAwMDA5MDYwNjA0ZmENCjA2MDZmYTA0 MDMwMjA1MDUwNTE0MDMwMzAyMDUwOTA5MDMwMzAzMDIwMjAyMDMwMzAzMDMwMzAzMDMwMzAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIxNDE0DQoxNDE0MTQxNDE0MTQxYTE0MDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMWUxNzFiMGUxMA0KMGQxODI3NjVmMWJlZjkwMDAyMDkwMGY5MGMwNDQ1YTYy MzY3NTFhYjk1NGQ3NzQ2ZGY3YTYzM2ZiN2MyMDAwNDI5MDAwMzA1MDAwMDAwMDUwMDAwMDAwMDA1 MDMwMzAyMDUwMDA5NDU0YTBkMTEwMTAxMTAwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDEwZmU2 YzExYTFhYjkwOTI5MDkwNDFhMTQwMDAwMDkwMzAwMDAwMDAyMDMwNTAwMDAwMDAwMDAwMDAwDQow MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwYmRmZTBiMDIwMzE0MDAwMjA1MDAwMDAwMDAwMDAwMDUwMDAwMDAwMjAzMTQw MDAwMDAwMDAwMDUxNA0KMDIwMjA1MDUwNTA1MDUwNTA1MDUwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAzMDAwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExODE4MDEx NTAxMDExZjFjMDE3ZmJkZDNmZmI5YTQwMGMxMjllMDNjZDMyNDU5Y2NhNjJkDQpkNzU0OWE1ZWVh NzA3ZjNmODhhYTBiMDYwMDAwMWEwNDE0MTQwMzA5MDMxNDE0MDkwNjBiYmQyOWZhMDlmMWYzOGYx ODE2MTAxMjEzMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzEwMTk2MTk5N2U4MjQ4NmVmZjc4ZGFj MzdiYzEwMDE0MWEwOTE0MDJmYTFhMDQxNDE0MTQxNDE0MTQxNDE0MTQwMjAyMDIwMjAyMDIwMjAy MDUwNTA1MDUwNTA1MDUwNTE0MTQNCjE0MTQxNDE0MTQxNDAyMDIwMjAyMDIwMjAyMDJmMWFjODFk OWYwYjBmOTA1YmUwYjA5MDAwMDE0MDQyOTA2MDQwOWZhMjkwYjFhMDQwMDAwMTQwMzA0MWEyOTBi MDkwOTA5MDkwOTA5MDkwOTE0MTQxNDE0MTQxNDE0MTQwNDA0DQowNDA0MDQwNDA0MDQxNDE0MTQx NDE0MTQxNDE0MDQwNDA0MDQwNDA0MDQwNDAyMDIwMjAyMDIwMjAyMDIwMDAwMDAwMDA1MDAwMTAx MGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxNjJlOGRm ZTZmOGRjYzY5OTY5ODJhM2NmNjM0YWUxNzM4ODU5YjM5NDk2ZTczZGQ3M2FhNmM2ZThmNWJkMWEw MDBiMjkwODI5MDANCmJlMGMwMzAzMjkwMDE0MDViOTAwZTkzZTRhMTMxMjBkMDExMjAxMDEwMTAx MDEwMTE4MTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEx YzFjMWMxYzFjMWMxYzFjMDEwMTEwMjAyMDEwDQowMTAxMDExMTAxMDE4NzAwMDAwMzAwMDkwOTAz MDAwMDA2MDAwNjA1MDYwMGQ4MTQwMDE0MDAwMzAyMDUwMjE0MDZmM2ZiMDAwOTA4MjkwYjA5MGIw MDA1MDAwMDAwMDAwMzA0MDBmYTE0MDAwM2JkMDYwNGE0NzUwMTU2NjRiZA0KMDAwMDAyMDAwNDAw MGFiZDA2MWEwMDI5MzIwOTE0MGIwMGMxOWJiNjAwYmQwYjAyMDA0NTAzMGIwNjAwMDIwOTAwMDBm YTE0MDAwMDAzZmEwMzA1MGIwMDA2MDcwMDAwMTQwMDA0MDUwMDAwMDUwMDAwMDUwMjAwMDUwMDI5 MDkNCjAwZTkwMDFhZmEwMzBiMDIxNDA1MDMxNDE0MDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDExYzFjDQoxYzFjMWMxYzFjMWMwMTFjM2M2YzdlYjk0NWZmOGY4ZjQyNDdk YWQ1OGRkNDM0OGQ2MGJmYWY4NGRiYTBhMTgyYjFhNTgyNDlkMzY0YmUwMDI5ZmMwMDA2YjkwMDFh YmQwMjAwMTQwY2VkZmFlN2UxMTEwMTFkMDEwMTE2MDEwMQ0KMDEwMTAxMDExYzE4MDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzFk MTAxODFjMWMxODEwMWQxMjFlMTAwZDkwMDgyOWZhMTQwMDAwMWExYTI5MDcwMDA0ZmENCjA2MDBm YTA2MWEwMjE0MDQwNDAyMDUwMDAwMDAwMDAwMDAwMjA2MDAwMDAwMTQwOWZhMDQwMjAwMDAwMDI5 MDAwMDA3MDgwMDAwMGJmNzdhMGUwMTY4NDViNmI1MDUwMDAzMDAwOTAwMDAwMGJkMDBmN2MyNzZl MGE3YzU5MWY4DQowOGZjMDBiZWMxZWY2NDY0ZjRmMGJkYjYwODk0ZDZhZjJhZTczMmY3MDgwMzA0 MDkwNjFhMjllOTBjMDkwNjAzMDUwMjAzMDUxNDA5MDQxYTI5MDAwMDA5MDBmNzAwMjlmYTA3ZTlm YTA1MDAxNDAwMDAwMDA1MDAwMTAxMGQwMQ0KMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMx YzFjMWMxYzFjMWMxYzEwMDFjZjZiYzMwNWUwNGE1NzY2NDQ1MTc3YjcNCjZhZTE3YWQ1NjE3Zjcy ZjQ5M2VkMzYzYWI0NDQyZDc5NDc1NTk3OTFkNjhlZWRjMTNlMTQwMDAwMDZiOTBiYmQ5YjAyNmM4 ODFjMTcxMTAxMDEyMDAxMDEwMTAxMDEwMTFjMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMyMDFkMTgwMTAxMTgxZDIwMTMw ZDAxMDE0OTE0MDAwNDBiMDQwODA4MDAwMDAwMTQwMDA2ZmUwNDA0MDAxNDAwMDQwMDAwMDUwOWI5 ZDhlOTE0MGMxNDAwMWEwMw0KMDRiOTA0MDkwMjAyMDIwMzA5ZmExYTE0MDAwMDBiMGIyOWY5ZTcw MTAxMTBmNmMxMDBiZGZhMDYwNGZhMDAwMDA2MDgwY2Q4MWFjMDlmNmRiYjhiZGVmNWY5MGFkMWUw MGI2ZDVmNDQ5ZDcwMDAwMGVkNGY0YWExNmE2NWQ0MzMNCmNlODZjNjkxYWU4MDk2ZGRhNDAwMDYw MjE0MDMwMjA1MTQwNDAwZWRjMmZlMGIyOTAwMDBmY2JkMDAwMDA0MDQwYjA3ZmEwMDAwMDAwNTAw MDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxODIw NDg3ODVhNzZkYTIxMGYxYjFmMTdkNTlkMmU1YzJiMWU3NTFlNzQ1NDVkNWRkMDJmZDdjYWU1MmY4 MjQ4NDZhZA0KM2E3MmMxOWVjNWE5ZDlmMDg3MmZhYmM1NDA1MTI3MDEwMTExMDEwMTExMDExYzAx MDEwMTAxMDExYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMWMxYzFjMWMxYzFjMWMxYzE4MTINCjEwMTMxMzEwMTIxODExMTYyMDAxN2U5YjAzMDBiZDA5 YmUxYTAwZmEwN2Y5YjkwNDAwMTQwNjA0ZjdmYmY3MDYwNDBiMDMwMjA5MDAwNmI5MDAwMDAyZmEw YzFhMDcxYTA0ZmEwNDAyMTQwMjAwYjliNjFhMDAwMDA0OWJkMDFlDQoxMTIyMmFlZDAwZWQwMDA2 YmVmYjAyMDhmYzAwMDM5YjBjZmU1ZTkxYmI0ZGRkZDBiNjc2NWI4Yjc2M2E2MDE2MGVhMWMyZWFj ODI3MWQxMTFlMTk3NTNiYjgyMzdhMmIxZjBlMWI1MjhlNDViZWJkMGIwN2JkMWEwYmZjZDE2ZQ0K M2IyMjNiMWYyMTU2NzllMWM3NDViOTA2MjkyOWI5ZmEwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDExYzFjMWMxYzFjMWMxYzFjMDExNWJhYzZiMGY1NDEwZDAxMDEx ZDAxN2YwZDExY2EwMTAxMTgxYzFkMjhjOTE2NWJhMTY2MTFiY2Q3MzQxZDRlY2MxMGJjZTJjNDU3 ZDc1Nzg3MjIxMDU2ZGYxNTFjMDEwMTE1MGUwMTEyDQoxYjAxMWMxYzAxMDEwMTAxMDExYzAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFj MWMwMTE4MWQyMDIwMWQxODAxMDEwMTFjMDFiMWZkZmRmNmU3ZWQzMmQ4YzBlMA0KY2RlZGQxZTBk OGE0YzdkMTljMGM0NWY5NzYyYTJhMzI3Njc2ZTBiMGYxZThlMGMyZWFmMzc2NDVmYmVjZjhlMGYx ZjFlYTliMGFiMGM5OTQ2YjY5ZDU0MDAxMDFmNDA4ZjFlYjMyYjBmN2NkMDQ5Y2RjYjk5NzQ1ZGNl Y2I2ZjENCjljY2QzMGYzZWRlYmRjOWZjNzU1MDExNTAxMTUyYjEwNjEwMTE3MWUxZTExMTMyMDU4 MmI0YjEzMDEwMTAxMjNiYmViYTRiMGIwYTRiMGZkYjBlYmVjYmEwMTEwMTYxZDAxMTUwMTM1ZWI0 NWVkYjVmMWViYjlmYTAwMDAwNTAwDQowMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTFjMWMxYzFjMWMxYzFjMWMwMTE4YmFlZGZhOGIxNzU4MTAxNQ0KMWUxODJkMTA3NTQyMWIwZjBl MjExMDc1ZDk1Y2E4YzI2OTYwNTFjYTUxNjJlZjZjNGY1OWI2NDk0ZjY5NmEzOTY1MGQxZjZkNTkx ZTRiMGUxZjFmMDExODIwMDExODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMTIxMjEyMTIxMjEyMTIx MjEwMGQxNjNiNDliZDAwMDYwMDAwYjkxNDAwMDMwMDA1Yzg5OTU1NTViMTNmYzZlZjMyOWIwYjAw MDUwMDAwMDQyOTAwDQowMDAzMDAwMDAwMDRmYzE0MDAwMDAwMDAwMDA5MDAxNGI5ZDA4NjZlNDIz YjAxMTIwMTdkZjUwMDA3MDAwNDE0MDBmYTA5OWZkM2Y5NDZmYTBjMDAwMGZiMDIwMGMxMDcwMDAw MDVmYTA4OTM0MTI3MDExOTIwMTE0MDIwMDEwMQ0KMDEwMTAxMDEwZDE3MGUwZDE4MDExZDg4NmNi ZTE0MDUxNDAyMDAwMDA1MDZmOTY1MDExODFlMTAwMTAxMjA5OTAyMDMwNGZhMDQwMGZhMDAwMDAw MDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFj MjAxY2NhMGIwMGIyMTY1ODExMGQxYzAxMzQxMjE5NGYwZDAxMDExYjAxNTliMWViMmVkNjc4OWQy ODNiDQo3ZjRmZDlkY2I4Y2I5Y2EzNGY3NDU1ODM5MjE1MDFlNTg1MTExNzAxMDEwMTAxMTgxMDIw MTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTFjMWMxYzFjMWMxYw0KMWMxYzEyMTgxYzAxMDExYzE4MTIwMTAxMTkwMTFiOTllZTAw YmUwMDBiMDQwMGZhMDljZDNjMTMwMTEwNzU1ODE2NzU2MjJlM2RkOGZhMWEwMDA1ZTkwNWJlMDAw OTFhMDZhN2UzMzc2OGUyZjBlY2QxZThjOGUxOWQ3NTFmMTINCjAxMDE2MjAxMDExOTYyMjYyMTE5 MGYwZjI1MmM0MDQxMjM5YjAwMWExNDE0YTkzNjcyYzZhNTM2ZjUwOTE0MDAwNjg1MDEwMTAxMGUx ZjI3NzQxZTAxMTgwZDEyMTgxZDE5MGYyMTIwMDEwMTAxMGY0OTA3MDAwMDA1MTQwMDAwDQowMDA2 MDcyZjE1MDEwZDBkMDExMDIwM2EwMDI5YmQyOTA0MDAxNDAwMDAwMDA1MDAwMTAxMGQwMTE4MDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzEyMDExNTlmMjkzNDAxMDEx MDAxMDEwMTRmMTcxODJiMWQxMjFjMTExNzUwMjZlY2FlN2NmODVjNGE1OTIyY2FlMjg3OGYzOGM4 NDJjYTNiMjJiN2UwMTYwMWQ1ODAwMTAxMTENCjExMTgwZDBkMDEwMTE4MTgwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFj MWMxYzFjMDEwMTE4MTIxMjE4MDEwMTE1MDExNzEyMDExMjBmYmY1ZDBjDQowMDAwMWEwODAwMWE4 MDFkMjAxODAxMDExZDFjMWMxODUzMDIwMDBjZmEwMDAwMDBmZTAwMGFmYzAyYTUwMTEzMTUwMTAx MDEwZDFjMTUwMTAxMDEwMTAxMWQwZDAxMWMxNTAxMDExYzE4MTAwMTEwMGQyMDIwMWNmMmI5MTQw MA0KMDAxYTAwMDBlZDQ1ZmQ5YjA5MDMwMDQ1YTk1YzE4MTAxZDBlMTY3NDIyMWQwMTE4MTgwMTAx MTgwZTJjMmMxNzFkMWUxMjEyNmViZDA1MTQwMzA5MDUwMDAyMGJmZWNmNTYxNzE3MTEwMTFkMTBk NDAwMDkwMjAyMDQwMjAzMTQNCjE0MDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDExYzFjMTgxODE4MWYxNzhkYjAxYTBkDQowMTc1MWIwZDAxMTI0NDEyMWI1NjAx MGUwMTBlMWQxYjdmZTFmNDJjNjhkNzhkN2Y1OTJjOGFiZmM0ODZmZDQ0NTYyNmQ1OGRhOWE2MWQy ZDZkNDAxNjEwMTIyMDAxMDExNTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDExYzFkMjAxMzFjMDExODEzNTBiNzkzYTlmNzBiMDNiNmU1MmMwMTE3MTMwMTEyMjAxMDBk NDkwMDAwMDcNCjE0MWEwNzFhZTkwMzAzMDBmY2Q0MDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMx YzFjMWMxYzFjMWMxYzFjMWMxYzFjMDExZTFkMGQwMTAxNTFiNTI5MDUwYTAwMDBmYTA0MDA0NTBh MDAwMGMwNmNmMjIxMTAxODAxMTAyNTc0DQo2MjFlMDEwMTE4MDEwMTBkMWYwZjBmMTcxMjAxMDE3 NGUzNzYwMDI5MDAxNDAzMDAwOTA2ZTk2NTAxMTAxZDBkMTUwMTFjZTUwMDAwMDgwNTA4MDAwOGJk MDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzE4 MTgxODAxMWQ0MmZkMjkxMjAxMGQxNTAxMDExMjJkMWQ3NTRiMTg1ODAxMDExYzE5YTY1MDhiYWUN CmUzZjE1NWE1NmE0OGU3NmVlMTJmMzI2MDAxNThmMmQ1OThjMzFjMWY2ZDEzMGUwMTAxMTIwMTAx MWQxODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgwZDEwMWQxZDEz MTUyMDAxMTcwMTFjMTY3NTIyNGI3NTAxMDExMTAxMTIxNzAxMDExZDM4MDYwMGZhMDAwOWZhMDAw MjA5ZjE2OGJiNTcxYzFjMWMxYzFjMWMxYzFjMWMxYw0KMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFj MWMxYzFjMGQwMTEwMjAxMzc1ZTNiYmU4OTliMTdiYzNiZmNlZGRlOGMwMDAyOTNkMDExMDE1MTAx ODEzMjEzYjI1MjAwMTAxMWMwMTAxMWQ3NTNiMmIxZjEyMDEwZWNhN2U4YzNkMjgNCjIxMTkxZTE1 MTI3NTJiMDExYzBlMTgxMjIwMDEwMWQ0ZWQxNDAzMDAxYTE0MDAwMDA0MDAwNTAwMDEwMTBkMDEx ODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxODE4MTgwMTJjNjNhZmMxMDEx OTc1MTIwMTAxMTg0NDEzMmMzYjBkMWYwMTAxMDExMGI3MTdhM2U4NDczMmFlNjNiZjdhMmFjY2E3 NmFjNzUyMWYwMTBkNzk3NzViNjY0Yg0KZTM2MzFlMTIwMTFjMWMwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwZDE4MWMxMjEzMjANCjE1MWQxODFlMDEwMTAxMDEy MDFlMDEwMTIwMTgwMTE4MWYwMTFlOWQ4Nzc2MDNmYTA1MDAxNGI5MzBkMjI0NDEwZjAxMWMxYzFj MWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMTMwMTAxMTMxZjE1DQow MWI4MjZkNjRjZDY1ZDJiYmMzN2M0ZTVmNjRkMDA5NTFmMWUxMDBkMTIxMzFiMjU1ODIwMDEwMTAx MDEwMTEzMjU2MDI2MTkwMTAxNTY0NzU5MmMyODJjMWUyMDE1MGUxYzAxMDExNTBlMDEwMTAxMjAx MzE3YTM1ZGFhZTI0NQ0KZWRiZGNkMDAwOTAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMWMxYzE4MTgxODE1MTkNCjFmM2VmNTAxMTcxNzEzMWMwMTAxNjExZDBm MjIxODE4MDEyMDE4MDE0YWNhMDE1ZWM1MmZjODI3N2MxYmUyMjg1ZGJhOWZhMzE1MDE1ODFjYWRl YThmY2E5OWRiMWQxMDIwMWMxYzEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMGQxMjE4MTgxODE4MTgxYzAxMTAxMzEzMTcxZDE4MTg3NTEyMDExYzAxMDExZDAx MDExMA0KNjFiNGNjYjRiNzczYjQ1YzdkMGYxNzAxMWQxODE4MTgxODE4MTgxODE4MTgxYzFjMWMx YzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzEwMDExYzE1MWQwMTAxMWI0YmE3YTVmOGM3YzQ3MDkw NGI4ZmYwODQ3NjcwMTcxYzAxMDENCjFjMWQxZTE2MWYxMTAxMDExYzAxMDExZDc1MjYyMjFlMDEw MTU4NGE2MzAxOWQwZTFkMDEwMTEzMTIwMTFkMTMwMTAxMTcwZDAxMTMwMTE4MGYyYzNiN2E0Nzcz YmYwNDAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFj MWMxODE4MTgwMTEyMWM3YmRjMGUxNTAxMjAwZDFjMDEzNDE1M2JmMjAxMDEwMTExMTgxMQ0KMjE0 NzEzMjNiNTIzOGJkMjQxNjJlY2M2OWZlNjFhM2Q0NzI4NzQwMTZlMmFiYzIyNmE5YzAxMDExNzAx MDExZTEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTIxMDBk MDEwMTAxMGQxMDBlMTExYzBkMTgwMTAxMTEwMTAxMWQxNTFjMDEwMTAxMTIxMDBkMDEwMTAxMDEx MjE5MWMwMTIwMWQxYzAxMTgxODE4MTgxODE4DQoxODE4MWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFj MWMxYzFjMWMxODEyMWQxMDE4MDEyMDFlMjhhYTQxODNiOTllYjI4MjJiNGZmNzZmYWE3MTFkNTYw MTAxMDExMDExMTExNTFkMDExYzEyMTgxYzBkMWUyYzYyMjAwMTAxMWQ0NA0KNzkwZTcwMmMwMTAx MWQxMzAxMjAwMTAxMDExZDU4MDEwMTE5MTcxMjFkMTgwMTAxMDExODAxMGIwMDAwMDUwMDAxMDEw ZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMTgxODE4MTgxNTEzODA2 NDc0NzUwMTEwMTIxODAxMzQxNzc0NDQwMTEzMWQwMTAxNGIwMTNiNzUwMWRkZGI5M2U4NDA3YWM4 M2ZkMzM4ZDg5MzIyMWUwMTIzDQo1ZjVlZGExOTUwYjA3ZDAxMjAxYzAxMTcxYzAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYw0KMWQxMDFjMDEwZDExMTgxODEyMDEx MjBlMWMxMzAxMTgwZDAxMDEwMTFjMDEwMTFjMTIxMjEyMWQxMTBlMDExMTEwMDEwMTIwMTk3NTFj MWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMGQNCjFjMDEx NzFjMGUxYzU2ZDlmMjkxNWU5NWQyYzUzNTYxYzJhODk2NmYwMTE3MTAxYzAxMTAyMDFkMTgwMTAx MTIxMDBkMWMxODIwMTk3NTEwMTExMzE4NzQ3OTc1NTkwZTAxMTgxZDIwMDEwMTE3MjExNTAxMGQx ODAxMTEwMTAxDQoxNTE2MTYyMDEyMTAxMjAwMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxOA0KMTgxODE4MTcwMTU5Y2IyMDBlMWMxYzE4MGQwMTYx MGU0MDYxMTgxMjEzMDEwMTBmNzUxOTIwMDE3ZmYxM2YzNzg0ZTEwOTVmODZlNDAwY2MxYjU2N2Zj ZWUxZDlmYjhkMzVjZDMzMTUxODEzMDEwZDAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDExMjEyMTgxODBkMTMwMTAxMjAwMTEwMWUwMTFjMDExNzEwMDEwMTAx DQoxMjE4MTAwMTEyMTAwMTAxMTIwMTAxMGQxZTE1MWMwMTAxMDExYzFjMWMxYzFjMWMxYzFjMWMx YzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMwMTFkMDEwMTE2MDExNTAxNzk4YjU2Mzg4M2Jh YzU2YjM5OWFiZDZhNmZlZQ0KMTkxYzExMTIxYzEzMGUxNTE4MDExMjEwMWQwZDAxMTgxMTE2MTcw MTExMTExNWNhODgwZWJjMjIwZjAxMDEwZDFkMWQwMTAxMDEwMTIwMGUxYzAxMTIwZDE4MTMwZDAx MDEwMTE2MDAwOTAwMDUwMDAxMDEwZDAxMTgwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDExYzFjMTgxODE4MWQyNTAxMTUyYjAxMTMxZDAxMGQxMzEyNjYxMTYyNjAxMDAxDQoxMDEzMTgx MDIzNzQwMTBkMWRlNGE5NWZlMjllMmFjMzZiNWZmY2JiYjdiYTlhOGZjYTcyYTk0MDUyNzIzOTEx MDEwZTAxMWQxMjFlMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExODAx MDEwMTFjMWMwMTAxMDEwMTIwMDEwMTFkMDExODAxMDEwMTAxMjAxNTAxMDExMDAxMWMxMDAxMDEx NTAxMTAwMTAxMTgwMTFjMWMxZDAxMDENCjAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxYzFj MWMxYzFjMWMxYzFjMDExNzFjMDExOTAxMTAwZDE1OGE3ZjhlZjY3NTIwZDJkYWE3MDQ2YThjNjgx MzAxMTcxODAxMTUxOTFlMWQxMjFkMTMxZDE4MDExMjBlMmMxZDAxDQowZDFkMTlkN2JhMWRjYTFj MDEwZDE1MGQwMTAxMTIxODEyMGQwMTAxMDEwZTAxMWMwMTBkMTAxYzEwMTgwMTAwMDQwMDA1MDAw MTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMTAxMDEwMTFjMTgxMjAxMGQx MjYyMjAwMTE3MDExYzEyMTAxODYxMTU0YjQwMDExMjAxMTIxYzFlNjE3ZDExMDExYzc5YmU1Y2Vl NGRkZGZmNjc1OWUyZTENCjI3Y2FmMjE4MDE3OWQwNzc0ZmU2NWEyODAxMWYwMTEwMDExMzFkMTIx YzAxMDExYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDExYzFjMWMxMWQzNDI0M2MwMDEyMDdlNzg3YjAyODE1YThlNTYxMjAxMTAxODFkNTY2MjBl MDExYzE1MTgxODAxMTUwMTUwMTUxMDIwMWMwMWQ1NDcxZTQ0MGQxODEyMDExZDE4MDEwMTAxMDEw MTAxMDENCjAxMDExYzFjMWMxYzFjMWMxYzFjMTgwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDExYzAxDQowMTAxMDExYzE4MTIxMDAxMTU3OTFlMTkxZDFkMDExYzBk MTg2NjIwNDE2MDAxMGQwMTE4MDEyMDUwNjAwMTBmM2I4MjkxODFjNWE0ZmUzMThiYmZjZGIyN2Q1 MTAxMjcxNjYzMzBiMzM0NjBkMDdhMDExYzI1MTAwMTE2MTAxOA0KMDEwMTFjMWMwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzc1ZDY5MWM0 NTQyYjNkOTc3OTdjDQpiNTRkNjhhODc1MTIxOTFlMTgxMzI3N2QyMTFkMDExMDAxMGQwMTEzMTg1 MTE1MGQxZDAxMDEzNTQ3MTc2MTE4MTgwZDAxMTAxYzAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFj MWMxYzFjMWMxODAyMDAwMDA1MDAwMTAxMGQwMQ0KMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MWMwMTAxMDEwMTFjMTgxMjBkMDExZDdhMDEyYjAxMTMwMTAxMGQxODY2MjANCjJiM2IwMTBkMDEx YzAxMTIyNzNiMGQwMTE3ZmY1N2MyYzU4MTAyZDY4YzU3YTQ5YTI1MTUxODIxMTk1NjNkYWMwZjBl ZDMzNjAxMWYxZjAxMDEwMTEyMWMwMTAxMWMxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMx YzFjMWMxYzAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMwZDRlNTI2YTAwM2Y2YWFiMTJiODk0OTU2 Y2I0NjAwMTE5MjAwMTEzN2Q0NDBmMTIwMTFjMDExMzAxMGQNCjFkYTYxMTEyMTAxYzEyNTJhMzBl N2QwMTFjMTAwMTEyMWMxYzAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMTgwMjAwMDAw NTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDEwMTAxMDExYzE4MTIw MTFjMDFiODAxMTcwMTAxMDEwMTBkMTJiODE1MmM1NjFjMTIwMTE4MDExYzNiM2IxYjIwMWQ2NjU2 OGVjNzhjMDNkMQ0KZGE1OTMyNTMwZjAxMTMwMWExNzBhZWRjMjAyYzcxNzExNzAxMWQwMTE1MDEx ODFjMDEwMTFjMTgxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDExYzFjMWMxODE4MWRlZTNkNWRkMDExMTgyNDQxYjRlYzg5NGQ3YTAxMjUwZDFjMDEwZTYx MmQyMTFjMDExYzAxMTExYzE4MWQ1MjBlMTIxMDEyMWQ1Y2EzMWU3ZDAxMDExZDAxMTgxYzEyMDEw MQ0KMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzE4MDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDExYzAxMDEwMTAxMWMxODEyMTAwZDAxYTE0YTAxMjAwMTEy MTIxMDEyYjgxZDU4MjEwMTE4MDEwZDAxMWMyNjQwMDExNjAxMjg0OTQ5ZDE5ZmMyZDE1ZGE4NDZk YWNhNjM3YTU5NzI0YzcxMWFhMDk0YzBhMjRmMDE0MTE4DQowMTExMTgxYzAxMDExYzE4MTgxYzAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxODE4MTgxZTZk ZDcyZGU3NDANCjEzOGYyNDM4YjY2MDM5OTU2MjFlMWQxMDFjMWY3ZDUwMTYxMDE4MTIxYzE3MWMx YzBkZDcxMTFjMGQxMjBkZDU1OTExNjEwMTAxMTAwMTFjMDEwZDAxMDEwMTAxMDEwMTAxMDExYzFj MWMxYzFjMWMxYzFjMTgwMjAwMDAwNTAwDQowMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTFjMDEwMTAxMDExYzE4MTIyMDAxMTM3N2JiMDExMzE1MTMxMA0KMTAxODY2MTM3NTc1MDEx YzAxMWQwMTFjMjc3ZDIwMTMwZTRjMWEwYzA5MDBjMDA3ZmI5NzAwOWZiYmRkOTJkY2M4Yzg5MGU4 ZWNlNWEwZmQ1NzFmMGQwMTExMDExMjFjMDEwMTFjMTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMx YzFjMWMxYzFjMWMwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzE4MTgxODEyMTY1ZTJmYzMzMDU5Y2NjZTQ5NjVj MmQ0ZTRkNDAxMWQwZTE1MDExMzU2MmMxNTEwMGQxMA0KMWMxNTE4MGQwMTRmMWQwMTE4MTgwMTRh NTcxZDYzMWMwMTBkMDExYzAxMTIwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzE4MDIw MDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAxMDEwMTAxMWMx ODEyMTAwMTQxNzJmMDQxMDExMzEzMTAwZDFjYjgyMDI1MGYwMTFjMDExMzAxMDEzYjdkMWYwMTE1 MzY5NjliDQpkOGVkMDBmZWViNmM2ZGJmNTAzYjc5YTYyYzU2MGY5MzM5NWM0OGVmNDg1NjAxMTUy NTAxMTAxODAxMDExYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMWMxYzFjMTgxODE4MTIxMjAxMzA4ZDVhMDljNjU1N2UxMDYxOGFlMzM5ZTExMDEzMTMxMjAx MTM1Njc1MTIwMTEyMWQwMTEwMTIxMTAxMzQxMDAxMTAwZDAxMjMyZDEwNGExMDAxMTIwMTE4DQow MTFjMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxODAyMDAwMDA1MDAwMTAxMGQwMTE4 MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMWMwMTAxMDEwMTFjMTgxMjFjMTc1MTgwZTAyMzAx MDExMzEyMTgwMWI4MGU0MTYyMWMxYzAxMTMwMTAxNGI5ZDc1MWMwZjgyYjc1OWIxZmQwMDA4MDBl OWYzZjZlMmQxZjMzMjBhMGNiZTA5Yjk5YzMxODENCmI1MjVhNjYxMDExYjFkMTIxYzAxMDExYzAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxODE4MTIxMjEy MTU1YQ0KNDQ5YWJlZThmN2UyMDIwOTAwZjRjMDllMWMwMTAxMDExYzc1ZjIyNzE1MDExYzEwMDEx ODBkMTkwMTI3MTMxYzExMTUwMTRmN2YxNWQ3MTUwMTE4MDExMjAxMDEwMTAxMDEwMTAxMDEwMTAx MWMxYzFjMWMxYzFjMWMxYzE4MDINCjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDExODFjMDEwMTAxMTgxMDEzMDEyMTc3ZmUwMGM4DQo0NDE3MTIxZDBkMTU2NjEwMjIy YzAxMDExYzFjMDExODc1OWQyYjBlMTE3ZjM2OGQ1N2RlYmUwMDAzMDAwMDI5MDkwYjAwYmQwOTAz YjkwNjAwMDBmOTAwMDYzMGUwYWEyMzAxMTAwMTAxMDExODFjMWMwZDAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgxODFjMWMxYzFjMDEwMTAxMzllNTAwMDYwMGZhMDVl YmFjZmViM2EyNDgxMTAxNTgwZDEyMjEyNjJjDQoxMzFjMjAwMTAxMWMxNTEwMDEyNTAxMjAwMTEy MTMzNTIyMTM3ZDE4MDEwMTFjMTAwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEx YzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgxYzAxMDEw MTE4MTAxZDBmMWRkOTAwZDhmMWM0MDEwZDEyMWMxNTY2MWM0Yjc1MDEwMTE4MWMwMTE4NzU5ZDU4 MTYNCjAxMjUzZGJjMWM3OWUyMDIwMGZhMDAwMDA1MDlmZTQ1MGFlOWVkZTkwMzA0MDUxYWYzNmYx OTQwMTYwZDFkMDEwMTAxMTgwMTAxMTIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTFjMWMxYzE4MTIxMjEyMGQ1OGU0MDRiZGU5MDYwMGY1YzIzNThhZDAwMDZlMGUxMDFl MDEwMTFmNTYxOTE4MDExZDAxMTgxODEzMTIwMTI1MTgxMzAxMDE1ODk5NTcxNjJlMTANCjAxMDEw MTEyMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBk MDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMwMTAxMDExODBkMTAxODAxOGIwMDAw MDA3MjAxMTAxYzAxMjA2NjAxMjUxNjAxMDExODFjMDExODU4OWQzYjAxMWQyMjUzNjA1MDRiNWEx NDAwZmMwMzE0ZmEwNjA2MDgwNjA5MjkwMg0KMDAwMDA1YmUwMGM4MDEwMTFiMWIxMzFjMDEwMTFj MDEwMTFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMTIwZDEw DQoxZDFkMjc4YjBhMDIwMDA4YzBhN2Q4NzYwMDZmNzI4MjAxMjUxMTAxMDExZjBmMWUwMTAxMTIw MTBkMTgwZDFjMDE2MjExMjAwMTFjNDBkYTIzNTYzNDFkMTgwMTAxMDEwMTBkMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMWMxYzAxMDEwMTE4MTIwZDE3MTMNCmJhYWVkZGIzY2IxMDEzMDEwMTE3NDQw MTJjNzUwMTFjMTgxYzAxMWM1ODc0NzQwMTE2OWQzMzI2NTUzNDY4MjkwMDA0MDAwNTAwMDAxNDAz MTQxNDAzMDIwMDE0MDBmZWI5ODAyMjIxMTYwMTE1MTgwMTFjMWMwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzE4MTIwZDEwMTA0MGRjODNlNDBhZGI1 NDE0YjkwMDA0NmM5MjUzMTgwZTE3MTgNCjFkMmI2MDJjMWQwMTFjMDExMDAxMDExODEwN2QxZjE1 MDExNTYwN2UyNjU2NjAxODEyMTgwMTAxMDEwZDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDEw MTAxMDExYzE4MTgxNTI1M2IyMDQxMjUzYjIwMTMxODAxMTE0NDAxNDEwZjAxMWMxODFjMDExYw0K MTY3NDJiMDExMjE4ZTYyNmEzNDFhYWFmZmJmYTAyMDYwMDAwMDMxNDA5MDQwOWZhMGIyOTAyMTQw YmUzNDEwMTFkMTkxNTE4MDExYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjNGI0ZTkxMGVmYjlkM2E5MTAwNzYwMGU4NDY4ZDE5 MDEwZTFkMTk1MDQ0M2IxNzBkMWMwMTEwMDEwMTBkMGU3ZjFmMGQxYzBkMTdiYw0KMDE5ZDRiMDEx YzEyMDExYzAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAx MDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMDEwMTIz MTkxODhmYmMxZjEwMGQwMTFkNjExMDQwNGIxYzE4MTIxYzAxMWMxNjQwM2IwMTEzMDFiYzIwNGY2 MjM5NTRlYjBiMDAyOTA0MDYwMDAwDQowMDE0MDAwMDAzMDAxYTA0YzJhMDE4MDExNzBmMTMxYzAx MDExYzAxMDExYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTE4MTgNCjFj MWMxYzAxMDEwMTAxM2VlNWQ0ZDg0MzRiNDE4ZTMxZjNiM2M4N2U1NzAxMjAxMDFiZjIyZDNiMTEx MjFjMWMxZDAxMDExZDFlNDQ1ODEzMGQwMTE4NDQwMTQyNjIwMTAxMTgwMTE4MDExYzAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMwMQ0KMDEwMTExMWM1NzRiMDFiYWExMTAwMTFkMWMw MTUwMjA2MTI2MWMxODEyMWMwMTFjMTY0MDNiMDE1ODFkMTAxZDQ3N2ZkZDA4MWFmYzAwMDAwMzAw MDkwMDA0MWEwMDAwMDYwNTAwZGM1OTk4MDE1NjIwMDExZDAxMDEwMTE4MDENCjAxMTIwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxODE4MTgxODE4MjE2ZDVhMzZm NzQ0MDEwZmI3ZGUwYTMwNTQ1NQ0KMDExNzEwMDExNzIyN2QwZjFkMWMwMTFjMTMwMTAxMTMxNTQw MTkyMDIwMDExYmJhNTg1YzdkMTIwMTAxMDExMjAxMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMWMxYzFjMDEwMTAxMDEyYzQxNjYxNTlkNzkxODAxMWQxYzAxNDAwZTJkMjcxODE4DQoxMjFj MDExYzFiNjAyMDEzMTAwMTYyOWQzYjdkNDMwMDE0ZjgwNDAwYmUwMDAzMDAwNDI5MDAwMDI5MDU5 YmVmNzQ2YzIwMWIwMTU2MTAwMTAxMDExODFjMWMwZDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDExYzFjMTgwZDEwMTAxZDAxNmM3ZTczZDAwZjQxMzhlZmExZWZkM2Yw ZTEwMTFjMGQwMTFkMmIyMjU4MGQxYzAxMDExNTAxMTgxZDE4MGYxODEwDQoxNTAxMjJlMTI2YTNj YTIwMDEwMTAxMGQwMTEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1 MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTE4 MWM0YjQxMDExNjUwMTUxMDBkMDEwMTM0MGU3ZjM0MDExMjE1MTgxNTEwMTgzNDE5MTIwZDEwMDEz YjJjNDQ2ZGM3YjU4N2MyYTQNCjI5OWI5NzBhMDAwODA5MDNiNjA3MDY0NjQzNWQxMDBkMDExZDAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTFj MWMxYzFjMWMxYzFjMWMwMTVlYzJhN2Y0ZDQ3MjkzNzMyNzMxZGY3YjdlMTMxYjEyMDExMDU4NDEy YzE1MDExYzEwMTIxMDAxMWIxODU2MjUwMTE1MTI0MWNmMmI3OTIxMTUwMTAxMWMwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMjYyNjAxMWIyNzAxMTAx MDAxMWM2MTFlN2YzNDAxMTIxZDAxMTAxODAxMzQ3NTEzMTIxMjAxMmIxYjlkNWVkMGIwMzgzMjAy MDA3NmM3ZmFjMGM2MzkwYjBiYzAwMGI5NzZkZTE4MWIwMTExMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzIwOGEz NDdjMDA3NzYxN2E1NTAxDQpkOWFhNWUzYTAxNTYxODAxMTAxYjBmMTYxZDAxMWMxODAxMTAwMTE3 MWMyNzFmMDEwZTEyMmMyZjU2NjMxYjEwMDEwMTFjMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMQ0KMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTFjMTI5ZDQwMDEyNTJlMDEwZDEwMDExMjY2MWYNCjJkN2QxMjEy MWQwMTBkMWMwMTJlMmMxMTAxMTgwMTI1MWUyYjdiYWNhMmM1NDUwMDlmY2Y5ZWI5ZDA3NzU5Mjkw MDA5MDAxNGZlNDkwMTE5MDExZDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxYzQzNGFiNGM3YzY5MTYxODkyMGM3 M2U0MzM4MTUxYzFjMDExMDE5NTgwZTBkMDExYzAxMDExMzAxMGQNCjAxNjExMTFjMGUwMTFlNzAz YjU5MTcxODAxMDExODE4MWMxODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAw MDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDExMDBkZjI5ZDAxNDE0ZjE5MTgxMjAxMTI2NjBlNjY2MDBkMGQxMzEyMTUxODAxMmU3NTFmMDEx MDFjMjUxZTE5NWI0Ng0KYTBlYTAwMDBiMzYyOGIzMThhNjRjNDQ2ZmUwMjc2ZmE2ZmM2MDEwZDEy MTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDExYzFjMWMxYzFjMWMxYzFjMTU1NDI3OTMwMDdkY2ZmNjM2Y2FkY2IzM2RmZjE4MTUxYzEyMjAx YjFiMTUxODFjMTgwMTAxMTEwMTAxMTgyMzFmMTIxMTAxMTU3ZTIyODgyMDFjMDEwMTE4MWMxYzE4 MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMTYxNDQwMTJjNGYx YjAxMTgwMTEyNjEyMDdkNGIxYzAxMWQxMDExMWMwMWYyMjEyNTBkMTcxMDIxMGUxZDZiMzJkZjFh MDYwY2IyNTBmM2JmOTZiNTVhZThlZGZhZjhmNzgwZGQxZDEyDQoxNTEzMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMw MTM5NTk2NWVkMjUNCjAxZTFmMDhlYTRmZmQyZGExYjAxMTIxZDFmNzUxYjFkMTgxMjBkMDEwMTFl MDExYzFkYTY3NTEyMjAwMTBlNjkyYzYxMjAxODAxMDExYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwDQowMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAxNGY3YzIwMTk0NDEzMDExOA0KMDExMjJlMWQ2MDIx MDEwMTE4MTIyMDAxMDEzNDBmMjcxMzFmMGQxOTFlMTg4ZTljMzYwMDA5MjlkYTRhYzIyZGNjZWNk YmI2ZjNiZWVhOTQyYTllMTcwZDAxMGUwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDFhMjVjNzEwNzE5MDE0ZmJj ODYwMDY3YmI2OTFlMWMxODIwMjE1NjFiMTAxYzEwMGQwMQ0KMWMwZTAxMGQxMWQ3MmMxYzExMDE1 ODY1MGQwZjE1MTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFj MDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMGQwMTQyNjUxZTEwNzQxMjFjMGQxYzEwNjExMDI2MWIwZDAxMWMxODIwMDEwMTUxMjE2 MDBkMTEwMTBlDQoyMTE3NGVmNDM2MDIxYTE0MzNhYjViYTFlMWY1M2RlZGVhYjVjMjg2MDA4MDFl MTgwMTFmMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMWMxYzFjMWMxYzFjMWMxYzFkYzZkZjM1MzAyNzYxM2Y3YjNmYjA0M2Y0Y2IwMTExMWMx NzBmNGIxNjEyMDEwZDE4MDExYzExMDExMzFlYTY2MjE4MTUxODE2YjcxMjc0MWQxYzAxMWMwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQw MTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTEwMDE4ZjczMTAw MTRiMGQxMjFkMTIxMzY2MTAzYjFmMGUxMjEyMTgxMTEyMTM1OTFmM2IwMTEwMDEwZTNiMGY5MjMx ODMxYWYzMDI3MThiNmM1MGNlYWNmZDk3YzkwYmY4ZTUNCjA2ODA3NTAxMDEyMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMx YzFjMTI1YQ0KZTgyNmZiNTI4NzgwZDUyNmMyNjdmNTU1MDExMzAxMTEyYjYyMWIxYzAxMTIwMTFj MTgxMzAxMjAxZTRhOWQxMjEwMDExMWJhMWY0NzBkMDEwMTFjMWMwMTAxMWMwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTFjMDINCjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMWMxNzY2NzAwMTBlDQo1OTE2MTgxYzE4MTM5ZDBk NTAyNTAxMTUwMTEyMTkwMTEzMjgxNjBmMWQxMzExMWMwZTIxOWU4ZWNlMDdmYTAwN2VjMjMwNTcy NjM4ZmE0NmNkMDBlMmFkZmVkYjFkMDExZDE1MDEwMTAxMDExODE4MDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzE4M2M4MTZhYzk2YTFk YzQ3YTk5ZmQ3MTY0YzQyMDAxMWYwMTQ0NTg2NjBkDQoxMTAxMTgwZDEzMDExZDEwMTM2MzQxMWYw ZDFjMWRjNDAxODgwZTEwMDEwMTAxMDEwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFj MWMxYzFjMWMxYzFjMTU1MWExMDExZjY1NzQwMTAxMTIxZDQwMTI2NjQwMDExNTAxMTIxZTAxMWQ2 MzJjNTYNCjEyMTgxZDAxMWUyNTY0ODc3MjAzMDBmZThjMzIzYzZjNzdhZGMxZGNjZDZiZjYyMzBh NmYwMTAxMDExODE4MDEwMTAxMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxYzY3OGE3ZWY3MjExYjM4YTU1MzMyOGM4YmNiMTAx YzBlMDE1MDYyNTcxNTAxMDEwMTE4MWQwMTEwMTIwZDJkNDAxZTFjMTgwZTUyMWRiODFkMWMNCjAx MWMxODAxMDExYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEw MTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTAxNTcz NDFjMWU4NTJkMDEwMTBkMTAyMjEyY2FiODAxMWQxYzEyMjAwMTEyMzQ1NjU2MDEwMTBkMDExYjQx OGI2ZGMyZTkwOGU5ZDBhY2NiNTk1ZGRkZjEwYg0KZjFhYmMyM2IwY2E3MDExZTAxMTgwZDE4MDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMWMxYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMx YzFjDQoxYzFjMThjODk3NTFjMjRmYjE1ZDcwY2NkMGM1YTA3NzAxMDExNTAxMjYyNjI4MTEwMTEz MDEwMTBkMDExMDFjMDFmMjNiMWQwZDFiMjZhNjJjMmMxODAxMDExYzEyMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMDENCjJkMzQxNTE3ZDQ2MTE4MWMxODEw NjAwZDJkN2QwMTEwMTgxMjFkMDExYzRiNGIyYjAxMDExZDEyMTYyYjM5MGExYWVhYjYwMDAwYjFi NDM4OThkNjhhZjBlZTQ4YTQ0ZjA4ODMwMTc1MDExODFkMTIwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTVlZDRkMmZj OTM3ZDJmNTgxYjlmMzk2NGU2MDEwZDFjMDENCjI3MWYyODEzMDExMzAxMDEwZDAxMWQxODAxNzQ2 MjEyMGQxOTRiMmQzNDU2MGQwMTAxMWMxODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFj MWMxYzFjMWMxYzFjMWMxZDBkNTA4ODE5MTdkNzYyMTMxODAxMGQ3NDBkN2QyNTAxMTIxMjEyMTgw MQ0KMDExZjc0MjIwZDEyMjAxMjE3MWY5OGVkOGI1ZWU5MDAwNDVjODYzMTlhNDhjY2ZiMjljNTQ2 M2ZiZTUzMDEwZTAxMDExZDEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDFjODkzMjdlYWE4Nzg5MzE2MjBkMDRkYmJj YzAxMjUwMTAxOWQwMWNhMTgxYzFjMDExYzEwMWMxNTEyMDE0MDdkMTMxYzAxMTA1Ng0KNTE3ZDE3 MGQwMTAxMDEwMTAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUw MDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMTIx MjBmYTMyMDEzNjYxNzIwMTgwMTBkNTAxMjI3MTcwMTFjMGQwZDAxMDExYzBkNjY1MDE1MWQxNzFj MTIxODkwOWM3YjMxMDdiNmJlNmNmMGEwDQplYjM5YWEwMGI5YjFlNzViMjk5MzFkMTUwMTEwMGQx ODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMN CjFjMWMxYzFjMWMxYzE4YjM4NjlkMDA0YjM4Mzk5NTVjOTRhNzNkOTkxMzFiMWMxMjc0MDEyMjE4 MGQwMTE4MTgxMDFjMjAxMDAxNzQ3NDFkMTAxZDE3NjI1MDU2MWUxZDAxMDEwMTAxMDExODAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYw0KMWMxYzAxMTIxNmNhMWMxM2I4MTExZDFj MDExMDc0MWMyNzFlMDEwMTEwMTAwMTFjMTIwMTJlNDAwZDE4MjAxYzEyMWNiMzBiZTkwYTAwMTQw MDAwZmQwMGJkMDgwMDQ2MGIyOWQxNjQwNTk1MTMyMDAxMGUxODAxMDEwMTFjMWMNCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExODE4MTgxYzFjMDEwMTAxMWMxYzFj MWMxYzFjDQoxYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMTU2ZmU2 MzZiNTExNTY0OTNmZGVjOGFlZDJkYQ0KMTIxMjExMTMyYjFlNTgyMDAxMWMxODFjMTIwMTIwMWQw MTlkZjIxMzFkMWI2MDU5MjYwZTIwMTgwMTAxMWMwMTAxMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDExYzFjMWMxYzFjMWMxYzFjMTIxMTBmNzQxODE5YTMwZjFjMDExODEwMjIwMTQwMjEwMTAxDQox MDFkMDExODBkMDE0MDRiMDEwMTE1MTIxNTEzYWFmOTAwMGIwMDAwMGMwMGJkMWFmOWMwZTkwOTA0 MDBjOTZjMDBmZjAxMTMwMTBlMDEwMTAxMDExODE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMTAwZDBkMGQxMjE4MTgxODFjMWMxYzFjMWMxYzFjMWMwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxM2U5NWI3NDY2Mzc0NWM0Yjg2ZTBj ZTY3OTMwMTExNTgxMTE5NTAxMTE2MDExZDE4MDExYzAxMTMxMDAxOWQ0MjFiDQowMTFkOWQ3MzM0 M2IxODAxMDExYzEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAw MDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMx YzFjMGQwZTlkMTEwMWJhMTYxMzEyMTAxMjRiMGRiODU4MDEwMTBkMTUxMzE4MWMxMjU3NTgwMTAx MTUxNzAxMTYzZTAyMDBlOWI2MTQNCjRkNWZjNDhlOTA4OTgxZjMwOTA2MTQwNDAyNzcyMTExMWQx MzE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMWMxYzFjMWMxYzFjMWMx YzAxMTUwMTAxNTgyNTIxMWYxMjE4MTgxYzFjMDEwMTAxMWQxMDFlMTExODAxMDExMDBkMTgwMTAx MWMxYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTFjMWMxYzFjMWMxYzFjMWMxYzg3NGNkNDMyMDExMGZmY2VjMzI5NGU0ZGIxMDEwMTFjNDExMTYw MTgxMTFjMGQwMTE4MDEwMTEyMDExZDQxN2Q1NjBkMTE3ZGE4NDAzYjEzMGQwMTAxMDExODEyMGQw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjDQoxYzFjMWMxYzFjMWMxODBkMGU5ZDIwMDEyNDE5 MGQwMTE4MTg2MjE1NTc0MTAxMDExODFkMWQwZDFkMTc0YTNiMTkwZDFkMWUxODFkYTg1YjA0MDAw NzE0YzA5ZmZjZDEwNjE0ZmFkODAwMDRkOGI2YzJiYzAxMGUxYzFjMTgxYw0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMWQyMTE1MTgxZDAxMDEwZDEw MTANCjEwMTAxMDBkMGQwZDAxMDExMzEzMTE3NTE3MTMwZDE4MDEwMTFjMWMxYzAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzE4 YjQ1ZTlkYzY1NzgwNGQ3ZDM0DQozMGUzOWU1ZjE4NjIwZDYyMWY5ZDAxMGQwMTAxMWMxMjAxMTgx MDAxMWM1OGYyMWIwMTEyNjFkYTM0MjUxMzBkMDEwMTAxMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMQ0KMTgwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMWMxYzFjMWMxYzFjMWMxYzFjMGQwZTUwMTcwMTZhNzUwZDAxMTgxODYyMTENCmJjMjcw ZDFjMTgwZDBkMTIxMzFmODgwZjFiMTAwMTBkMDEwMTdkOGY4YTE0MGEwYzI5ZjMwMGYzMWFiOTAw MDAwNzAwMTQwMGI1MjgwMTE3MDEyMDE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMDEwMTBmNGIxNTBkNTgxYzFjMWMxYzFjMTgxODE4MTIx NTBmMWMwMTE3MGUxNTBkMTgwMTAxMWMxYw0KMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMThmOWZmMmYwNzhlNTM2NTFj YjljOTM4YmNmMDExMTEwMjYwZjdmMGQwZDAxMWMxODBkMWMwZDE1MDENCjAxMjAyNjIwMDEwMTlk MzY2NjQxMTAxMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMw MjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMx YzFjMWMwMTEyMWVmMjFmMGQ3MzQxMTUxMjEyMTg0YjE1NzkyNjEzMGQxMjBkMTIwMTE4MTVhNjFi MWIxOTAxMGQxNTEzMWYxYg0KNzIwNjAwMDAwMGI2ZGMwMGYzOTQ0NjBiNzE2ODAwZmJhZmI0NzUx NzAxMTAxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTFjMWMxYzFjMWMx YzFjMWMxOTU4MjdkYmQwZThlMmYwZDBkMGQwYWZjOWM5ZThlOGM3YzJkY2NmMjAxODAxMDEwZDE4 MDEwMTFjMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDExYzFjMWMxYzFjMWMxYzFjMThjNDBiNjliMDIzMjJiNzkwYWQ5YzczOTI4MjExMTIwMTU2 NGIyODE1MWQxODE4MTIxMjAxMTIxMzAxMDEyMDIxMTUwZTBkMmNiZjM0NTAxODAxMDEwMTFjMWMw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAx MTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDExYzFjMWMxYzFjMWMxYzFjMDExMjFlN2QxZTEy YzQ1NjE1MTIxMjFjNDExMzYzNjIxMjE4MTIxMDEyMDEwMTEyNDcwZDEwMTkwMTAxMTA1ODAxMTdh ZDBhZmFjOWVlODQ1ZDQ3MDExMDg5ZGRiNzk1YzYzYjlkMjExYzFkDQoxZDEyMTgxYzAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMDExNTMwMjkwMA0K MjkwM2ZhMDQwNDA5MDkwMzAzMDIwOTA1MDQ1MzEyMDExMjE1MGQxODAxMDExYzFjMWMwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFj MWMxYzIzZDBkNTRlNDINCmM1ZWZjZjU2NWU3ODM3Y2MxNjAxMDE1ODYyYTMxNTBkMWMwMTEyMTgw MTAxMTAwMTFjNTg2MjEzMTYxMDFmNDI0MDlkMDEwMTAxMDExYzE4MTgwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwDQowMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxODBkMWU1MDE3MDE1YzU4MGQwMQ0KMDEwMTJiMWQ1 NzRiMDEwMTAxMGQxMjAxMWMxMDIzMWQwZDE3MDEwMTAxNTgxNzdkODcyOWE0ODFhODI4OTE0OTkz MTE3M2YxZGM5ZWFhMGQxZTI2MTIwMTAxMDExODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwZTIwNzVlY2ZhMTQwODA1MDAwMDAwMDAwMDAwMDAw MDAwMDUxNDkwMTIxMzE4MDEwZDE4DQowMTAxMWMxYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDE3M2VlY2IwMmY2NGVi MzgwM2Q3NmVmZjU0MzAxMWMxMzJjMjc3YzIwMGQxMDAxMWMxOA0KMDEwMTE4MDExZDRiNjMxYzEz MGQwZmEzNDExYjFjMDEwMTAxMWMxMjEyMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMx YzFjMWMxYzFjMWMwZDFlN2QxZTE4YjQyNTEyMDEwMTAxNTYxMmI4MjExODAxMDExODFjMDExODE1 N2EzYjU2MWIxMTExDQoxZDJjMDExYjkxZDBkZjU0OTAyZTdhMjRjM2FlZTllYmE4NzM5ZTAxMDEw ZTAxMDExODE2MTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMx YzFjMWMxYzFjMDEwMTE4ZWIwODAyMWEwMDA5MDkwOTA5MDkwNDA0MDQwMDFhMTRjNTEzMWIyMDEy MGQxODAxMDExYzFjMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzFjYjE1ZWQ0MjkwMGZhMDBmYzc2MDBkNmY0YjMwMTFi MTk3NTQxNDIxMjEyMTEwZDAxMTgxYzFjMTgwMTE1NjBhNjAxMWMxNTlkYTM1ODAxMWQxMjAxMDEw MTFjDQoxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAx MGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMTgxZTJl NTgyMDVmNjAxZDFjMTgwMTI1MDE1MDE3MTExZDE4MWMwMTAxMWMxNTNiNDEyYzAxMDExMzAxMTIx MDExODRlM2E2YzE0MzE4MjhiYWNiODA0NmFhNjE1NjViNTgNCjAxMDExMDEzMDEwMTE4MWMwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxNTFjDQowMTMy MDQwMDI5MDMwNTE0MTQwMjAyMDMwMzAzMDAxYTAwNTMwMTAxMDEwMTBkMTgwMTAxMWMxYzFjMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFj MWMxYzFjMTJhMQ0KYjVmMTAwMTQxYTA5ZmQ2YWVhYWY1NDNhMGUwMTExMTUwZTYzMDEwMTExMTAw MTEyMGQwZDEyMDExNTQwOGQwMTBkMTY2MTI4MTcwMTE3MTMxODAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDINCjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMGQyMDAxYTYxNjAxDQpjYjE2MDExYzFjMTgx NTBkZjIwZDEzMTAxYzAxMDExYzEwMTM3NTYwMmMyMDAxMDEyMDBkMWMwMTcyNjdkN2VkOTA0MTk1 YzY3ODY5ZTJhOTQwNWMzOTExMTgxMjAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMWMwMTEwNDZmOTAwMTQwNjAwMDYwMDA3MDAx NDA1MDYwMDA0MDIzZjAxMjANCjE4MWQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMTAxMDEwMTFjMTgxMjAxZTUwNDE0MDYw ODBhZGNiNWE3MDdlZWRkZmYxMTEwMTIwZTI2M2IxNTAxDQowZDBkMDExODAxMDExMjAxMTUyN2Ez MTYwZDFjNTgyZTU5MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMx YzFjMWMxYzFjMWMxYzAxMWQxYzdjNTYwMTY1MTcwMTEyMDExODIwMWQzNDE4MWQwZDE4MDEwMTE4 MGQxZDE2NzQNCjBmMTEwMTAxMTUxMjE4MTI4Y2M2N2ZmOWQ5NmU2Y2Q0ZGRiMjUzNGQxNzY2NmIw MTAxMDEwMTBkMTIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMx YzFjMWMxYzFjMWMxYzE1MWMyMGIwMjkwMDA0MDYwNDA2MDAwNDA1MDAxNDAwMWEwNjAwNDkxMDEy MDEwZDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTFjMDEwMTAxMDExYzE4MTIxNmUzZTg1YjA5ZmVlOWI5ZmEwODA1ZDZjNjlh MTkxMjIwNzUyNzRiMjAxYzBkMGQwMTE4MDEwMTEyMDExMzI2NTkwMTAxNzVmMmExZDU0ZjAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAw MDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTFk MWNkNzI2MTU1ZjE2MTAwZDAxMWMxNzExNjExODBkMTIxODE4MTgxODEyMGQxZjdkMmIxMTE4MDEx MDFjMTA1ODNkYzUxOTU0ZjQ5MDkzOTcxMTAxZjhjMQ0KZDU0YTgxMTUxYzE4MDExMjE4MDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMNCjFjMWMwZDAx MWZlYzA0MDAwMDAwMDAwMDE0MDIwYjAwMjkwMDAwMDAwMjlhMDEwMTAxNzUwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMTAx MDEwMTFjDQoxODEyMDE2Njc2MjRhZTQ4YzRkN2FmMDcwNGY2NWE3ZTEzMDExOTQxMjcyNTE1MTIw ZDEyMDExODAxMDExMjAxMWQ2MjRhMDExNzBkN2EyMjY2YjgwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzE4MTINCjAxN2E1NjIwNjUyYjE1MGQw MTAxMWYxOTJkMGQxODE4MTgxMjEyMTgxODE4MTc2MTYyMTEwZDAxMTgwMTAxMWU3MmIyODllY2I2 M2Q4NDRmMTkxNzVkYWM5YTRiZGQxZTEwMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMGQ1NmFjY2RiZTI5MDRiOTBiMDAw MzAwYmQ3NjA4ZTlmYw0KMGI4MzJkMjUwMTEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDEwMTAxMDExYzE4MTIxMTNiMzkx ZGU3NDJjYmIyODZjZDA0NjhhY2NmMTUxMDE5M2INCjYyMGUxMDBkMTgxODAxMTgwMTAxMGQwMTEw MmI3OTEzMWUwMTIzNjIyNzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTFjMWMxYzFjMWMxYzFjMWMwMTAxMDFiODE2MTI3YzFiMWQxODAxMWMxYjU4NTExMDFjMWMxODEy MTIxOA0KMWMxYzE1N2YyNzE1MWQwMTAxMDEwMTFjZmYzOWU0MDRhZjcwZGU4ZTlkMTZlNDcxYWVj YmJiMGQwMTFjMDEwMTFjMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTFjMWMxYzFjMWMxYzFjMWMyMDE2MTNhMzhmMjNjYTlkNjY1OTc4NmViM2I3OGYyODdkN2QyZDBk MDEwMTEzNTYwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDExYzAxMDEwMTAxMWMxODEyMDExMTc2MTY1NDg3YmE1NzdjODAyYWUz NmNiMjAxMDEyMDI3MmIxMjFjMTIxYzEyMWMxODAxMDEwZDAxMTIyNTI2MmIwMTExY2Y4Ng0KOGMx YjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAw MDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFj MDExMDBkNTcyNTEyNGYxZDBkMTgwMTEyNTg1OGNhMGQxYzFjMTgxODE4MTgxYzFjMTM3OTYwMWQx MzAxMDExODE4MjA5MzQ1NmNlYzY5NDEyNWQyDQo0OWM1ZDA2Y2I3YTliYjFkMTIxMjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYw0KMWMxYzFjMWMxYzFj MDExMzAxMTIwMTAxMDEwMTAxMWM3MzdkMzYxZDE4MDEwMTBkMjUxYjE2MmMxODAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFj MDENCjAxMDEwMTFjMTgxMjFjMmNjOTcxNGQzNTRhZGFkOTM2ZDE3M2FhZDUwMTIwMTA3NDRiMDEw MTEyMDEwZDFjMTgwMTAxMTAwMTE4NzU0MTExMTAwMTRjMDBlOTIzMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYw0KMWMxYzAxMTUxMTYzMGYxMjU3MjAw ZDBkMDExZDE2MTliODFjMWMxYzFjMWMxYzFjMWMxYzEzMjM0MDBkMWQwMTAxMTIwMTE1NzhiZWFk ZjU3ZTdmMTBhMTYyNTFlYzRlMGRlODZmMTUxZDEzMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTFiMjAxYzEyMGQxNzFkMGUx ZjdlNjAzMzAxDQoxODEyMWYxZDFjMDEwMTEwMDEwZDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAxMDEwMTAxMWMxODEyMmMw MWVkZDBlODVlODVjNGM0MjBkNjg3YjU4OQ0KMWQxNTFkYjg3NDFjMWMwZDAxMWQxODE4MDEwMTEw MDExYzE2NTAwMTE2MDFkMjAwYTQyZTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDExYzFjMWMxYzFjMWMxYzFjMDExODE4N2QxNzAxN2YxOTBkMWQxMjE1MTYxZTM0MDExODFj DQoxYzAxMDExYzFjMTgxMzU5NDAxODFkMDEwMTBkMTAwMWU1ZjU1NzJhZDMzNTEwODIyMjE4NmZj Nzk2NjQ3MTAxMDExMjAxMWMxYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDExYzFjMWMxYzFjMWMxYzFjMDExMDFjMDExMjAxMTgxMjAxMTM5OTdmODQwZDAxMDExODFj MDEwMTBkMWMwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMTAxMDEwMTFjMTgxMjAxN2E2ZDQyZWI4YmE2Y2E3YWE2 ZjU5MmUzOTMxNTFlMjA2MzJlMTAxMjEwMDExNTE4MTgwMTAxMTAwMTAxMWIzNDFlDQowMTFiM2Jm YWZmMTIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAy MDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFj MWMxYzFjMDEwMTYxMGYwMTYxNjAxMTE4MTEwMTU2MjAyNjAxMDEwMTFjMDEwMTFjMTIxMDEzYmM2 MDE4MTgwMTAxMTgwZTAxYTUwOTE5NGUNCjRjZTMzMzlhMWQwMWRkNWI5ZDNkN2IxODAxMGQxODBk MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTFjMWMxYzFjMWMxYzFjMWMwZDBlY2IyZGRhMTgwMTExMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTFjMWMxYzFjMWMxYzFjMWMwMTEwNjQxOTZmYjNlODdiZTEwMTgxNGM3YjNmMTMwMTE3MjEz NDEwMDEwMTEwMWQwMTEyMDEwMTAxMDExMDNiYmMwZTE4MWQxZWM5OGYwZDAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDEx ODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjDQoxYzFjMWMxYzFjMWMxMjFjMGQ2NjYyMTA2 NjdkMTUxYzIwMDE1NjExMjcwMTAxMDExYzFjMDExYzEyMTAxMzU3MjIwZDEyMDEwMTFjMDEwMWIz ZWQ2MzgzOTMzYWI3NGUyYjdkMzEzZTJmNGVhOTFlMWMwMTAxMDEwMTBkMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMx YzFjMTENCmFiY2E5YTEwMDExMzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMx YzE4MTMzMjZhNzY5ZDdhNmViMDcwDQo5ZjQzNWRiMjBkMDExZDc1N2YxNjE3MGQxODAxMWMxMjAx MDEwMTAxMjA0MDQ4MTcxODAxMTNhZTRiMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMQ0KMTgwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzEyMGQxZDM0MjYxNTlkMzQxZDAxMTMwMTJiMGUNCjQw MDEwMTAxMWMxYzAxMDExMjEwMWQ0NDI3MjAwZDAxMWMxYzFjMDE5Mzk1NzEzZTU5YTY2MDU1OTgz Mzg0MmFhNTUzZGIxYzAxMWQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTIwNjk3YWFlMWUxYzBk MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxZDAxZGMyOGU5NjAwMTE2 ODA2ODAwMmZhZWMzMDEyYzFlMmJiYzU2MWIxMDFjMDEwMTEyMDEwMTFjMDENCjE3NTBiNzAxMTgx YzFlYTMwZTExMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFj MWMxYzFjMWMwMTBkMTIzYjRiMGQyYzUwMTAwMTEwMDE0YjE5OWQxYzAxMDExYzFjMDEwMTE4MGQx MGYyMjYxZjFkMDExMjAxMTgyMA0KODU2ZmY0MDlkYmE5NjdlYzMzZGMwMGRlMTU5MDcxMDEwMTIw MTIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMWMxNzJmNGFkMjJjMTAwZDAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDEyMWZiNDdhYWJjMjIyMTkxNzMwMDMwNGUzNjEzMDE0 YjIyNjMxNjExMTgxMjEwMDExMjFjMWMxMjAxMTUyMjdhMDExYzE1NThiODE2MWUwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEw ZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDExYzFjMWMxYzFjMWMxYzFjMDExZDE4NTgy YjE4MTU1MDEwMDEwZDAxM2I1OGYyMTIwMTFjMTgxYzAxMDExODBkMGQyMjNiMmMyMDAxMGQwMTAx MTdjNTAwYjEwOTA3MDBmYTAwYjZkODAyMGEyZjdlM2UxNTEyMTIwMTAxDQowMTEwMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMx Yw0KMWMxYzAxMTEyZjRhNzEyYzEwMGQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMx YzFjMWMwMTBkZWQ5NWM4NDQNCjc5ZTM5ZjdhZDE0Y2EyODIwMTAxNjIyYmYyMWQwZDAxMGQxNTAx MTIxMjBkMGQwMTEyNTYzNDFkMDExMzEwN2EwZjEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwDQowMTAxMGQwMTE4MDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTExMTgxMTQxMTAxMjQ0MTMwMQ0KMTAwMTI3 MmM2MTEwMDExYzE4MWMwMTAxMWMxMjEyMmI2MjRiMTcwMTEwMDExMjAxZTViOTg1ZWJlMjg2MzJm ZTAwMDBiOTAwYjA2ODdiMTAxYzBkMDEwMTAxMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDExNTY5MjM5MTFl MDExODAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDExZmU0MDFlYTZk OTUyNDVjNDhkMTVjNWJlNTEwMTYyNTFmNGIxYzEwMTgxMjBkMDExMg0KMGQwZDBkMDExYzJjMmQx YjAxMWMwMWI3NTAxNTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFj MWMxYzFjMWMxYzFjMDExNzE4MGQzYjE3MGQyODExMDExZDAxNjA1NmI4MWQxYzE4MTgxYzAxMDEx YzEyMTIyMTRiMjcwZTAxDQoxZDAxMTUxOGFlNGViMDA2YTc4MmUwNDUwMzA0ZTkwYTAwMDA4MzAx MDExMzBkMGQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMjBjYjYzOTAxZDAxMGQwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMTVkYzhkZjUzYTdhYTVlZTk1YzI2MWIyYmYx NTAxNjA3NTQxMWMxNTBkMTgwMTAxMGQxMjE4MTgwMTBkNGI0YTE3MWMwMTIwY2NmMjE5MDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAw MTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMTEw MTAxMjYxOTEwYTYxNzAxMTMwMTc0MmI0NDEzMWMxODE4MWMwMTAxMWMxMjEyNTg0YjYwMWUwMTEz MDEwMTBkM2Y3OGE3MDZmMGZlOWZkNmJkYjkwMDAwYmRiNTViMTcNCjAxMDEwMTAxMDExYzAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjDQox YzFjMWMxYzFjMWMxYzE3Njk1MWIyMTIwMTEzMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMx YzFjMWMxYzFjMTIxMQ0KZDE4N2QwYWE5OTdjNTI1NzhhNGE2NDMzMTgxZDIzNjAyNzFjMTUxMDE4 MDExODEwMWMwMTFjMDExNTYwNWMxYzBkMDE3NTVjNzUxODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDINCjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMzEzMjBmMjAxDQoxYzU3MTgwMTFk MDE1MDJjOWQwZDFjMWMxYzFjMWMxYzFjMWMwMTQxMmU0MTEzMGQxZDEyMWMwZDQzNmRjNmZkMDAw MDQ1YzczMGVlYjZhN2FlYWMzZDEwMWMxMDAxMDExMDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTE4MWRhYjRm ZTEwMTFlMTgxYzAxMDEwMTAxMDENCjAxMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzFkMDFiNmJi YzAzZTQwYjg1MDQwZWE0OWM4YTgxYzAxNjMwZjFlMTAxNTBlDQowMTE4MTIwMTBkMTgxODAxMGRi OGNjMWMxMDAxMWUzNTBlMWYwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMTIxYzBkN2QxODBkNzkwZDAxMTAwMTQwMWU0YjAxMWMxYzFjMWMx YzFjMWMxYzBkM2INCjM0MjUxYzAxMWQxNTAxMDFlMTNlZDYwNjAwYzBlYmEwOTA0MmUyODdkNWMw YWUwMTAxMTIxYzE4MTExMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExODE1NjUyMzZlMDExMTFjMWMwMTAxMDEw MTAxMDExYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTEzYTk1NmVmYWNkMjVkODg2MTQ2ZGZj NmU1MTUwMTlkNTgxZjE4MTIxNzFjMGQxMDAxMGQxODE4MDExMDQ0YWIxMjEzMDExNzhkMGQwZDAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAw NTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTFjMDExYzdkMWQyMDU5MTUwMTFkMTg2MDEwNzUwMTFjMWMxYzFjMWMxYzFjMWMwZDI2Yjg0YjEy MDExMjFkMWQxMTZiZmM3YmZiMDhlNzk2NTYzNWE4ZmU5OA0KN2Y5ZjgzMWYxODFkMWMwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMWMwZWM0MjNjZjAxMGQwMTFjMDEwMTAxMDEwMTAxMWMwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMx YzFjMWMxYzFjDQoxYzFjMTgxY2M5MmUzMWIyYjE3Yjk4Y2JhNGRhZTM5OTFjMmIyYjJjMGYwZDAx MjAxODBkMTMwMTBkMWMxODAxMWQyZDY5MGQxNTFjMTE0MjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTINCjAxMTg1MDBkMTdhMzEx MWMxNTEwNzQxMDIxMDExYzFjMWMxYzFjMWMxYzFjMDEzYjUxNTAxZTAxMDEwMTAxMjE0NzRkYzNk ODY3ZmYwZjE4NGIxY2E0ZmRkYWYxNTMwMTAxMWMxNTBkMjAxZjAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFm NDg3YTZlMTgwMTAxMWMwMQ0KMDEwMTAxMDEwMTFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxYjAx NDYzNWM5YjcxYzUzZGQ4NmI1NDJhN2JmMWMzYjJiMjINCjdkMjAwMTEzMWMxYzIwMDExMjFjMTgx YzFkNDRjYjEyMTMwMTExYTYxMjE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTBkMTIxMjYwMDExZDRhMTMwMTFkMGQ5ZDExMmIxMjFjMWMx YzFjMWMxYw0KMWMxYzFjNjI1MWYyMWIxYzAxMWMwZTBmNDkwMDhjMDg0YzQ5Y2UyZTAxMWZjOTQz MzVmOTg3MWIxMDBkMGQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExOWI0NjNlNjEwMWMwMTFjMDEw MTAxMDEwMTAxMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMWMxYmY1YmE5Y2E4MDE4ZmNiNjcw YTg5MzEyZjFmMDEyYjlkNjYwZTAxMWQxYzAxMTEwMTEyMWMxMjFjMTA2NmNjMWMxMDAxMjA0Mg0K MTgxODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIw MDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDExODE4MTIyMjAxMDE2MzFjMDExMjAxOWQ1ODYwMGQxYzFjMWMxYzFjMWMxYzFjMWQ0MTM0 MjYxNzAxMTIxNTAxMDFlNWRjM2VmMWJmOGQ2YzVhDQpjNDJiNjhkZjUyNDY1NTAxMDEwMTE1MWQx ZDBlMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMWY4MjdmODQxZDBkMDExYzAxMDEwMTAxMDEwMTFjMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTFjMWMNCjFjMWMxYzFjMWMxYzAxMTZhNGRmYzhhNTdkYjg0OGQ0OWJiMzY4NTUxMTFjMmMzYjlk MTUwMTEwMDExYzE1MDExODFjMGQxYzEyZjJiZjAxMTAwMTE3NDIwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4 MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMTgwMTBkZjIxODAx NjEwMTAxMGQwMTUwM2I2MTBkMWMxYzFjMWMxYzFjMWMxYzBkMjEyNzJiMjAxYzE4MTMxNzAxZTNi YmRlZjAyNDE1NjNiYTZlYWVmZGM3YWUzMGM0MTMxMTAxMTIwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwZTcwNjY2NzEzDQoxMTAxMWMwMTAxMDEwMTAxMDExYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFj MTIwMTliNTMzY2FlODJlNTgwNDhkMTlhOTJiZg0KMWMyNzI1MjU0MTBkMDExZDAxMTgxZDAxMWMx YzEwMWMxYzc0YmEwMTEzMjAyYzUyMGQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWQxMjAxMWRjYTBlMTg3ZDFjMTIxNTAxMzQ3ZDU3MTAx YzFjDQoxYzFjMWMxYzFjMWMwMTBlNGI0MTFmMTIwMTAxMDEyMGNlMmY5OWMxNWM1ODk5NDAxN2U1 YmQ5MTIwYjU1OTAxMTUwMTEyMWQwMTFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTEzYTM0NmIxMzFmMDEx YzAxMDEwMTAxMDEwMTFjMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzE1MDFjMjFmYTJmYjUwM2Y3 YjY5NDY1NmRiMzMyMDYwNGIyYzI1MGQwMTFkMDExODBkMDEwMTFjMTAxYzAxMjI4ZDAxDQoxNzU4 NjA4MjBlMTAwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEx YzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTBkMDEwZDEyMjI1NjAxMjMxMDAxMTMxYzYzMWI0NDEwMTgxYzFjMDEwMTFjMWMxODBk MDEyNjExMjIxODAxMTgwMTEzM2Y3N2QyMDANCjlkN2FiNDhkZDY4NGMwODMxYzk0YmYxMjEyMGQw MTAxMWQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTBkYTg2MjVkMTAxMjEyMDEwMTAxMDEwMTAxMWMxYzAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTFjMWMxYzFjMWMxYzFjMWMyMTAxMDA5ZjZkOTE4NGNkN2M4ZjY4YzQ1YWJmMTMxMzNi N2YzYjFmMGQwMTEyMTIwMTAxMDExMjIwMDExODI1NzkxYjEyMGQ0MTcwMDExNTE4MWMwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBk MDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTBkMDEwZTE3 MWIwMTQ4MTgwMTEzMDE1MTFlMmUxYzE4MWMxYzAxMDExYzFjMTgxMjFjMjIxNzIyMTIwMTEyMWQw MTNmY2VmMjBhNWY3YTRjNGUzZjFiZWZhZWI4MzBiNDFjMWMxYzFjMDEyMDFjMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMTENCmIxMzQ4NzBkMWMxZTFjMDEwMTAxMDEwMTAxMWMwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFj MWMxYzAxMTlmOTlhOTcwM2YwZjFjOWVlDQpmZWFhYjUzZDRiNTAwZTIyMjExNzE1MDExMDE4MWMw MTAxMTgxZDAxMTA2MjIzMTUxODAxMTYzNTAxMTAxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMQ0KMTgwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTUwMTExNzUwZDFjZDcwMTAxMTUwMTQ0MjAN CjUwMDExODFjMWMwMTAxMWMxYzE4MWMxODc0MGUyMjEyMDExMDAxMTc2Yjg0YTZlMGFhY2RjODg4 MTIxMTA5ZTAyNWViYjcxMjAxMDExMjAxMTUwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTE5NzBiY2U2MWMw MTI1MWMxYzAxMDEwMTAxMDExYzAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMyYjE1M2M3Nzc2MDA0 NTAyMDMwMDAwZmVmM2M2MTkwZjEwMGYxNTE4MGQxYzFkMWMxMDBkMDExYzEyMDENCjIwNTBkNzAx MGQwMTFmY2EwMTEyMTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDExZDE4MWMwMWJjMDExMjNiMDExYzExMDFiODIwNTAwMTE4MWMxYzAxMDExYzFj MTgwMTBkZjIxZjIyMGQxYzFkMTkwMQ0KOTNkZTI2MDBmMGE2NWNiYTAxMDE4MTk2YmZhNDZhMTUx ODAxMGQwMTEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExZWFiNGZlNTAxMTI3NTE4MWMwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDExN2IwZTkwODBiMDAwMDA0MDIwYjA1ZmIzYTAx MmQxNjRiMTIwMTAxMDExMDFjMTMxZDFjMDEwMTAxMGU2Njg5MDExMTAxMjVmMjE1MWMxODFjMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAx MDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMTMxODFj MWM1OTAxMDExNjAxMTIwZTAxMmQxZTJlMDExODFjMWMwMTAxMWMxYzE4MDExM2I4MWIyMjEyMTgx ZDAxNDFkZTg2ZGNmMzgzN2I3NzhkMTUzNGY0NGE3M2UyOGQxNTEyMDExMzAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTE4MTVjYmNhYjMwMTEzMTUxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFj MWMxYzFjMWMwMTIwYTQwMzI5MDANCjI5OGJlNzAwMDNjMjMwNWYxMzQ0MGYyNzFkMDEwMTAxMGQw MTE1MTMxYzAxMDEwMTE3NjY4MjE4MGUxODYwNTAwZTAxMTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwDQowMTAxMGQwMTE4MDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTIwMDExZjJiMWQwMTU3MTgwZA0KMTEw MWNhMjFjYTFjMTgxYzFjMDEwMTFjMWMxODAxMTc1MTc1MjcxMjE4MTAxZDAxMzNlYTM4ZTdiMTdk NWJkZDJlMDFmYjQwOTAwOTUxMTIxODAxMjAxYzAxMTIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgxZGFiMzRh YTAxMTMwMTEyMTgxYzAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMjAwZmIwZjNi ZDFhMDYwMDlmMDAwMDRkNTQzNjJjMjExZjYyMTExMjFkMTgxMjAxMWQxMA0KMDExYzEyMDExNTlk ZDUxZDIwMTg3NDc0MjAwMTE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDExZDAxMGUxMzFmMDE2NTEyMTIxMzAxNTE0MTRmMTAxODFjMWMwMTAx MWMxYzE4MDExOWJjMmMyNzE4DQoxYzBkMWMxY2U1Zjc2Y2U3YTE1NzhmNjI1YTcyZWEzNTQ4YTA5 ZDAxMGQwMTExMDEwMTBkMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWU1NTdkOTQwMTFjMDExMjE4MWMwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMWU5NGNlMzczOWFkZGFmMGY3MDNmODli OTkwMTJlMTU1NjExMGQxZDFjMGQwMTBkMTgwMTEyMWQwMTEyNDFjYTE3MWQwMTRiM2IxYzFjMTgx YzAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1 MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTEy MDExMzAxMTYxNjE1MmYwZDE4MGQwMTU3MjY1OTEzMTgxYzFjMDEwMTFjMWMxODAxMTY0ZjI1MjYx YzAxMTIxODAxMzhmOTJiNDU2Y2IyY2EyODAxNzQwNGRkNGZkYzIyMTgNCjEzMDEyMDAxMDExYzAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTIxODkyZWY2MTgwMTAxMTIxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFj MWMxYzFjMWMxYzFjMDExZA0KYjA1ZGE3YzY2YWUxODE0NTA2ODZhNzcwMTg0YjExMmIxMzAxMDEw MTEwMTgxODFjMDEwZDE1MDEwMTc1NDAxYjFkMDEyMTJiMDExNTE4MWMwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDINCjAwMDAwNTAwMDEwMTBkMDExODAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEyMDEyMTgxYjc1DQoxOGFiMDEy MDAxMWQ3NDQwMjMxYzFjMWMxYzFjMWMxYzFjMWMxMzAxNDcyYzYyMGQxYzFjMDExM2M1YzFkYWY0 YTg5ODMwN2RiODE3NGMzNTI0OWYyYjIwMDExMjBkMDEwMTEyMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzEyNThi ZjI4NGQyMDFkMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzIwMGQ5 Nzg2NzE2YzcxODYzZTQyOGIzYzU0ZTYwMTdkNjIyZDAxMDExMTAxDQoxZDAxMDEwMTBkMDExYzE4 MDEyNTYxMWYwMTE4NjMxMTE5MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMWQxYzFjMWY3NTAxYjQwMTE1MDExMzYwMjI3OTAxMWMxYzFj MWMxYzFjMWMxYzEwMDENCjU3NTYyNTE1MDExYzFmMDE3OGFhNmQ1NDk5YmEzNWU0NmU3ZmNkNjll MWYxNTgxMDAxMGQxMDAxMDExYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxODE2YmZiY2FhMTAxMDAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxZDFkZmQ4YWI2NzYzMzhkN2RkN2I5 ZDZhNzg0MjA2MTIxNTExZDAxMTUwMTEyMTIwMTAxMTIwMTAxMTgwMTJiYmMxYjAxMDE2OTExMTMx MDAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAw MDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTEyMDEwMTFlMjEwMTQyMDExZDFjMTMyNjNiMmQwMTFjMWMxYzFjMWMxYzFjMWMxMjAxNjAz YjFmMWIwMTFjMTAxMmRhZGZkZmQxYjcyZDQ3M2ZhYjgyMzJhOQ0KNTE0ZDExMWMwMTBkMWQxYzAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDExYzFjMWMxYzFjMWMxYzFjMDExYjgyN2ZkMzAxMTIxODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MWMxYzFjMWMxYzFjDQoxYzFjMDEwZGZiZGVmMDU0NjlkNDc5N2FkY2Y1ZGY3MTE5MWYxNzU3MGUw MTE1MDEwMTFkMWMwMTE4MDEwMTE4MTgyNzhkMWYxMDAxOTAxMzAxMTUwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgNCjAxMWMwZTI1MDE1 NzAxMTIwZDEzNGI0MWYyMDExYzFjMWMxYzFjMWMxYzFjMWMxMjE2OWQyMDJiMDExODAxMjUzODQ5 ZDRiZTIzNzRkNTIyMmU4MDc2NDgxMWZkMjAxMjAxMTIxMDFjMDExYzAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMw MTFmNjUzNDgwMDExYzEwMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMx ZDAxZTg3Y2M4NGVhZDcxMmYyZDhiZjU3MTc3MjUyNzExN2YNCjBlMDEyMDAxMDExMDE4MDExYzAx MDExYzEyOWQ1MjE1MWQwMWE1MWMwMTBkMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMTgwZDE3MmIwMWYyMGQxYzFkMTAyYjJiNDAwMTFj MWMxYzFjMWMxYw0KMWMxYzFjMTMxNWI4MjAyNjAxMGQxODEzOTE3NzgyMjk3Zjc0OGRjNWJiODg5 YjZlMTM1YjBlMTMxODE4MTgwMTFjMTIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDExZWNjOWQzZjAxMDExZDAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMTAwMWVhMzUzMGE3YjQ4N2Iz ZDRkMThhYjMzYTc0MjExNjUwMWQwMTExMTIwMTE4MTIwMTE4MDEwMTAxMGQzNDQ4MGQxZDBkN2Ew MQ0KMGQxODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFj MDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDExYzFkMTAxMzJiMDEyMjE3MDExZDE4MGY0YjI2MDExYzFjMWMxYzFjMWMxYzFjMDEy MDEwNTcxZTI2MDEwZDBlMTgzMzgwOGZmZWI0NmU5NGVmDQpjYTAxZjEzZDRiZWYxNzE1MGQxYzAx MDExODEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMGVjYjQwODUwMTAxMGQwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTFjMWMNCjFjMWMxYzFjMWMxYzAxMTA5ZjkzZDNlMzI1ZDVlMDg3ZTJiMzk4YzQ0NDdkM2Iy NTAxMDEyMDEwMDEwMTBkMDExMjFjMWMwMTEyMmViNDFkMTAxNTJjMTgxNTIwMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQw MTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDExNTFkMTI1 NjAxNjI3NTAxMWQwMTJjM2I0YjFjMWMxYzFjMWMxYzFjMWMxYzAxMjAxMDc5MTY0MTFjMTIxMDEx ODVkYjU5ZmRjNmUzZDRiNzU4MmNmNmVmM2JkNjEyMGQwZDE4MWMxYzE4MTgwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMx YzFjMDExNzcwNzQzYTFjDQoxYzE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMx YzFjMjAxMGUzN2I3YjRlMDExZWFkNjVmMTc2ZDg1Zg0KMTc3NWYyMTUwMTFjMGQxODAxMTgwZDAx MTAwZDEyMDExODJlNDgxMTBkMTg1NjEwMDE3NTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTE1MTAwMTI1MDE0MTU2MDExMDAxMmMyNjRi MWMxYzFjDQoxYzFjMWMxYzFjMWMwMTE1MWQ3OTc1MjUxYzFjMDExMjM4YWVkYTJhZjA4ZDc1YzQx YzEwZjRkNTQ4ZTgwMTAxMTIxMjE4MTgxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMTcyZjlkZDQxMDFj MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMTVkNDViOTlhOTFk NTlkYjgwZWJmNmYwNDgxZWI4NjYwMTAxMTMwMTAxMDEwZDEwMDExZDFkMGQwMTFjMmViYTFlDQox YzAxMzQxZDAxMmIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMWMxMTEyMWQyMDFkM2I1ODAxMTAwZDFiNTAyNTE4MWMxYzFjMWMxYzFjMWMx YzE4MDExMTI4MmM3NTAxMDEwMTEyYTg3NjNhMTQNCjQ4YzY1YTdlMmIwMWMwMmUzZjlmMTYwZTBk MDEwMTAxMWMxODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTFkY2I3NDg1MDExMDE4MDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTExZTY2YjU1ZWFhZDgyZWM5NmIwOTE0MzczMjEy ZDExMDExMjE4MDExMDEwMDEwZDAxMDExYzAxMDExMTRiNGEyMDAxMTMzNTFkMDEwZTE4MWMwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEw MTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTFjMjAx MjFkMjAxZDI2MGYxYzE4MTI3NTYxNTYwMTFjMWMxYzFjMWMxYzFjMWMxMjE4MGU4ZjJjMjEwMTFj NzUxMzQzYjVkNGJkNTI0MDdjZDA4MGYyZDkwMWNlZTAyMDFkMTgwMTFjMWMwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMx YzFjMWMxYzAxMTMNCmNiMzRhNTAxMGQxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTEzNTZkNDZiOGU3NmFiNmJiMzI4DQplOGU0NGVhODJjNzU2MTEzMTUxMjAxMWMxMjBk MTIwMTAxMGQxODAxMTA1ODdmMDExYjAxNmUwMTEzMTgxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMQ0KMTgwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExNTE4MWQxMTEzMjc0YjFjMDExYzIx NDQNCjJiMDExYzFjMWMxYzFjMWMxYzFjMTAxMDE5OGYyYzJjMWMxMjBlMDFkZTgxYTNmMzZiNDg2 MDQyMzM4NzQ1NTFlM2M3MDEwMTAxMWMxMjE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTE1Y2IyZDk5 MTgwZDFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMDAxMzdiNTgz ZmM0MzIxZTExN2M5NGQ4ZTg1NzUxYzJiMDEwMTExMTAxZDAxMDExODAxMWMxZDEyMDENCjAxMTUy MjAxNTgwMTg1MDExMTAxMTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMTUxODFkMTExMzI3NDExODFjMWM1ODYxMGYwMTFjMWMxYzFjMWMx YzFjMWMwZDEwMTkyODc1MmMxMjBkMDExMw0KZGVmNGM0MDg2ZmQyZGFlMTdhMjAyYWU1NDlkYzAx MDEwMTFjMTgxODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDEwZTVmNTdiZjEyMTAwZDAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTAxNTI0ODdkNmY4YmNjZTk5NThjNzgxNzJj YzFmMTdjNDE2MWMxYzAxMDEwMTIwMWMwMTFjMGQxODAxMDEwZDBmMTcwMTAxNWMxYzAxMTAxODFj MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUw MDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTE1MTgxMDIwMWQyNjI1MWMxMjFjMWU3NDJjMWMxYzFjMWMxYzFjMWMxYzFjMTIxMjE3NzkxYjBm MGQxMjAxN2Q4NWZkOTlmNjI2OGRjZmEwNWYxZGVmOTk1ZGYwMTMwZDFjMDEwMTFjDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMx YzFjMWMxYw0KMWMxYzE4MTk4Mjc5YTExMjEzMTUwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTFlZTUzY2QyYzENCjcwNTlhYzQ4YTRhY2E5NTIwMTI3NzMxOTAxMDEwMTAx MDExMTE4MDEwMTAxMDEwMTFjMTAyYzIxMDEwMWQ1MTIwMTE1MTgxYzAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwDQowMTAxMGQwMTE4MDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTUxYzBkMTUwZDYyMmMxYw0K MGQwMTE3MjI3NTFjMWMxYzFjMWMxYzFjMWMxYzE4MDExMDJkMTk0MTEzMWMxMzEyY2IzMGRkNTRh MWNjY2NhZTZmYWEwNmI3NzNmNDBlMTUxMjAxMDEwMTFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMTIxNmM0 NGZiYzEyMWQyMDAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExNzQ3 ODM2ZGNkYjhkYTkwOTVjMmE4Njc1MzUwMGU5ZDAxMDExZDEzMTMwMTAxMTIwMQ0KMDEwMTAxMDEw ZDFkNzUxZTFjMDEzNjAxMTMxODE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDExYzIwMTgwZDFkMTI0MTU2MTgxODAxMGU3NDIxMDExYzFjMWMx YzFjMWMxYzFjMTgwMTAxMmUxYjI3DQoxNzFjMWQwMTg0OWJjNzAwYjBhZmVhYTRlOGMyMDBhZTBm ZWUxNzEzMTIwMTAxMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMTZiNzhmNDQxMjEwMTMwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTBmMDEyZDk0NzFlZjAxNGFlNDkwZjhh NzY4MmY1ODc1ZDcwZTAxMWMwMTE4MWMxMjEyMTgwMTAxMDExODBkMGQxNjEwMWUwMWIzMDExYjAx MTgxYzAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAw MDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTFjMTgyMDE4MTIxZDFjNTYzYjEyMDEwMTE5MzQyNTAxMWMxYzFjMWMxYzFjMWMxYzEyMDEwMWYy MTY3NDFlMWMwZDFmYTUwMmE2MDM0NWMxZmEwMGYxMDAwNWM5ZDIzNzEzMTANCjE4MWMxYzFjMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEx YzFjDQoxYzFjMWMxYzFjMWMwMTFiYjdhMzYxMGQxMjEwMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KNTlmNTNhNDYxYjBlYmM4MmY4YjMzZWRhMjgwMWNhMTgwMTBk MWMxMzFjMDEwZDBkMTgxYzFjMTIxODAxMWIwZDE1MTA5ZTAxNTgxMjE4MWMwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDINCjAwMDAwNTAwMDEwMTBkMDExODAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMGQwMTAxMGUxMzBkDQo3NTc0 Y2EyMDEyMDExMzQ3MWYwMTEyMWMwMTAxMDEwMTAxMDEwMTEwMTAxOTYwMjcxNzAxMDEzYjMzYTQ0 NWYzOGRiNzAyYmUwMDAyMGNiOWI2MDYwMTE4MTAxMjAxMDEwMTBkMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MWQ3MzdjNjYxODBlMDExZDFjMDEwMTFjMDENCjAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzEz MDE1MTk3NmE4YjYyY2NlMmE5MDAzNjdiZTY2NjU2NjMxOTAxMDEwMTAxDQoxMjEwMTIxYzAxMDEx MjEyMWMwMTIwMTgxMTAxZWUxOTAxMTkwMTAxMDEwMTE4MTIxODAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTEyMDEwMTE4MTgxYzE4MTAyMjE4MDEwMTEwOGYxZDFjMTIx YzAxMDEwMTAxMDEwMTAxMTANCjE4MTY0YjI2MTMxYzE1MDE5MWUzYjMwM2U3YjBkOTJhMDMwMGYz ZmEwMGVhMWUyMDEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTBkODI0ODU3MTIyMDAxMWQx YzAxMDExYzAxMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTFlNTc0OWE2ZjdmODU0ZmY0 MmEyOGZjZWIzMmQ1MDI3MGQwMTBkMGQwMTE4MWMxODFjMDExYzEyMTIxYzAxMGQxODFlMWQ5NjFm MWMxMjEyMTgNCjAxMWMxODE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMw MjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDExMDExMDEwMTEzNzU3NTIxMTYwZDAxMTIxMzRhMTgyMDEyMWMwMTAxMDEwMTAxMDEwMTEw MDE3NTBmMjcwZDE4MTAwMTk5Y2U4Y2JlOWIwMGM3NDYwYWU4MWFlYQ0KYzliNTQxMWYxYzAxMDEx ODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDExODU1Y2M4ZjEyMWQwMTFkMWMwMTAxMWMwMTAxMTgwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMWMxYzFjMWMxYzFjDQoxYzFjMDExNTM1ZjFlYjAyOTZmZjkxNzNmNjdiOTc1YTRiMTU3NTAx MDExMzEwMDExYzFjMTgxYzAxMWMxODEyMTgwMTEyMTAxMTE3MmYxMDE1MDEyMDFkMTgxYzFjMWMw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAx MTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTENCjBkMDExZTJj MWIxYjBkMWQxODBkMWRhNjFjMWQxMjFjMDEwMTAxMDEwMTAxMDEwZDAxMjE0MTUwMTAxYzAxNTE5 OTZmYWUwMDAwYmRmNGExOTk3OGE5MDE2N2U4NTYwZTAxMDEwMTEyMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTFjY2M3MGEzMTgwZDFjMWQxYw0KMDEwMTFjMDEwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFj MWMxZTAxOGQ5ZjhjZTkwYTAwYzFlYWJlZmJjMjZiNjExNzJjMTINCjAxMTAwMTAxMTIxMDE4MWMx YzFjMTgxODEyMTIxNTIwMTgxZDczMDExNTAxMjAxZDFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTEyMTMxMDIwMjAxYzAxMWMwMTE4MDExODQyMTMw MTEyMWMwMTAxMDEwMQ0KMDEwMTFkMTIwMTc1NTA2MTIwMDEwMTAxYjMwOGRkZjEwOGVmZDM5ZjUx MTIwYjdhZGRiMDIwMTAxYzAxMDExODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTIxMmNjYWI4ZjAxMGQw ZDFkMWMwMTAxMWMwMTAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDE0YmJjZDZmNjAwMGEw YjA2MDYwMGNkMzBhNzQ0MWIxYjE4MWMxMDAxMDExMjBkMTgxODFjMWMxYzE4MGQxMDFmMWYwMTFl OTUwMQ0KMGQxMzEwMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMWMxMjFkMDExMzUxYmZjNDlkMDEwZDAxMTU4ZjU4MDExMjFjMDEwMTAxMDEwMTAx MTUwMTAxNTg1MTM0MWYwMTUwMGUzMzVkYjcxNGQ2ODU2YTI2DQpkYWU0ZGMxODNkZWMwMTAxMTgx YzAxMDExYzE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTEyMWRjYzgyNzkwMTFkMGQxZDFjMDEwMTFjMDEwMTE4 MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTFjMWMNCjFjMWMxYzFjMWMxYzE1MTMyODA2Y2Q0ZDAwMDA4YWQzZmJjZGVjZjUxZDYw MTAwMTAxMWQxODFjMTgwMTFjMTgxODFjMDExODEwMTM3NTE2MTg5ZGFlMDExMjFkMTgwMTAxMDEw MTFjMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAx MGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTE1MWQxMzAx NzU4N2ViYzdjZjEyMWQxODU4YjgyYzBkMTIxYzAxMDEwMTAxMDEwMTEwMDEyMDE2MjgyNzE2MWMw MTExNTNlMDM1Y2Q5NWUzODYzYjIyMjhmODUzNmZlMjFjMTgxODFjMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDExM2FiYjQ3ZjAxDQoxZDFjMWQxYzAxMDExYzAxMDExODAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFj MWMxYzFjMDEyMmI3YzEwYTBhZmFlZDVkZTFkOThhZjg5NA0KMDE4ZDExMDEwMTBkMWMxODEyMDEx YzE4MTIxYzAxMWMxMDIwM2I3NTAxMjg4NTAxMTcxODE4MDEwMTAxMWMxODFjMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMjFmMDEyMmVlMDAwYzgzMWQwZDBkMjEw ZjBlMDExMjFjDQowMTAxMDEwMTAxMDEwMTAxNTgxNjRhMGY1ODEyMWIwMWIyMGFhZGYwOTA0MjU1 NGNlMzczZjBhNmQ2ZjQxNTEwMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTVjYjZhYjgw MTEzMDExZDFjMDEwMTFjMDEwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMWI2ZWUyODdj MWM3ZmVhOTlmYjVlZjlmZDkwMTBmNDEyMDAxMDEwMTAxMTAwMTFjMTgxMjFjMDExYzFkMTFmMjc1 DQowMThkOGQwMTIxMDEwZDE4MTgxODEyMTIxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDExOTAxMWYzYWVjYjY3OTE3MTEwMTRiNDAwMTE1MTgxYzAxMDEwMTAx MDEwMTAxMGUxYzE1NTkwMTYxMTgwMTE3N2JjNTM3MDgNCmJjYjhiMjJkN2NlZTAwZTI4YjI5MTIx MjE4MWMxYzFjMTgxODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxMzFlY2JiZjFiMTUxMzAxMTgxYzAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTAxMGYzODM2NGVlNjRjZmQ0ZWQxOWFiM2Ey MTc2MjBkMDEwMTE4MGQxMjE4MTAwZDAxMTAwMTAxMWQwMTFkZjIwZDE1YTE4ODAxMTAwZDE4MWMw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAw MDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwZDAx MWUwMTAxN2ZlNDliMmIwMTBkMDExYjdkMDEyMDE4MWMwMTAxMDEwMTAxMDEwMTEzMDEwMTU3MDE2 NjE4MWUwMWM0ODYzYTAwNjViOGEzNThjZmQxMGMyNDUxYzkwZDBkMTgxYzFjMWMxYzFjMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFj MWMxYzFjMWMxYzFkMWQNCjg5YjcxZTBkMTIwMTE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFj MWMxYzFjMWMxYzEyMWUzNGFlOTVkMGJiYzgzZTdlDQphMDkzYjM2NDExN2ExZDFjMDEwMTAxMDEw MTAxMGQwMTEwMDEwMTFkMDExZDYxMTExMTczNDIxMzEyMDExODFjMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMQ0KMTgwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFkMDExMzEzMDExMTNmNWExYzAxMTgx MjBkNTcNCjAxMWQxODFjMDEwMTAxMDEwMTAxMDExNTAxMDE0NDAxN2YxYzAxMmUyZjdiMjMwMDc5 MjJiZmM5ZWY5OWMyNzk3OGQwMWQxMDEyMTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwZDAxNDhj NDE5MDEwMTAxMTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTEzNzk2 NGRkZmUzN2UzYmExNWU0M2Q2NDk0MTEyODFmMTMxODE4MTgwMTAxMTgwZDAxMTAwMTAxMWQNCjAx MWQ2MTE5MjAzYTRhMTkwMTAxMTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDExMjAxMWMxMTBkMTJhMTQyMDExODEwMTMwMWQ3MDExMjE4MWMwMTAx MDEwMTAxMDExODE1MDEwMTYxMDE2MzAxMGUwMQ0KM2Q4N2NhMDA0MjY4YTIzOGYyMzRkMDZkYTFh YzEzMTAwZDE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMWMxOGNjOTk1NjAxMDExODE4MWMwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDEwMTIzZjdjOTBhN2I1M2I3MjJlMDk0 YjU1NDc1MmUxYjIwMTIxODE4MDExYzBkMGQwMTEwMDEwMTFkMDExZDUwMWUxMmFkYjgwZTAxMWMx ODFjMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAw MDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwZDE4MDEwMTE1NGYyMDFkMTAwZDEwMDFjYzFjMWMxODFjMDEwMTAxMDEwMTAxMDExODAxMDE2 MTEzNDcwMTAxMTAzY2RkNDJiMDRkYzk2YjFmMWM1M2Y2OTY5YWFmMTMxMDBkMTgwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFj MWMxYzFjMWMxYw0KMWMxYzAxMjBhODc3NDAxYzAxMGQxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFj MWMxYzFjMWMxYzFjMWMwZDBkMjNiNTViZjgNCmQwZTc1ZWIzMDM0NWI2NmQ3ZDYwMjAxODAxMDEw MTAxMDExODBkMDExMDAxMDExZDAxMWQ0MDE1MDEyZjBmMTgwMTE3MTgxYzAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwDQowMTAxMGQwMTE4MDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTIwMTIwMTAxMTZjYjUxMjAw MQ0KMTgwMTFkYWQxZDE4MTgxYzAxMDEwMTAxMDEwMTAxMTgxODFkY2EyNTczMGUwMTlkNTE2ZmIy YTRhY2Q3YmY0NzdkY2IzMTM0ZWNhMjFkMTAxMjE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDEx OWMzZTU2MDEyMDEwZDE4MWMwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDEx MTJkZjE1ZTQ2ZDgxYWU3NDYwMDBjZjNkZjYzNjAxMzAxMDEwMTAxMDEwMTEyMGQwMQ0KMTAwMTAx MWQwMTFkNjExNTAxY2IxYjAxMTIxZTE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExZDAxMTIwMTBlOTM3MDExMDExZDAxMTllMTE1MTIxODFj MDEwMTAxMDEwMTAxMWMwZDBkMTM3ZjRiDQo3MDU4MWQxZDY5ZDBkYmVkYzM0ZGRkN2UxZTVjNzY4 MjgzYmIwZDBkMTgxYzFjMWMxYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzFjMTllMWIxMjUxMjEyMTIxODFj MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMTI0MGI5Y2RlOWZiYTRlYzc2 YjkwN2U5Njc1MTM0MjAwZDFjMTIwZDE4MTIxMDBkMDExMDAxMDExZDAxMWQ4ODFiMWQyZjQxMDEx NTFkMTgxYzAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAy MDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTBkMTgwMTFiMTMwMWM0YjQxZTAxMWYwZDI1YTUxZDE4MTgxYzAxMDEwMTAxMDEwMTE4MTgw MTAxOWQ3NTU1MTExYzU4MjRlZmNlOWM3N2I4NDk1YjcxNjU0ZDQxMzE4YjEyMTINCjE4MWMxYzFj MTgxODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDExYzFjDQoxYzFjMWMxYzFjMWMwZDBlNjk4OTExMTgxMDE4MTgxYzAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDExYzFjMWMxYzFjMWMxYzFjMTMxYw0KMjcwMDFhZDhkMTc2ZmJiNmYzYmQwYzk4Yjg3YTE1MTgw MTE4MTIwMTAxMWMwZDAxMTAwMTAxMWQwMTFkNWMwZjE5NmVmMjFkMTcwMTE4MWMwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDINCjAwMDAwNTAwMDEwMTBkMDEx ODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMzAxMTMwMTE4DQoy OGI3MWQwMTE1MDE1ODM2MDExMjAxMDEwMTAxMDEwMTAxMDEwMTExMDExZDM0MGY3MzFmMTUxZTcw ZjRiNzlmNWU3MTg2MTE5M2VlZDE1OTg0NWExMDE4MDEwMTAxMWMxYzAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMx YzE4MTliNDczMTEyMDAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxNzU0MDBiMDIwMDA4NzZmZWI2ZmIwOWU5Y2UyODdhMWQxYzAxMWMxODAxDQowMTFjMWMwMTAx MTAwZDAxMWMxM2E1MGYwZDQ4MzQxODE5MDExYzAxMDEwMTAxMDEwMTFjMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFkMTcxODEzMDEwMWI4NDIxZDFjMjAwMTBmYzMwMTFk MDEwMTAxMDEwMTAxMDEwMTAxMTMNCjAxMTA3ZDBmNDgyNTFkMDE5MGIwNDJjODhjODBjNmRmODVi NDJhNDM3MTVkMTUxMDEyMTgxMjBkMGQwZDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTIwNTI2YTE4MGQwMTEy MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMjFmMmIwY2ZhOGFhOWJi ZmVmZWI1MDMwNzY3NDc1NzE1MTIxYzBkMTAxMjE4MGQxMjAxMTgxMDEyMDEwMTEwZTE0MDAxYTMx ZTAxMGQxYzFjMDENCjAxMDEwMTAxMDExYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwZDEzMWMyMDEwMWQ2MThkMGQwMTEzMWM0MTNmMDExMzAxMDEwMTAxMDEwMTAxMDEx ODE4MDExMDUwMjVhMTI2MWIwMTM2ZjViMWVhNWY0MGU2ODlhNTgzYjllMw0KZjRlZjEwMTIwMTAx MWMxODE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDExYzFjMWMxYzFjMWMxYzFjMDExMDM1NWMwMTFjMWMxNTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMWMxYzhmMDBiNjhmN2YyZDMxNDZjMDAwZmVlM2E2NDIx ZDFjMDExODEyMWMwMTE4MTIxODEyMTAxMjAxMDEwZGFiNjYwMWEzMTMwMTAxMTIxYzAxMDEwMTAx MDEwMTFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTFjMDIwMDAwMDUwMDAxMDEw ZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMTgNCjAxMTMy MDE1NDBkNzFjMDEwZDAxNGI5YTAxMTAwMTAxMDEwMTAxMDEwMTAxMTgwMTAxMWQ0MDBmNTc2MDE4 MTU2ZTNkNDllYTkxNGI0NDAxM2E5MmZhMzZlZDhjMGQxODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMx YzFjMWMxMjFkNDg4MjAxMTgxMDE3MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMx YzFjMWMwMTU4OTYwN2JiMTMyNTAxNmJjOWQ4MDBiNjg3NDI0MjFkMDENCjAxMWMxODAxMDExYzFj MTgxMjBkMTIxYzEyMTA0NzUwMDEzNTRiMjAwMTFjMWMwMTAxMDEwMTAxMDExYzAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwZDEyMTIwZDEwMDE3NWQ3MGQwMTE4MDEzYjkw MWMwZDAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTEzMjcyYjc0NzQwMTE2OTljMzk2Y2RlNjc1YjE1 M2U2ZDRmN2E2NmM0OTE1MTAxODE4MTIwZDBkMTIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMTAxZDY1M2ExMDE4 MTAxMzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDEwMTk0MDJiMjE4 MmMxMDk0OWM3NjA1MDc4NmE2MmQxMzE4MDExMjBkMTgxYzEyMDExODBkMTIxODBkMWQxZGNhMmMx Yzg4NDAxYw0KMGQxMjFjMDEwMTAxMDEwMTAxMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMTIwZDIwMWQxNTBkMmIyZjE3MDEwZDAxMjJjNTEyMGQwMTAxMDEwMTAxMDEw MTAxMDEwMTBkMGQ0MTIyNGIyZTBkMTA2OWFlMzYyOTg5MjhhYzg3DQo5MDRkZmI0MmE3OTMxZDBk MWMwMTFjMTIxODE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzEyMTI2OTk1MTUxYzE4MDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTE4MTgNCjE4MTgxODE4MTgxODAxMWU3NmJkOGQwMTFjNGJiMGQ4ZWQwMmZjOThk NzRmMTAwMTAxMDExYzAxMDEwMTAxMTIxMDEyMTgxMDFkMTA1OTFlMDE3ZjIxMDExMzIwMWMwMTAx MDEwMTAxMDExYzAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAw MTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMTgx ZTFkMTUxMzc0MzgxNjEyMGQwMTI3YzUxODEyMDEwMTAxMDEwMTAxMDEwMTAxMDExNTAxMjEyZTNi YmMxZDFkMzY4MzQ0MGM5ZTMxNGQ5MTNiYjc0NmZmODE4MDBkMWMwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMx YzFjMWMxYzFjMTgxYzJmZGExMTFjDQoxMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExODE4MTgx ODE4MTgxODE4MDFiN2I1YWMyNTI1MjI0NDJhZmI5YjE0MGMzZA0KNDI0NzEzMWMwMTE4MTIxYzAx MTgxODEzMTUxMjFjMGQwZDE4YjQwZjAxZDUyMTAxMWQxMDFjMDEwMTAxMDEwMTAxMWMwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMjFmMWMwMTAxNDE4NDU4MTIxODAx NjI5MDAxMDEwMTAxDQowMTAxMDEwMTAxMDExYzEyMTEwMTFiY2E0MGEzMDExODg1YTdjYWMwOWYz ZGM2NzQxOWUxYjBhYmFhZTUxMzBkMTgxYzE4MTIxMjEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzEyMWMzYTlh MGUxODEzMTIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgxODE4MTgxODE4MTgxODEyNTc2YjQ2 NDM3ZTdkNTJlMGQxMmExNDAyODYyOGYyMWIxNzIwMGUxZTE3MTEwZTEwMTcxMTBkMDExODE4MDE3 ZTdkDQoxYmMzOWQxMTEyMDExYzAxMDEwMTAxMDEwMTFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTFkMTgwMTE1MTAwMTIwM2ExODAxMjAwZDI3OTAwMTE4MDEwMTAxMDEw MTAxMDEwMTBkMDExNTE4MWM0NGYyNDcwMTBlOTBhMjZmMDMNCjNlZDU1MjE5MDFhOGMyYTFjOGNm MTMxYzAxMWMxMjFjMWMwZDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxYzFmNWY5MDExMTgxYzAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTEwMDExYzEwMDEwMTBkMTAxMDAxNTJkODA1YmVlOGVhMGMwYWZlMDBm YjkxNTU3ZjAxMWUxOTIwMTAwMTAxMGUwZjU4MWQxMDFlMTUwMTFjOTNjYTBkZGZiODAxMWQwMTEw MTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAw NTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTEyMDEwMTAxMGQxOGQ3MTIwMTBkMWMyN2M1MTgwZDAxMDEwMTAxMDEwMTAxMDEwMTAxMTAwMTAx NDRmMjRhMTMwZjZlOGJlNjM5OGE1YWMzNDc3NTg3OWI2M2Y1NTUyMDEyMDExODE4MDEwMTFjMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMx YzFjMWMxYzFjMWMxYzFjMWUNCjU1NzgxNTFjMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTEwMTMwMTAxMTgxODFmMGViOGI2MDMwMGQwNDY0NmViDQo5YzliZTdkZTJkYmMwMTQxNzUwMTE2 MWIwMTAxMDExMjE1MTcxNzBkMTAxYjlhNjYxY2IzNTcwMTFjMWQwZDFjMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMQ0KMTgwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTExYzAxMDEwZTFjMmQyMDAx MTgwMTIyODQNCjE4MTgwMTAxMDEwMTAxMDEwMTAxMDEwMTBkMWMxODdmMzQ0YTE5MDEzYThlNzcw YmFlNzljNjdiNzM3ODU0MjJkMTRmMTcxMDFjMTgxODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxYzBl YmZlNTFkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgxMDEyMDExYzEwMTAxMjYw MTNiNWM4YjBlZDA4ZjlmN2JlNDUxNGU4N2E2MTc1MGUwMTAxMTUwZDEyMjUxMDE3MTYxNjIwMWMN CjEwMTk5YTJlMTI5MDYwMDExMjFkMTgwMTAxMDEwMTFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTE3MTgwMTE4MGUxMjYzMmMxODEyMWM3NDg0MDEwMTAxMDEw MTAxMDEwMTAxMDExYzAxMWQxMjBkNTFmMjhmMTExYg0KZTZjOTJlYWY5Njk3OGVkYWJhNjgwYjAx ZTM0MTExMGQwMTE4MTgwMTAxMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMTgxMWM0YzMwZDAxMTgwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDExODEwMDEwMTAxMGQxMDE1MDExZDdmZjkzMGI2MGFhNGNkZjZi ZDFhZjE3MTI2NDEyMjAxMDE1ODEyMDEwMTAxMTAwMTAxMDExYzFkMWUxOWIxMzQxZWNjMTgxODEx MDExYzAxMDEwMTAxMWMxYzAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIw MDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwZDAxMTgwMTE4MTI1MjJiMGQwZDEyN2RhZTFjMDEwMTAxMDEwMTAxMDEwMTAxMTgwMTEw MTIwZDdmNzQ3OTI1MDE5YWFhMjNiNjQxMDE4NWU1YTg5MTliNDkwNzQ4MTMxODAxMWMxODFjDQox YzEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTFjMWMxYzFjMWMxYw0KMWMxYzE4MjA0OGU2MTIxYzEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTE4MWQwMTAxMWQxODAxMWMxOTM0NWUwMGZiMDANCmViZjk4MWQ1NjcwMDBiYWM0OThkMmM1Njc1 MDEwMTE3MTYwMTFlMDEwMTEwMWMxZDE5MTc2NTI2MmI4OTAxMWQyMDAxMWMwMTAxMDEwMTFjMWMw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwDQowMTAxMGQwMTE4 MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwZDE4MDEyMDEwMDExMzdl MmMwMQ0KMTgxZDJlOTExMjFkMDEwMTAxMDEwMTAxMDEwMTFjMDEwZDE4MTIyZDIyN2Y3NTE1YzQ5 YjY0ZWFhZmQxYTljNzc2ZWMwNGJiZDE0NDFkMWMwMTFjMTIxYzE4MGQwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFj MWMxNTZhZTYxMDEyMGQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTBkMDExMjFmMDEwMTIw OGZiMzVlMDUwMGZiYjBlZDNlYTU3YjBiZjRlNGM3NTM4NDUzYTE3NTBlMDEwMTFiMjAwMQ0KMjAx ZjAxMDEwZTIwNWYxYjIyOTk3NTExMDEwZDE4MDEwMTAxMDExYzAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMGQxMDAxMWYxMTEyMTU3ZTFiMDExODEzMmU0OTFjMWQw MTAxMDEwMTAxMDEwMTAxMWMwMTEwMGQxMzUxDQo0MGNhMjUwZTg1ZWNmYzAwMDlkODBiMDUwMGJl ZTljNWE5NDQxNTE4MDExYzE4MDEwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzFjMTM2YTMzMTMxMDEwMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwZDAxMWQxYjAxMTM3YWIxM2VhMTAyMDBlYWZkM2M1 NTMzNmRlZGZkNDZmODk5Yjc4ZGRhZWViYmI3M2IwZTE2MDExODEwMDEwMTE2MWVhZDFmNjBhYjJj MWIwMTEyMGQxYzAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEx YzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMTIwMTBlMTUxMjEyYjcxYjAxMTIxNWYyOGMwMTFjMDEwMTAxMDEwMTAxMDEwMTEy MDExNTE1MGU0ZjM0N2EwZjc1Y2YyYWJlMDIwMDAwMDcwMDA4MDQwMDRlZjQzYjExMGQNCjFjMTgx ODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDExYzFjDQoxYzFjMWMxYzFjMWMwMTEzNDhjMzIwMTMxZDAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDExYzFkMDExMjFlMTgyMjkzODRhOA0KNTlmYTM3NWFkMGEyYzY5NGYxYmQyOWI1ZmUwYmNk M2EzNmNlNTc0MmQyZmZkYWE2MzQ0MTEyMTU3NTFjOTUyYzIyYTMxODI1MTAwMTEwMTgwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDINCjAwMDAwNTAwMDEwMTBk MDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExODEwMWMxNzEy DQoyMDI0MWIwMTFjMDE0MDkzMTMxODAxMDEwMTAxMDEwMTAxMDExYzEwMWMwMTEzNTcyNzQ0MmMx Y2UxYzgwMGJkMGNmYTAyMDAxNDAwMDNmYmYzZDcwMTAxMDExYzEyMTIxYzAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFj MWMxYzAxMGRjYjM2MWIwZDAxMTAwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMjAxMDExMDAxMDExODFjMDExNTEyMDE3NTIx YmY4MDRjMDlkNmQxM2FiMmFlOWEzODUzNjhjOWViYzEwODAwMDZiOTQ2MDQ5ZmFjDQplMDM5M2Rh MjRkNmI3YjYxMWQyNTYzODE0ZTdlMDEwMTE2MDExODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgxMDAxMTMwMTEwNGExYjAxMTAwMTJiZDQw ZDIwMDEwMTAxMDEwMTAxMDEwMTAxMTgNCjAxMDExMmI4MjI0NDc0MTM5OTcxNGRmMzA0NzYzMGZi MDRmYjAwMDBmOTk5MWQwZDFjMDExYzE4MTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTBkYWJhODFlMTIw MTFkMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMWMwMTFkMTEwZDE4MGQxYzE5NTgxODBlNTAzNmI3M2NmM2MwMDAwMjljZmJl YzZjZDA5ZWY1ZWIwMGYzNWI4NTRmY2JjMzcyMzFlODAwMTQwNTAwMDliZDA2ZjdiNThhYWYwNGJl M2Q1ODAxMGQwMTE4MWMNCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTFjMTAwMTEyMDEwMTdmMjExYzIwMDExNjY1MDExZjAxMDEwMTAxMDEwMTAx MDEwMTE4MTgwMTAxNzQ3NDY2YmMxMDhjZjhlODAwMDBlZGEwY2QwMDA3MDg2NA0KMzJlNTE3MTMx ODAxMDExYzE4MTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDExYzFjMWMxYzFjMWMxYzFjMDExMGNjNmUyMDFjMDExZDAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMwMTAxMDEwMTAxMDEwMTAxMTIw ZDEyMTAwZDFjMTYwMTAxNDc2ZGNiDQo1ZDViNGU1YWNkZmRiOWYxYjZkYzA4ZmJmZWM4NjQzODQ5 OTgzZjhlYmI4NTgzNjc0MzdiM2M4NDg2YmI3ODlmZmQ5M2YxMDAwMDlhMjAxNTE2MTExODFjMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTFjMDIwMDAwMDUwMDAx MDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjEw MDExYzAxMDE3NDQxMGQxMTAxNzU4MjAxMWUwMTAxMDEwMTAxMDEwMTAxMDEwZDEzMDEwMTU2NTA3 ZGJjMDFjNTA5YWMwMDAzMGNkYmQ0NWM1ZWEwODg5YzQyMTUxMDE4MDExYzE4MTgxODAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFj MWMxYzFjMWMxYzFkY2MzYTEwMDEwMTEwMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExODAxMDExMjFkMGQxMjAxMTY0MGIy YTg0ZDY3NjdhMWUzOGNlOGViMzg5ZTlhZTRhMGM4OWU0OWJjMTUwMTI1YTENCjlkMDExZjlkMDE0 MDAxMDExZTU4MWQyNmExNDBmMGYxZTdkNzAxMTIxNzIwMTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWQwMTFjMGQxMjQxNjAwZDEzMGQy NjJmMDExZDAxMDEwMTAxMDEwMQ0KMDEwMTFjMTIxNTAxMDEwZTUwNjI0YTFmOTVmMTVmZjllMGZk YzM0YTI1NWFlNzUyMDQ1MTE4MWMwMTFjMTIxMjFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMWMxNWNjMmYx ODAxMWMxMDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTEyMTMwMTAxMTcxMzAxMGQ1ODBmZDI3OGE3NDk4MDQyYWQzZDk5MzJj ZGUzOGI5MDM1ODBlODM5Y2U0YjFmMWUxOTI1MTcwMTFkNjAxYzUwMTMyYjAxMDFiYzAxMWY5NmQ2 Nzc2NTFmMDEwMQ0KMDExZDE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTFkMTgwMTE1MWQ1OGYyMTIxMjFkNjE5MzE4MWMwMTAxMDEwMTAx MDEwMTAxMDEwMTEwMDEwMTBkNTAxNjRhNzVlNmMxOTVmZDhjOTg2ZDY0DQo2N2E3NWI3YThhMjYw MTAxMDExYzEyMTIxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzFjMjA1ZjJmMTgwMTFjMGQwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEx ZDE4MTAxZjAxMDExYmI4N2UNCjI0ZWZiMzQ4MjRhMjQ5ZDViMTRkYTIzZGM4ZGQ3MGIzMDhjN2Q2 NTA1NjAxMjEwMTE1MDExZTExMTcyNTIxMjExZTAxZjIwMTdhY2UyZjQxMjAwMTEwMTEwMTEwMTgx YzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDExYzAyMDAwMDA1 MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTFj MDExMzE4MDEyMDFkMTUyZTAxMDExMzdmMzMxMDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwZDAxMDEw ZDY2MWUyMzE1ODU0NjRjNDU0YTQ3MzQ3MDNkYTBmZTM5ZWI2MjBkMTgxYzFjMTgxMjE4MDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFj MWMxYzFjMWMxYzFjMWMxN2NiMmYxODFjDQoxODEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxODEyMGQwZDAxMTAxODEwMjAwMTE1OGRjZTYx YmJiMjYyODg2NDY4YTg0Nzg2NTRlMmRmZDI2ODM1OTlkOTlmODExYg0KMWQwMTE3MDExMjAxMjAw MTFkMTMxZDAxMWIxMDAxNTY1ZjYzN2QwZjE5MWIxMzE5MTMwMTE4MWMwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgwMTEzMTgwMTIwMGQxYzM0MDEw MTEzY2FjMzFkMTgwMTAxDQowMTAxMDEwMTAxMDEwMTAxMWQwZDFkMTU2MzFiODI0MDNhODA3YjI5 NjU1OTg4NjNkNDk0YjllNGI2MjYxMTFkMTgwMTAxMTgxODE4MDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzFjMGU2 OWQ0MTIxODEyMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDExYzE4MGQxZDEzMTMwMTE3MWQxZDEzMDE1MGM1YzRkZDk4MjRjYTM4M2Q0ZjU3ZDdh OGRmZjU0MzU1YzI2ZWU1ODFmYTViN2EwMTEwMTAxNTFjNzUxODFkMDExMzBkMjAwMTEyMjE3Zjdj OGZjYTE5DQowMTFlMDEwMTAxMTMxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxMjFjMDEwMTEwMTdjYTAxMWQxMDU3OTMwZDExMDEwMTAx MDEwMTAxMDEwMTAxMDExYzAxMTgxZTRhMjFkNzFkYTg5MTk5MGINCjY5NmFhODVmODdkY2ZiNTk2 NDYyMTUxODAxMWMxODAxMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxNmVmZjEzMTIwMTEwMTgxYzAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTEwMTAwMTAxMDEx YzEyNDAwMTEwMWUxMA0KYjM1MzkyODBjNGI4YmY0OWFiMjcxNjhkNmNlZjRkM2M5YTQ2ZmZjNTky NjRmNTJjMDEwZDAxMGQxMDEyMWMxYzE4MWMwMTE5MDExOTc1YmE4ZjYxMTcxMzEyMWMxYzFjMWMw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAw MDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTFjMTgxYzAxMDExMDExMjMwMTAxMWQ0ZmE1MTgxMTAxMDEwMTAxMDEwMTAxMDExYzAxMWMx MjAxMTc0YTFiYjQyMjkwNzE0MmU5NjE3MzkyYTg3M2VjZjkxNmFhNjExMTBkMDExYzE4MDEwMTE4 MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTFjMGQNCmE4NzcxMTEwMDEwZDE4MWMwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMTAxMzBkMWMxYzE4MWMwMTAxNDAxODBlM2RjNDQ5 M2Y3MDJlMmZiYjQ4MjEyZTdkNmFmNDg2Nzg1ZGU2YTRjZjhjDQo1YTcxNWExYjBlMjExMjBkMTIx YzFjMTgwZDEwMTMwMTY2MGQ3MGYyYTMwZTEzMGQwMTAxMDExYzFjMWMwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMQ0KMTgw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDEwMTAxMWMxMjEwMTMy ODAxMDExMDI4ZDQNCjFjMTMwMTAxMDEwMTAxMDEwMTAxMTIwMTEyMTMwMTEzODgxMThmMWI1MzVk NTkwMGQzOGU4MDNjZDU4NjRkMWI5ZTIyMWUxZDFjMWMxYzAxMDExMjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEx MjEzZTZiMjFlMTUwMTE4MTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDExODEwMGQwMTAxMTAwZDAxMTUxODAxOGQ5YTJkZTRiYTYyMjgzNzcyN2YyZGJjYjhl MTQ4NGU3ODczOTcyZmY1ZTYzNmRmOTZkYjI3MTMwZjFkMTIxYzAxMTgxMjEwMTAxYzE2MDE1YzYx ZDUNCjE3MTkxMjFjMDEwMTAxMWMxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExODAxMDEwMTE4MGQxMDBkYjgwMTEyMTg3YTU1MTIxODAx MDEwMTAxMDEwMTAxMDEwZDAxMGQxMTAxMTI1OTEzNWM1MQ0KNzA3ODg1YWY1ZGQzYWE0ZjAxM2Vk NmRhOGExNzFmMWQxYzFjMWMwMTAxMTIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMzMzYjIxZTExMDExYzE4 MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTIxYzAxMDEx MzFkMDEwMTFkDQo0YWRiZDQ0MzZiMzU0MDM4OTFjYzJiNTg2NTcwYmE4ZjZjNmNjYmZiYjQzNzM5 NjU1NWQ5NDkyZTAxMTYxMzE4MDExODEyMTgxYzE4MDEwZjI1YjQzNDUxMGQxOTEyMWMwMTAxMDEx YzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFj MDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMTgwMTAxMDExMjBkMGQxMjYyMDEwZTAxN2ZiYTFkMDEwMTAxMDEwMTAxMDEwMTAxMTIw MTEyMjAwMTFjNzkyMDczMDFmZmI2YzlmNzRlNDk0MTIxMDE4MzQ5YWJhYzJlMGUxMDFjMWMxODAx DQowMTEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMGQ5NWMzMjAyMDE4MTgxODFjMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwZDEwMGQxODE4MTAxMDBkMTMyMmE0YTVlZTkx M2RjYWQyYjEyODBkNTFmZjM1ODgxNzgyMzFlMzlkYmINCjc4OGVmMGE2YTNmODg1NDEwMTEzMGQw MTAxMGQxMDAxMDEwMTEwNzU3ZTdmYzQxYzJiMDExMDEyMWMxYzFjMTgwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwDQowMTAxMGQw MTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMTgxODE4MTgx MjEyNGIxOA0KMTkwMWI4OGYwZDAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxODBkMTIwMTQ0MTk0YTI1 YjJmYmQ5MDA1M2IyZmY2MDAxYTBkYTUyMDg3OTE1MTgwMTE4MTgwMTAxMTgwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDExMjg1YTgxMjEzMTgxODE4MWMwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDExYzFj MWMxYzFjMWMxYzFjMGQxYzE4MTIwMTAxMTIxYjQyYzQzYWUyZWU4OGE1YWQ5MDI0MDFhNjgzNzkw MTYxMWJjZWU0NjAwMTcwYTkzOGQwYTZjYmY3OWExZjE2MDExODAxMDExZDEwMDEwMTFkNTYyMw0K YmE3YTBmMTMxMDEwMTAxMjE4MWMxODE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExODBkMGQxYzAxMTgwZDdmMGQyMDAxN2Y2NjAx MTIwMTAxMDEwMTAxMDEwMTAxMDExNTAxMDEyMDFjDQpmMjBmNmE3NDk1ZjQ4ODBiNmIzOWVlNzE2 MWM2NzIyZjI5M2IxMjAxMDExODEyMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTBhNWFkMDExMjFj MTgxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwZDAxMDEx ZDAxMDENCjE5NTFkN2NjZDk1MWE1ODY2Y2Q1N2EzNDJmYWQ1MTNiMWYxMDU4YjJhODE1MjUzNTM3 NGZmNmNjYWJiNmNlMGUyMTAxMDEwMTAxMWQxMjAxMTMyYzIzN2MyZDIyMDEwZDAxMjAxYzAxMDEw MTE4MTgwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMTgxZDEwMWMwMTFjMTBhMTEwMTgxODc5NjAwMTIwMDEwMTAxMDEwMTAxMDEw MTAxMWYwMTAxMGUxODc0M2I2NjQ0NzcwNWIxYzk5MzY3MzAzZmRhZThkZDUwYWMyZTAxMDENCjAx MTgwZDFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDExODE1ZTEzYTAxMWMwMTFjMTgxYzAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMTMwMTE4MTkyMDEwN2Q1NWFlZWVjNTI0 MzgzY2NiNjY1OTNhNzM0MDFlNzUzYjBmMTFiZg0KMjIxOTEwMjVjNWNmYjAzM2I4ZDFmZjEzMWQx ODAxMDEwMTBkMTgwMTFmNDA3YzU5NjEyMTE3MGQxMjAxMDEwMTAxMDExYzE4MWMwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDINCjAwMDAwNTAwMDEw MTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMGQx MjE4DQoxNTE2YjcyMDAxMDE2MTI3MDExMDAxMDEwMTAxMDEwMTAxMDEwMTFjMTIwZDE4MTA1ODIy MmQ1MDcxYzZkZTFhNzM2NmE2ODI3OGY5OWVkMmY3MWYwZDAxMDExODEyMDEwMTFjMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMx YzFjMWMxYzFjMTI3ODg5MTAwMTAxMDExODFjMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MTMxMjAxMDEwMTAxMDEwMTAxMWYxZDFjMWNmMmEyN2NlZTUzNjljZjg3Y2Y2MTZhYmY1OTYyMWUx ZjFiMTExMjBkMTMwMTAxMTMxZWQyMzUyYWU1N2RmMWE4MjAwMTAxMTkwMTIwMTkwMTE2DQo0MTIz NDJiODI1MTExMDE4MWMxODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTE4MDEwMTBkMTAxMjEyMWQ4ZDE4MDExZDQ0 MjcwMTE1MDEwMTAxMDEwMTAxMDEwMTAxMWMNCjEyMTIxYzBkMTYyNzFmNjNkYWFlNmIwYzJlNmE1 YzIyYWVmOWUyZTIwMDc0MTMxYzAxMTgxMjAxMDExYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxYzEyNzg4OTEw MDEwMTAxMTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTE4MGQxMjE4MGQwZDEyMDEw MQ0KYjgwMTFlOGNkZWM2NzA5MTNhYjJjYjI3MzU3Yzc0NGIxNjFmMTkxOTExMGQwMTBlMWMwMTAx MTU3ZWJhNWVjZWNhZjFmZjExMTIxYzEyMWQwZjFjMjcwMWJmNGE1MTIyMWUxMDE4MWMwMTE4MDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDExMDAxMDEwZDFkMTIwMTAxNTkwMTFjMTFiODYyMDEyMDAxMDEwMTAxMDEw MTAxMDExYzFjMTgxODAxMTIxYjI2NjJhMzdiZGU1MmJkYjc3ZjgxNmQyMTdiZTk2MQ0KYTk2MjEx MGQwMTFjMTgwMTAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDExYzFjMWMxYzFjMWMxYzFjMWMxMjc4ODkxMDAxMDEwMTE4MWMwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwZDFkMWMwMTBkMTAxYzU4MDExMzdkZmZjYjkyZDc3MDg1 NGQyNDAxY2Y2NTFkMjEyMTIxMTYwZTEzDQoxMjFjMjA3NTFlMDExMjEzN2E4NmRhMzdhM2U3YzMx NTE4MDEwMTE5MDEyMjAxZDc0ZjM1MjYxYjEyMDEwMTAxMDExYzAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTFjMDIwMDAwMDUw MDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTEyMDEN CjFjMTAxMDE4MTIxZDdjMDEwMTE1NTA1NjAxMTMwMTAxMDEwMTAxMDEwMTAxMTgxYzE4MTgwMTE4 MTkyNjExZDQ3Mzc4NDhhNDcyYzUzM2M0ZTMzMDVkNDJiNjAxMWUxZDFjMWMxYzAxMDExMjAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMx YzFjMWMxYzFjMWMxYzEyNzg4OTEwMDEwMTAxMTgxYw0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTFjMTAxMjAxMDExZDE1MGQwMTIxYTFjNjIzYTRiZjUyM2RhYzhmYmNkYTlkMTJiODIyNjIy MTE3MTgwMTAxMWMxODAxMTgxMjFkMDExZmYxOGY0Y2EzMmEzNjEyMTgwMTU4MDENCjAxMTY2MGFi MmQ2MTFiMWQwMTAxMWMwMTAxMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTIxMDFjMWMxMTJjOTkxZDAx MGQyNjJjMTgxMzAxMDEwMTAxMDEwMQ0KMDEwMTE4MTgxODFjMDExODE2MjIwMWQ0ZGU5NmQ3Mjk4 YzQ4MzczZTJlMzdmYTRiNmZhMTFlMWQxYzFjMWMwMTAxMTIwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMWMxMjc4 ODkxMDAxMDEwMTE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDEwMTAxMDEwZDE1DQox NTEwMTI3ZjQzOGM4MDg2MjM5NTg2ODVjYzIzMmVjYTNiMjU1NjFiMTAwMTAxMDExMDEzMDEwMTAx MWQwZTAxMDFmNjJlOTJiY2VhODUxYzFjMTIxYjFjMTgxNjJmN2Y0MjEzMTExMjAxMWMxMjFjMDEx YzAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTEwMTAwMTAxMWU2MjlhMTkxYzEwMmI1ODBkMTUwMTAxMDEw MTAxMDEwMTAxMTgxODE4MWMwMTBkNzU3NDBmYTZlNmFjNzhmN2Q0NDlhZTQ0DQowMThlZTBjY2Q2 MWYxMTBkMDExYzE4MDEwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzFjMTI3ODg5MTAwMTAxMDExODFjMDEw MTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzAxMDExYzFkMTIwMTAxMTJmMjk2MjQzYzJmNzBiZjc4 YTViYWJhNzk1ODI2NzQyMDE3MGQNCjAxMDExODFkMWQxMDEyMjAxMjEwMTkxZjAxYjFkNDY4ODhm YjM2MTgwMTEyMDExNTFmNjNkNTU3MmMyMDE1MTIxYzEyMGQxYzAxMTgwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDExYzAyMDAw MDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMWMwZDEwMWMwMTIwMmNiMjFlMTIxMzJjMTcxYzFkMDEwMTAxMDEwMTAxMDEwMTE4MTgxODE4 MWMxZDI1N2QwMTU1OGMwMDk2Yzk4YTY2NTcwMTFlNWFiMmFlZjdmMjEzMWMwMTE4MTIwMTAxMWMw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEx YzFjMWMxYzFjMWMxYzFjMWMxMjc4ODkxMDAxDQowMTAxMTgxYzAxMDEwMTAxMDEwMTAxMDEwMTFj MWMxODE4MTgxMDAxMGQxNzE4MDExOTUxNDJlNmEyNGY2YWUzODBlMzQ3YjQyNzFiNTAyYzFkMTIx MDEyMWMxODEwMTAxODAxMDExZDAxMDEwMTEyMDExOWRkOWY0YWI5NzcxMw0KMDExNTAxMTMyODdm N2E2NjAxMTcxMDFjMDExMjEyMDEwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTIxODEyMTAwZDFjMGQxMTk1 MTAxMjIwMWIwZDAxMTIwMTAxDQowMTAxMDEwMTAxMDExODE4MTgxODE4MTM1NjJlMmMzNWIyOTI2 OTBjYWYzMDUyMjYwMTZmYWRiM2NkNjEwZDAxMDExODEyMDEwMTFjMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzFj MTI3ODg5MTAwMTAxMDExODFjMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzE4MTgxODFkMDENCjBkMWYx NTBlNDdjNWQ0NWI2NjUyOTE0OTk1Yjc4ZjI3MWUxNTE2MWUwMTBkMDEwMTAxMDEwMTAxMDEwMTFj MTUxYzE5MWMwMTBmMjA0ZDViNjZiOWMzMWUxMjJjMDE3YTU3NDI2MzNiMTcxYzE4MDEwMTFjMTgw MTAxMTgwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMGQxMzE3MWVhODc1MTAwMTU4MDEwMTBkMTgx YzAxMDEwMTAxMDEwMTAxMDExMDAxMWMxNTBlNjYxMDhkOTVjOTIzNzYNCmUxNmQwYWRkODdkMDVj OTllMDIyMWQwZDFjMWMxODE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTAxNzg4MjAxMDExMjAxMTIx YzAxMDEwMTFjMDEwMTIwMDEwMTE1MDEwMTFkMTIxNzAxMDEwMTE4NDg4MzkzNGQ4NjU3NWM4NjU1 MTYxNjFkMGUxNjE5MTMxOA0KMTgxZDAxMDEwMTAxMDEwMTAxMDExODAxMWQxZjEyMWQxNzAxNzdh Y2FiY2RkZTAxMTAwMTdkMjM0MjU3MmIyMDE4MDExMjE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMWMw MjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDExYzFjMWMxODEyMTAxMzE1MmYyMTEwMDEyMTEzMDExNTE4MWMwMTAxMDEwMTAxMDExYzAx MTAwMTAxMTIxZDlkMTk1Y2RiMDA1YzhhNTIwMTU5M2NjZTAyZDk1ZDA3NTExZDBkMWMxYzE4MTgx YzAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMWMxYzFjMWMxYzFjMWMxYzAxMDENCjUzNjUxYzAxMGQwMTBkMTgwMTAxMWMxYzFjMDEwZDAx MTgxNTBkMTIwZDAxMDE3NTIyMTI3ZjUzNzc2YjIzNTBiN2RlNWMxMzE2MWUwZDE1MTExNTE4MDEw MTFjMDEwMTAxMDEwMTAxMDEwMTAxMDExODEzMDExODE1MDFkNTcxDQo5NmM4M2QwZDEwMWRjNDZh NTk0MTFjMDEwMTEwMTIxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMQ0K MTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTE4MTgxMjEyMTIxMjE4 MTg3MzJiMTIwMTFiMTENCjAxMTIxODFjMDEwMTAxMDEwMTAxMTgwMTBkMDEwMTE4MGQ5ZDFkN2Yz N2QwYWUzMmYxNTRlYTQ2MzA5Y2M5YTBjMjE5MWQwZDFjMWMxODE4MWMwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFj MWMxYzAxNTM2NTFjMDEwZDAxMGQxODAxMDExYzE4MWMwMTAxMTIwMTAxMTMyMA0KMTgwMTJiMWMw MThkNDk2Yzk1YjM3Y2U2Y2U5MzJlMTIwZjlkMWQxMDBkMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwZDAxMTIxZDAxMTIyMDBkZjI5ODgxZDBlNjFlMTAyMjVjYTMyZTFiMWMwMTE4MTIxMjE4MWMw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzE4MTIwZDEyMTgxYzAxNzM2MTIwMDExOTBlMDEw MTE4MWMwMTAxMDEwMTAxMDEwMTAxMTIwMTEyMTAxNTJlM2IyNw0KOTQ0NWMxMDBlOGZlMDA5YjAw YjVhOWFlNGU1NzFkMGQxYzFjMTgxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDEwMTc4ODIwMTAxMGQw MTEyMWMwMTAxMDExYzAxMDEwMTE1MDEwMTEzMTcxYzBkMDExODY2OTY1ZDgzMjUxMmRiMzlkNTAx MjAwZTAxMGQxMTFkDQoxYzAxMWMxODFjMDEwMTAxMDEwMTAxMDEwMTAxMGQxODBkMTAwZDFkMTUx ZDU2ZDM4MWY4YWQxMjlkZDVjYTc0NzUyMDEzMTUxZDFjMTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTE4MTIwZDEyMTgxODVmNGExZjBkMTYxYjFjMDExODFjMDEwMTAxMDEwMTAx MWMwMTEyMTgwZDBkMWQzNDdkMTVkM2QxODFkOGQ5MjkwNmY3MjliZWZlZTJmNDU4MWQwZDFjMWMx ODE4DQoxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTFjMWMxYzFjMWMxYw0KMWMxYzAxMDE3OGJmMDEwMTEyMDExODAxMDEwMTAxMDEwMTAx MDExMTE4MDEyMDEzMDExMjE3OGZjNmRiYzM2NzQxNjc5ZTI0MTcxYzE2MmIxMTAxMGUxZDAxMDEx ODBkMTIxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxODEwMTINCjFjMTgxZDUzOGFlZWRhMjBiYTg5 NTczYjEwMDEwMTEyMTAwZDE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwDQowMTAx MGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxMjBk MGQxMDEwNTVkNw0KMTMxODFlMGUwMTE4MTgxYzAxMDEwMTAxMDEwMTEyMDExODFjMTgwMTAxNDAy Yzc0YTBmYmI2MDBlZGJkZWQwMDAwMDIwNTAyOGUyMDFkMGQxYzFjMTgxODFjMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFj MWMxYzFjMDEwMTc4ODIwMTAxMTIwMTEyMWMwMTAxMDEwMTAxMDEwMTFjDQoxMjEwMTAwMTAxMTU2 MTgxM2RlM2Q3YzRiN2NjNTAwMTIwMmIxODEzMTcwMTE1MGQwMTAxMDExODFjMDEwMTAxMDEwMTAx MDEwMTAxMDEwZDE4MWMyMDFkMDExMDAxNzMzMjU0MzhkNWExMjgzNDJjMTgwMTFjMTIxMjE4MWMx Yw0KMDEwMTAxMDEwMTFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgxODE4MTgxMjBkMTAxZGNiYmExYzFjMTEx NTAxMTMxODFjMDEwMTAxMDEwMTAxMTIwMTFjMTgxMjAxDQowMTYwMmIxNmIzOGU5N2YwZDQyMjVi MDgwNjFhMDAwOWEwMGYxZDBkMWMxYzE4MTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzE4MDE5MDU1MTgw MTEwMWMxMDEyMWMxYzE4MTIxODFjMDEwMTEyMTEwMTAxNTY1MTk1Y2ViMjI3ZjJlZTI0M2IxODEw M2IxZjAxMTMNCjE4MWQxMDEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMjAxMjAxMTEx MzFjMTcxMmJjZjEwNzZjMzY2MzJiMGUxMjAxMTMwZTE1MTgwMTFjMDEwMTAxMDEwMTAxMWMwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTEwMTAxMjE4MTIwZDEwMWRhNWNjMWQyMDFiMTExYzE5MTgxYzAxMDEwMTAx MDEwMTE4MDExYzBkMTMxYzE4ZjIyZTBkOGUwNzMzMGI2N2UzNjgwNDQ1MDAwMDVhZmEyMjFkMGQN CjFjMWMxODE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDExYzFjDQoxYzFjMWMxYzFjMWMwZDE4Mzg1ZjBkMTgxMzEyMTMxMDEyMTIwZDEw MGQxMjFiMDExZDE5MDExN2EzZTE3MmRmOWRhZGRjOTgwMTAxYjgwMTAxMDEwMTBkMDExMDBkMGQx MjE4MWMxYzFjMWMwMTAxMDEwMTAxMDEwMTAxMDExNQ0KMDEwMTEwMTIwMTE3MTAxOTk0MDBlZDgy OGQyMDEwMDEwMTEyMTMxMjAxMDEwMTAxMDEwMTAxMDExYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDINCjAwMDAwNTAw MDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFj MTgxODEyDQowZDBkYjEzYTE4MDE2MTAxMTcxNzAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxODExMTIw MTYxNDA2MmFhYzliMTA1MzI1NGFmYmQ5N2U3Y2UzNWY0MGYxMTEzMTgwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFj MWMxYzFjMWMxYzAxMWM5YTZhMTIwMTAxMTAxNjFjMDExYzAxMDENCjFjMDEwMTAxMTUxYzExMjMz M2Y0YjNkNzI4OTI2NzFkMTA4ZjAxMDExYzE4MTgxODFjMWMxODE4MTgxYzFjMDEwMTAxMDEwMTAx MDEwMTAxMWMxYzAxMDEwMTAxMWMxYzFjMWMxZDFjOGIwNTA1YmE3ZDEyMTkxNTAxMDEwMTEyDQox ODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzE4MTgxMjBkMGQzYWQ0MTgw MWNhMDExNTEwMDEwMTAxMDEwMTAxMDEwMTFjMDENCjE4MWMxNTFjMDEzNDI3NzU2ZjgxN2YyYWM4 MzBmN2JmNTY5ZTM4OTUzZTBmMjAxMDFjMDEwMTFjMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxNTE5ZTEy NDE2MGQxMDEwMDEwMTEyMWQxODEyMTUxNTE3MTUxZjAxZDUzYzgwYmEyYzkzNDNhYjBmMTk2MjAx MTIxOA0KMTgxODE4MTgxODE4MTgxODFjMWMwMTAxMDEwMTAxMDEwMTAxMDExYzE4MTIxYzFjMWMx YzE4MTgxODE4MWU0MDk3MDA5YjdhNzUwMTE3MTAwMTAxMWMxMjE4MDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxODE4MTIwZDBkMmY3ZTEyMWM0YTBkMTMxYzAxMDEwMTAx MDEwMTAxMDExODAxMTgwMTFkMWMwMWYyNTg5ZGE3YzA3YWYwZDc4ZmM0MDJlOGY3ZjZjYg0KYWVm MjEzMGQwMTAxMDExODE4MTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDExYzFjMWMxYzFjMWMxYzFjMWMxNzRjZGIyZDc1MDEwMTAxMTgxMzBk MDEwMTEwMTUxMDAxMTAzYjU5ZmZjNGI4ODVlOGQ0MTYxMzAxMTYxMDEyMTgwMTAxMDEwMTAxMDEx YzFjMWMxYzAxMDEwMTAxMDEwMTAxMWMxODEyDQoxMDFkMGQwZDBkMGQwZDBkMTIxMjAxNTczMWVj NzIyMDE4MjAxZDE4MDEwMTFjMTIxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTFjMDIwMDAw MDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFj MWMNCjFjMTgxODEyMTIxMmNiNjkwZDEyNmExNzE1MWMwMTAxMDEwMTAxMDEwMTAxMWMxYzEyMDEx ZDEyMWMyZWYyNjI5NmZhMzNmYzgyNjUzZmJhYzNmMGI2NGNhMjYwMTAxODAxMDExYzEyMTIxMjAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFj MWMxYzFjMWMxYzFjMWMwMTI3MDBmZDYxMWYwMTFjMGQyMA0KMTAwMTAxMTgxMjEzMDE1ODc5YTJk MjQzODhhNmQwYmNmMjU4MGQ0MTAxMjAxZDBkMTgwMTAxMDEwMTFjMWMxYzFjMDEwMTAxMDEwMTFj MWMxYzE4MGQxMDEzMTUxMzEzMTMxMzFkMWQxZDFkMDEyYjVmM2FmMjAxMTIxNjFjMDENCjAxMDEx ODE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMTgxODE4MTgxMjEyNzM2 NTEyMWNjYzBlMTUxODAxMDEwMTAxMDEwMQ0KMDEwMTAxMWMwZDAxMTMxZDBkNjE2MDAxNmMwM2Vi YzdkNTlkOTkzOGEwOWIwNGY1YmIwZTBkMTgwMTAxMTgxMjBkMTIwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMTIz ODA5NmQxMzAxMTMxZTEwMTMwMTAxMTEyMDFjMWQxMzY2ODM5MGFhODU5MTgyZTEwMTBmMTgwMTJl DQowMTAxMTExNTFkMTIxODEyMGQxMDFjMWMxYzFjMWMxYzE4MTgxODE4MTgxMjBkMWQxNTIwMTEy MDIwMjAxNTE1MTMxMzExMDEwMTE1MDExZTBlMTgwMTAxMDEwMTE4MTgwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgxODE4MTgxODE4MTgxODZhODkxODAxNzAyMDBkMTgwMTAx MDEwMTAxMDEwMTAxMDExYzEwMDExMzEzMTJmMmYyMDE5ZTA1MDBmZWE5ZWVlMGMxDQo5ZjA4ZTg4 YTZjMTIxMjE4MDEwMTE4MTIxMjE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzE1ZjA4NjdmMTAwMTRiMTExYzBk MDEwMTFlMDEwMTEzZDdhODZmNGFlM2FiZTM4ZDFlMjQwZDAxMGYwMTBkMTYxMDBkMTgxYzAxMDEx YzE4MTgxODE4MTIxMjEyMTIwZDEyMTINCjEyMTIwZDFkMTMxNTIwMjAxNTE1MTMxZDFkMTAxMTEy MDExMjAxMWIxNTAxMDEwMTAxMWMxYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDExYzAy MDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTE4MTgxODE4MTgxODE4MThiNzY1MWQwMTk5MWQxMjEwMDEwMTAxMDEwMTAxMDEwMTAxMWMx ZDAxMWQwZDAxMjczYjBlNzcwMDA4MDA0NTAwMTQwYzE0YmUzY2RjNTMyMDBkMTgxYzFjMTgxMjE4 MWMwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDExYzFjMWMxYzFjMWMxYzFjMDFiYmI4MDE1NjE1DQoxYjE1MWMxZDAxMWMyMDAxMThiY2ZmNWFj ZmFhODNlZTUxMWQxMzAxMGU3NTIwMTMwMTE5MDEwMTAxMDEwMTAxMDEwMTEyMTIwZDBkMGQxMDEw MTAwZDEyMTIxMjBkMTAxZDEzMWQxZDEwMGQxMjE4MTgxYzAxMTUxZTU4MDExYw0KMDExZDFjMWMx YzFjMDEwMTAxMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgxODE4MTgxODE4MTgx ODgyNzAxZTAxYWQxZDBkMTUwMTAxDQowMTAxMDEwMTAxMDEwMTE4MTMwMTBkMWMwMTU2NDAyNWU2 YmUwOTAwZmEwMDAzMDAwODA0NDZkNmRhMTgwZDEyMWMxYzEyMTIxYzAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMx YzAxNjEwMTE1MjEwZDAxMmMwMTE1MTgwZDE3MTg2MTQ5NzAzOGNjNzBhZGI4MDExODE2MTINCjBk MDEwMTBkMTAwMTBkMGQxMDFkMWQxZDEwMTAwZDBkMGQxMDFkMWQxZDEzMGQwZDEyMTIxMjBkMTAx MDEyMTIxODFjMDEwMTAxMDExYzAxMDEwZDFjMWMwMTEyMTgxMjE4MWMwMTAxMDExODAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTBkMGQwZDE4MWMxYzBkMWRjNDczMGUxYzg1MTYwMTE1 MDEwMTAxMWMxODFjMWMwMTAxMTIxMDEyMDEwMTEyMTU3NDEyNzcwMDAyMDMNCjA5MDQwMDA2ZWQw MzE0MDM3ZTBkMTAxMjFjMWMxODE4MTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTI1MWMxNTBmMWQxNTE3 MjAwMTUwMDExMjM1NzhiMzgwZDdiN2FkNGExNzAxMWQxODEyMGQwZDEwMGQwZDEyMGQwZDBkMGQw ZDBkMGQwZDBkMGQwZDBkMGQwZA0KMGQwZDE4MTgxODE4MTgxODE4MTgxYzFjMWMxYzFjMWMxYzFj MWMxYzFjMWMxYzFjMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDExODEyMGQxMjFjMWMxODBkNmFiYTEzMWRlNTBmMDEwZDAxMDEwMTFjMTgxYzFjMDEw MTE4MTIxODAxMDExODFkNjAxMjNmMDAwMjA0MDMwMDA2ZmFiZDAwMDMwOGNiMTcxMDEyMWMxYzE4 MTgxODFjMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMWMxYzFjMWMxYzFjMWMxYzFmMTMNCjFjMGY0MTEyMDExODAxMGYwMTNiN2FiZjZmNmI0 ODU1NzhiZjEzMDEwMTFmMTMxMzEzMTMxZDFkMWQxZDBkMGQwZDBkMGQwZDBkMGQxZDFkMTAwZDEy MTgxODFjMTgxODE4MTgxODE4MTgxODFjMWMxYzFjMWMxYzFjMWMxYzFjDQoxYzFjMWMxYzFjMWMw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQw MQ0KMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgxMjEyMWMw MTFjMThkN2EzMTgxZjg3MjYNCjAxMWMwMTAxMDExYzFjMWMxYzAxMDEwMTAxMWMxYzFjMTgxODQw MGRiMjAwMDMwNjAzMDAwMzAwMDJmM2Y5MDM5YTEwMTAxMjFjMWMxODE4MTgxYzAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMx YzFjMWMwZDAxMTgyNTU2NzUxMDFjMDEyMTFkNGI3ZmNlNzg1MDQ5ZGFiMTlkMDExZg0KMWIwMTE1 MTMxMDEyMTIxMjBkMGQxMjEyMTIxMjEyMTIxMjEyMGQwZDBkMTIxMjE4MTgxODE4MTgxODE4MTgx ODE4MTgxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTIxMjE4MDEwMTAxNTk3YTAxNzU4MDI2 MDEwZDAxMDExYzFjMWMxYzFjMWMwMTAxMDEwMTE4MTIxODFjNjExMA0KNzcwMDAzMDYwNDAwOWI5 YzA2YjBmYTA5YjMxZDEwMTIxYzFjMTgxODE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDEwMTExMDEwMTU4 MDEwMTE4MDE1MWJiYWYzMTdhMTg3Nzc5MGUwMTFkNzQyMTAxMjAxNTEwMTgxYzE4MTIwZDE4MTgx ODE4MTgxODE4MTgwMTAxDQowMTE4MTIwZDEwMWQxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFj MWMxYzFjMWMxYzFjMWMxYzFjMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTEyMTIxODAxMDEwMTU3NjMwMTc1Y2U0MTAxMjAxODE4MWMxYzFjMWMx YzFjMDEwMTAxMDExODBkMTIxMjdhMTMzNjAzMDNmYTI5MDYzNzIwMDEwZTY4MDBhZjJiMTAxMjFj MWMxODE4DQoxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTFjMWMxYzFjMWMxYw0KMWMxYzE4NDE0MTAxMDE3NTAxMWUxZDIyODdhMjJlMDFi MWM1MjYxYzEzMWYxNzBkMDExNzFlMGUyMDFkMTAxZDEzMTUxODE4MTgxODE4MTgxODE4MDEwMTAx MWMxODBkMTAxMDFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMNCjFjMWMxYzFjMWMxYzFjMWMx YzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwDQow MTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTE4MTIx MjFjMDExYzE4NDQ1Nw0KMDExZmM1NTYwMTExMTIxMjE4MWMxYzFjMWMxODFjMDEwMTAxMWMxMjEw MTNhMzExOTMwOTE0MDQwYjI5YjMxNzFmMWU4NjAwYzAyNTEwMTIxYzFjMTgxODE4MWMwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMx YzFjMWMxYzFjMDEyYjI3MWUxZTEyMDEwMTIyNWVkZjZlNWE0ZDZlMmIxZDEzDQo0MTBmMTUwMTAx MTYyMDEzMWQwZDBkMGQxMDEwMWMxYzFjMWMxYzFjMWMxYzE4MTgxODFjMWMwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgxMjBkMTIxYzFjMTgwZDY2NjMwMTEz NTM0YjAxMTIwZDEyMTgxYzAxMWMxYzE4MTgxMjE4MDEwMTFjDQoxMzBlYTExZTM2MTQwNTA0MDYw MzVhNjIwMTAxN2ZlOTFhYmMxMDEyMWMxYzE4MTgxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMTE3NTFi MDEwZTY2NTBiNzMxYzRjYWIyNzg0MDYwMTgwMTAxMDExODE2MTUxZjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDExMjE4MTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFj MWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTBkMGQwZDE4MWMxYzBkMWQ2NjYzMDExODc4MjIxYzAxMTAwZDE4MWMw MTFjMWMxODE4MGQwZDFjMDEwMTE1MWI4ZDFmYzMwMDA1ZmEwNDAwYTQ2MTAxMjY0YmZkMDA2ZDEw MTINCjFjMWMxODE4MTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDExYzFjDQoxYzFjMWMxYzFjMWMwMTAxMGQxZDE4ZTFkOGE0ZjRjZDAxYjQ1 NTFjMTAwZDExMTcxOTE4MTAxNTAxMTIwMTAxMDExYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYw0KMWMxYzFjMWMxYzFjMWMxYzFjMWMx YzFjMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDINCjAwMDAw NTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEx ODAxMDEwMTBkDQoxNTEzNTc0MjE3MTA3NzIxMDExMzAxMGQxMDFjMTgxNTE1MGQxMTFjMjAxMjAx MTgwMTE3ODgwZDhjMDkwOTAwMjkwMGZlNGIxZTEzMDFkYjA1ZWYxMDBkMWMwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxOWQxNTFkMWI3MWVlODc0OTBiOTNiNDdmMDENCjFkMTIxZDFkMTAwZDEy MWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgxYzAxMDExMDEzMWQ2MWEx MWIwMTNhNTgwMTEyMWMwZDEyMDExYzE1MTcyMDE1MTINCjFlMTAxMjEzMDExMDQwMWI0OTAwMTQw MGI5MDVmOTYxMTA0NDBmN2IwMzMwNzUyMDFjMDExZDE1MTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTIw MDE1ODJiNWQzMzU1OTZkMmZmNzkxMzIwMjAxYzBkMGQxMjEyMTgxYzFjMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMTgwMTFjMTAxZDBkZjJhNjFmMDFiZjBkMDExYzAxMTgw ZDBkMWQxMTExMTUxMDEwMTkxZDFkMTkxODAxNGI3NDMzMDhmYzA0ZTkwOTA5ZGZkZWE0ZjdjMQ0K NGUyZTE5MTMwMTAxMTIwZDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMTExMjAxYjQzZmRiNWY3Y2FiMmJh NjEzMDExMTBlMTcxYzFjMWMxYzFjMWMxYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTFjMDIw MDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMWMNCjEyMWMxODEwMTAxYzNiMjMxNTAxODkwMTFjMjAwMTE4MTUwZTFlMTcxMDFjMWMwZDFm MTgxZDIxMTMwMTU2NDRhNWIwMDYwMDAwMDAxNDBiMDUwMDAwOTc5NTE2MWMxMjBkMWMwMTAxMDEx MjAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMWY5ZWZkNmVhMzJjMWIxOA0KMTAwMTJiMTgwZDI1MDEwMTAx MDEwMTFjMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMTIxODEyMTAwZDAx MTkzNTIxMDFiZjFjMGUyMDBkMWQyMDE3MTExZA0KMTgwMTAxMWMxMTAxMTIyMTExMGQxOWJjYzVj ZDE0ZmEyOTA4ZmNmYzAyYmViZTFhM2YwMTEwMTAwZDE4MWMxYzEyMTAwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTEyYjFiMzc1MWUwMTAxNTgwMTAxNDAxYzAxMmMwMTAxMDEwMTAxMWMxYzE4MDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExODEyMTgxODEwMGQwMTE2MzZiODAxNjUxNTBlMDEx OTExMTAwZDE4MDExODFkMWMwMTE1MDExODFiMjAxMTEwMjNkYmI5MDIwMDA5MDAwNWZhDQowMDE0 M2NmNzhjMGQxZjEwMDEwMTBkMWQxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTIwMWQwMTFiMTMwZDAxMWYx ZTFjMTAxMTAxMTEwMTE5MDEwMTAxMDEwMTFjMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEx YzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMTgxMjFjMWMwZDBkMWMxNmMzOWQwMWIxMTMxNTE3MWYxNTBkMGQxODAxMWMxZDBk MDExMTBkMGQwZTEwMWUxMThmYmIwMGJkMDAwYTA5MDAwNzBjMGI1YmY3YzUwMTE1MWQxMjFjMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTExMTkwMTRiDQowMTFjMjAwMTIwMTUwMTE3MTgxZDAx MDEwMTAxMWMxYzFjMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAx MTgwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMjEyMDExYzBk MGQxYzAxYjQxODFjOTAxZDBlNGYwZDE4DQoxMDE3MTExODAxMDExNTE4MWUxNzE1MjAxYzFlNjE2 YTZiMDBjOWMxOTM5OTliMDAxNGJkMDAwMGUwY2UwMTE3MjUxZjAxMDExMDI1MDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTE1MDEwMTAxMDEwMTE2MDEwMTBkMWQxMjAxMTIxNTAxMWMxYzFjMWMxYzFjMWMxYzAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMWUxNDAxYzlkMjYw MTFmMTIwMTFkMDExOTAxMDExMzIwMjIwMTBkNDE0MDdlYzVlZTA2ZjAwYmMyZjQNCjM1NmUzZTAy MDAwMDA0MDBmMTg2MmYxNTAxMDE0MTFiMTkwMTU4MGQwMTAxMDEwMTBkMTIwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMx YzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMGRjZTJjMWYyYjg4NjIwMTUwMjAxMjAxMTExNzIw MWMxOTAxMTc2NzM3N2IzZjJlYmM3NmYwYzFmZDMyODI2NDZkOWY3NmZlMDAwMGE3YThiMmJhMjIx NzAxMDEwZTFkMDEwMQ0KMDEyMDEwMTIxMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMNCjFjMWMxYzFjMWMxYzAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAx MGQwMQ0KMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFj MWMxYzFjMWMxMDZjMjE0MTU3MGQNCjAxMTUyMDAxMTIxZTAxNTY1OTUyZTVmNWY1YWMxYjFiODI2 YmI1MDAwMGZjZWRjODg5Y2U1MWI1MDBmY2ZkOWJlNDdkN2VhYzIzMDExNTc1MDExOTBlMDExYzBk MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDEzOTI4MGU1 MjIxNjAxYjAxMTM1NjgyMzZlMzkwOTM2ZWEzNjVmNmUzYWFmM2ZhMDNmYg0KMDBmYWQ4MDZjZDAy ZWZhYzhiMmY2OWM4YWE0OTcxNWZmNjUyMDExMTE2MDEyNTEzMWMwMTAxMDExYzFjMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMx YzFjMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzE1ODZjZGIwYzYxODExMDFjZWQ2YzdmM2Iw OTdhMDlmZGMyOWY5MDcwNjAwMGJmYTBiMDAwNWMwMzJkOGQ3NjE3Yzk5YmJjM2NjNjgyOTMyMGJi YmRjNDhiNzAxDQoxNjBlMTAwMTAxMWQxODFjMGQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAw DQowMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFj MWMxYzFjMWMxYzFjMDFkMw0KMDQyOWViYzJiOWQ4MDIwMDQ1MGMwNTAwMDAwMDAwZGM2ZDZmM2Nl MWQ3NjE1MmRkYzBiZTAwMDBlZWU4YjBlMjAwMDAwNzA2MDAxNDFhMDkzOGJhODQ2OTBkMGQxNTAx MDExYzAxMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzEwOWUw YzAwMDg1ZGE3ZjkzMGVlZDNiYmRlOGM2ZGNlODBiYmNlZDQ4M2RkDQpiYjZiODBlNjk4NDZhOTlj YjVmYTFhMDAwOWMwMDAwNTAwMmEzZDg1YTk5ZjhmODM1ZjAxNTgxMjAxMDEwMTAxMTIxODAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMx YzFjMWMxYzFjMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTJmZWIwNTAwYjc0YTM1YmEyMTE1 MmMxMTQxOTk0YjFmMGQxNTE3ZjI0YTUxNTYxYzE1MDFhZjJkYTQ0ZGM3YzlkYWYwZGY3NjAwMzZm ODRiMzYNCmE1ODA5ODdmNWI3MzAxMDExMDE2MWYxMTE1MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDINCjAw MDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MWMxYzFjMWMxYzFjDQoxYzFjMGUwMTUyNGNkYWI1YTMyYjE4M2IxOTFmMWUxZTczMjUyYzExMTgx MzJjM2I0YjIxMDE5ZDYyOGU5M2UwYjE4YzU3ZGI1YTNmZjcwMDg0OWEzY2NjNWFjY2Y0NjhhNThl OWQxMjYwMDEwMTc1MDE0NDFjMWMxYzFjMWMxYw0KMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMzBkMDEwMTE4MDEwMTE4 MDExODBkMTgwMTAxMTgwZDAxMDEwMTAxMDEwMTFjMWMwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMw MTFkMWRiNGE4MzE3MjQyNjAyNTAxMTYxZTAxY2ExOTEzMTgNCjAxMDExMDIwMjAxMzFjMDExNjZj YzYwMGVlN2JkNTU0YWU3Y2VkZDhkYjc0OTk4NmNmMjg1ZjNhNmJhZWM1M2YwMTU4NTgwMTUxMDEx YzFjMWMxYzFjMWMxYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMTgxNTEyMDExZDAxMDEwMTAxMDExODE4MDEx YzAxMDEwMTAxMDEwMTFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMTAxYzAxMDEyZjUxM2ZhMzAx MTkxYzJjMDEwMTQxMDExODBkMTAxMjAxMDEwMTE4MWI3NTU4ZjYzMWVkM2U2MGE2Y2RjOGFiOWNh Yw0KYTc4ZjExNDFiMDZkM2IyM2JiZjQ2MDgwMjQxODI1MTgwMTU2MWMxYzFjMWMxYzFjMWMxYzAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTBkMGQwMTEyMDENCjAxMWMxYzEzMGUxNzEwMDEwMTAxMWMxYzAxMDEwMTAxMDExYzAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTFj MDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTFjMWMNCjFjMWMxYzFjMWMxYzFkMTUwMTJjNzRiYzQyMzUwMTFiMTI1ODAxMTAxNjAxMTAx NTE3MjAxMDFjMTgxMjAxMjAwMWVlMzlhOTllMmQ0MmIwYTdiMmViMzhiYjQ3MmMyODAxNGU4OTcz Yjg5MDZmODlkMmJhMDExOTAxMDExYzFjDQoxYzFjMWMxYzFjMWMwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExNTFjMDEwMTFj MDExYzAxMDEwMTE4MWMwMTEyMjAxODFjMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDEx ODAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMx YzFjMDExNzEyMjEwMTY1OGQ2NjdjNDEwMTE1MWQwZQ0KMGQyMDE4MTIwZDEwMGQxMjFjMDEwMTAx NzllMjNlOWYyZmJmODRiNjNiOTBmMzcxZjUyMDAxMDE1NjdjMzcxOTIzNWQ5MmQzYmE5YWU2MTgx MDBkMWMxYzFjMWMxYzFjMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMGQwMTAxMTAxNTEyMTIxYjEyMDEwMTFjMTgx ODEyMTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMTIyMDE4MTgyY2Q1 ZjI1MjM0MTcxMjEyMWYxYzEzMDEwMTAxMDExMjBkMWMwMTIwMTgwZWE5NzdhZjkwM2VkZGYzDQpi OGM2ZjRkOWQxYTMxZjE4MTgxZWEzOTYwMTU1MDE5Zjc3YjE0Yzg4MTA0YjFjMWMxYzFjMWMxYzFj MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDExOA0KMDExYzE1MWMwMTAxMDEwMTEwMTcxZDAxMDEwMTEyMTgxYzAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTE3MDEyNjBkMTAyZTg5NjFjYTIzMWQwMTE3MTIx NTAxMDEwMTFjMTgxMjE4MWMwMTIxMDFlOGNjZDZlNTg1NDNhMjNmNmRhODZmZDNjZTAxMTUwMTE5 MGQyMjNjYWI4OWNjYjMzZGJmYTgNCmFiMDExYzFjMWMxYzFjMWMxYzFjMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTBkMTgwMTBk MTAwMTAxMWYxZDAxMDEwMTEyMDEwMTEzMTIxODFjMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEw ZDAxMTgwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMx YzFjMWMxYzE4MTUxMjAxMTYwMTAxNTA1MjU3DQo1OTE3MTcxMjAxNTYwMTAxMWMxYzAxMDExYzE4 MWQxNzAxZWIyZGU3M2E4MjcxODZjZjgxNTIzZmRhODUxOTFkMWYwMTAxMjE1MTNmNzI3YTAxZGVh MjZhYjQ2NTFjMWMxYzFjMWMxYzFjMWMwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMDFjMDEwZDFkMDEyMTg4NmQ2NTE1MDEx MTI1MTEwMTEyMTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMGQxMzEw MTIxMzFmMjgyMzQyN2EwZTAxMGYwMTBkMDExODFkMDEwMTBkMTAwMTAxMjE4ZWM2ZTMNCjMzNDdk Yjk1M2ZhYzJmMzlhZWVlMTIxNzFlMWIxMTAxMTFkNzkxYmY4ZDI2NzhmMDg4ODFjYjE2MDExZjAx MDEwZTAxMTAxMDBkMTIxODAxMDEwMTE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDExMjE5MGUxMjYwMzhmMTAwMGJmMDZkOGYzNDFjMGQwMTAxMDEwMTEy MWMxYzEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTIwMTAxMTIxMDBkMGQxMzIyMzU1MTJmMWQy ZTAxMWQxZTE4MTIxZDAxMDExMjFjMTUyMTE4YTQ2YWIzNGI0OTljNGE5YWU0NDI5ODZiZTAxNTBk MTgxNzE2MTUxODBlNDc5ZQ0KNGJiZmE1YjNlZDU3ZWVhYjBkMTUwMTJjMDE1ODAxMDEwMTAxMWMx ODE4MTgxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMjE5 MWYwMTE1NDhlZjAwMGIwMDAyMDc5Nzk5MWYwMTE1MTINCjAxMTgxMjAxMDExYzAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAw MTAxMGQwMQ0KMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwZDAxMDEwMTEwMGQNCjFjMWMwZTI1Njk5ZDZlMDE1ODAxMTUwMTAxMWMwMTFj MTAxODAxMTEwMWU4YWVhZWI4YjJlOTcwZGQ4N2I4YmM4YmVhMTYxYzAxMGQxZjIxMTcwMTE5NzRl MzBlYzQ1MTMzZWJkNDlhOGQxMDIxMTAwMTJiMDEwMTAxMWMxYzE4DQoxMjEyMTgxYzAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWUxNzE3MjhiMmVjMGIw MzAwMDBhNTFlMWMxNzBkMDExYzFjMDEwMTFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTIwMTAx MWMxMjFjMDEwMTE4MDE0Nzg4YTE1MjAxMTExMjAxMDExMjAxMDExMjAxMWMwMQ0KMmM1YmQwNWRk YTY5OTQ3OGQxNjUyYjAxYWQ0NjM0MWYxMzFkMDEyMDJjMWYwMTU2M2JlM2I3MjI5MjhjZGE1ZTI0 MjUyYjFlMWQwMTBkMTIxMjEyMTgxODE4MWMxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTFkMGYyYzAxMDExZDE2MWUyMjc4NjgzMjJhMzQxMjI1MTMwMTAx MDEwMTAxMDExMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDExMjEwMTIwMTAxMTIwMTFiMDFi Zjc5NWNiYzFlMjAxYzEwMjAwMTAxMDEwMTEwMGQ1ODk0ZTY5ZmExYTg4ZWJhZDE4ZjBkNDEwMWU3 NGYyYjU4NTgwMTAxDQoxNzE2MjUwMTc0YmNjM2FmNDQ0MTQyNzc0OTlhNTI3NTAxMTIxMjEyMTgx ODFjMWMwMTAxMTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxNDE2MjAxMDEwZDAxMTc1NmNjYWQzYg0KMTUwMTEzMDEwMTAxMDEwMTAxMTIwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAw NTAwDQowMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDExYw0KMTAxMzEyMDEwMTEwMWYwMTIwMWI3MzE2ZTUxYjEzMDEwMTEy MDEwMTE4MDExMjAxMTE1YTlhODQ2M2RhNjRiN2EwMWIxNzFiMDFhZDYwMTcyMDI1NTgxMDE4MGQ1 ODI1MDExZTc0ODcyZGEzMzYzODRjNjRiNDkzMTMxZDAxMDENCjAxMDEwMTAxMDEwMTE4MWMwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFmMjUxNzAxMDE1ODRiMWIx YjBlMDE2MjAxMDExMTEwMTcwZDAxMWMxYzAxMDExYzAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDExODFkMTAxYzAxMTgxOTAxMmMxMzEyY2NjYTVjMmMxYzAxMDEwMTEwDQoxNTE4MDE1NjAxYTRk MmUzOWRlNDZkOTY4NDEwMTYwMTJlMDExMjFjMDEyMDBmNTgxMDEyMDEyNTJiMDEyNjE5Nzg1MjFk YjRlNThhN2M2YzdhMGYxMjEyMTIxODE4MWMxYzFjMTgxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwZTFmMWMwMTBkNTgxMjAxMjUyMDE2MWIxODE1 MTIwMTE4MTIwMTAxMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExODAxMDExMjEzMGQwMTAxMDE0 MTAxMTMyMDIzYjc5OTI4MmIwZDE4MTAxNzIwMDExZDE4NDE5MjhlZTEyMWMxNzgzOTQ3YjgwMTFj MWUxZDAxMGUNCjEyMDExNzFiMTUwZTE5MDEwZDIyMTYxNTYwYmE4NWEzODJkNWUyOThlMjdmMGUx NzExMTUxMDEyMWMwMTE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMGQxMDAxMDExYzBkMTI1NjIwDQoxNzFkMDEwMTAxMGQwMTAxMDEwMTEyMWMxYzEyMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIN CjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMWMxYzFjMWMxYzFjMWMxYzBkMTExMzAxMDE1Njc5OGQyNDc5 MDExNzE1MTgxMzE5MTgwMTFkNmY1Yjk2M2JjMWE4ZGQyMTFmMDExMzEwMTIxMjEyMGQxMDFkMTUx MTE3MTUxMzE1MTUwZDEwMjE3ZGExZGU0NzU5MGZkZg0KZTBiYzI4MWYzYjFjMTMwZjRiMDExZDE4 MDExODEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMjFjMWMxMjE4MDEx YzFkMjUxNzEyMGQxMjAxMDExYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4 MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDExYzFjMWMxYzFjMWMxYzFjMDEwZDBkMDEwMTExOWQ0ZjRhN2UNCjBlMWUxZjAxMTkxZDFjMDEw MTVkMzAzZTYxYzczNWRjMjYxYzFlMTAwMTBkMWMxYzE4MTgwZDFkMTMxNTE3MTExMTIwMTIwMTEy MWUwZTc3MGM3MjI0Y2ZhMGRiMzhkNTI1MDEyNTBlMDE1ODEzMWMwMTE4MTIxYzAxMTgwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgwMTFjMTIxODAxMWMxZDc1MTEwZDEwMGQxYzAx MTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMx YzAxMTgxZDBkMDExYzJjNjY4ODUyNDI3NTAxMGYwMTBkMTExMzAxYjJhZjY3NGE4ZTdjNWIxNTAx NTgwMQ0KMDExNTAxMDEwMTAxMWMxMjBkMTAxZDEzMTcxZjBlMWQxMjEwMTgxZDM0NmQyNzQxM2Q1 YTVkOTM1MzIwMDExZTAxMTIxNTE4MDExYzE4MWMxODBkMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDExYzAxMDExODFjMDENCjFjMWQxZjIwMTAxZDEwMTgwMTFjMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxYzFjMTAxNTE4MDExNTQx Nzk0NDVmNGYwMTBmMTIxMzE1MTIxOTQ4YjUzNmRhMzk4MGNiMDExZjFkMDExNjBkMDEwMTAxMDEw MTFjMTgxMjFjMTIyMDFmMWIxZTE1MTAwMTI2DQo3NTU5ODY3NGFkNDg2Yzg1ZGI0ODNiMTMwMTFk MjAxODAxMDEwMTAxMDExMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTgx YzAxMWMxZDE1MWQxMDEwMGQxODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBk MDExODAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMWMxYzFjMWMxYzFjMWMxYzEyMDEwMTBkMTIwMQ0KMDExMzJiMzU1OWFiYjgwMTE2MWIw MTAxMGVkNTA4YzNkOTVhNTQ2MTAxNGIwMTAxMWUwMTFjMWMxYzAxMDExYzE4MTgxODEyMTAxNTEx MTExMDAxMWYwMTI3NjZkYWFlMGY1MWQ1YzY4YzNjZDcwMTBlNDExMTEyMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTE4MWMwMTE4MTMxMjEwMTAwZDE4 MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMx YzFjMWMxMDFjMDEwZDFkMTIwMTAxMTJkNzdmNTJiZjJiMDEyNjEwMGUwMTY5ZDgzMzU0YWU2YzYy DQowZTE3MTIxNTAxMTIxMjE4MTgxYzFjMWMxYzE4MDExYzEyMTIxMzBlMWUxMTAxMjEwMTc1NDA1 NTY4ODkyY2E2OTFkOThmN2UyMDE5MjAxMjAxMDEwMTAxMDExYzAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDExMjEyMWMxMjIwMTgxZDEzMTIwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMGQxZDFkMGQwZDEz MTAxYzFjMjFiYzc5MjRiNDAxMjUwZTc1MDFhZGQxNzM5ZmQ0YzU1ODEzMDExMDEzMWMwZDEyMTgx YzAxMDEwMTAxMDEwMTFjMTIxODEwMWUNCjU4MTYxMjAxMjAxZTU2NTZkNTNlODk1NjJiZDY4Mzk1 OTUwMTFkMWMwMTEyMTAxMjEyMTAwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDEx YzBkMGQxODEwMTExMDExMTExMjAxMWMxYzAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAx MDEwZDAxMTgwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTBkDQoxMzAxMDExODBkMDExMjAxMmVhNjRmM2E1 OTAxMDExODAxNzBjNzU5MzJiMjNkMTEwMTAxMTAwMTE5MDExMjE4MWMwMTAxMDEwMTAxMDExMDEw MDEwMTE4MGQxODE4MTkwMTI1MWMxZDRiODI4NDU2OTU1M2QzNjc3MjczMGQwMQ0KMDExMDE1MTMx MzIwMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExODAxMTgxMDEwMTIxZDE3MTMxZTBl MGQwMTE4MTIxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxMGYwMTFkY2Y0MDVmN2YwMTE3MDE3Y2QxOTUNCjhh ZDI0YTJjMDEwMTEwMDEwMTEyMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxMDFlNzUx ZjEyMWMwZTBmYmFhZTU4MzgyNTViNzE2N2IxMTMxZjE5MWMyYzAxMDExMzFjMDEwMTE4MDEwMTE4 MDEwMTAxMDEwMTAxDQowMTAxMDExMzBkMDExNjAxMTg0YjEyMTcwZTE4MDExODBkMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFj MWMxYzFjMWMxNTBkMDEwZDQxYjc1YzczMTExMjAxN2NjZDk4Y2VhOTQxMTAwMTE4MTUxYzAxMWMw MTAxMDEwMTAxMDEwMTAxMWMxYw0KMWMxYzFjMWMxYzFjMDEwZDE3MWUyMDBkMTIxMDAxY2Y4NjZh N2RjZTc4ZDA4ZDc5NjYwMTAxNjIxMjEzMWQxODFjMTIxMjFjMWMwZDAxMDEwMTAxMDEwMTAxMDEw MTEwMTMwMTE1MDEwZTM0MGQxMzFkMWMwMTFjMTIxODAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1 MDAwMTAxMGQwMQ0KMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDExYzFjMWMxYzFjMWMxYzFjMWQwZDAxNGIw MWNiNTczNWI0MTgwMThkNDZjNjkyNjQwMTAxMDEwZDEwMTgwMTFjMDEwMTAxMDEwMTAxMDEwMTFj MWMxYzFjMWMxYzFjMWMxYzE4MWQxNzE5MTkxMTFkMTcyYzczMGE0NzExDQoxZmNjYzg1NTU5OWQx NzExMWMwMTFjMDEwMTEyMTgwMTAxMGQwMTAxMDEwMTAxMDEwMTAxMTgxYzE3MDExYzAxMjc0YTEz MTgwMTAxMWMwMTAxMTIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMwMTEzMjUwZDBmMTY1OTY2YTVjYQ0KMDFjYWFm M2M0NjhjMTgwZDBkMDEwMTFjMTIxODAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMWQx MjAxMTIxNzU4MjUwZjFkMWQxMTdjYWM5NTc3MmQ2NzQ5NmYyZjEzMDE2MjEzMDEwMTFjMTIxODAx MDEwZDAxMDENCjAxMDEwMTAxMDEwMTE4MDExNzE4MTgxODdmYmExZTFjMDExYzEyMDEwMTEyMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFj MWMxYzFjMWMxYzFjMDE2MjAxMTIwZTAxMzQ4ZDI4YWQwMTU2YzdjOGM5NjExMzE1MGQwMTAxMTIx MjAxMDEwMTAxMDEwMTAxDQowMTAxMWMxYzFjMWMxYzFjMWMxYzE4MDEwMTAxMDEyMDU4NTYxNjE3 MWIwMWExOWExYmIxMzM2N2E5Mzk5YTFkMDEwMTBkMTgxODEwMGQxYzE4MWQwMTAxMDEwMTAxMDEw MTAxMGQwMTIwMTgxZDEwYjhhNjE5MTIwMTEyMGQwMQ0KMDExYzAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAw MDAwNTAwDQowMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzAxNDEw MTBlMDExNjAxN2M4OGJmMzUyZWMwYzFjMjE1MWMxYzFjMWMxMjEwMWMwMTAxMDEwMTAxMDEwMTAx MDExYzFjMWMxYzFjMWMxYzFjMDEwMTE4MWMwMTE4MWQxNzExMjYNCjAxNDEwZTlkYzM0MjIyYzRj NTgzYzY3ZjRiNTgxZDAxMDEwMTFjMDEwMTFjMDEwMTAxMDEwMTAxMDEwMTBkMDExZDAxMTUxYzRi MmQxMTEwMTgwZDEyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMTUwMTJlMDEyYjAxDQowMTI1OGRiYzM2 OTFiZGJlYWMxNTAxMDEwMTBkMWQxMjFjMWMwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMx YzFjMTgwZDEwMGQxODEyMTIwMTAxNGIxZDE4MTUyZDkzMzg1NzBlNWNiYmI3N2ExNTBlMWMwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTBkMTMwMTE3MDExZjJlMDExMjEwMTgwMTE4MWMw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MWMxYzFjMWMxYzFjMWMxYzBkMDExNTEwMDExZjEyMDEyMGExMjM5YmI5MDViYTEwMTAxYzE4MTAx MjAxMTgxNzAxMDENCjAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxODAxMDEwMTAxMTgxMjE4 MDExOTAxMTM1MTU4MDEzNDkxYmI2MzEzOTY4NjkwNTE1NjExMDExYzEzMTUxZDBkMDEwMTAxMDEw MTAxMDEwMTAxMTUxNTAxMTkwMTBlN2YwMTAxDQoxMDAxMDExMjBkMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFj MDINCjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMWMxODEyMTIwZDEwMGUzNDhmYjViNmE0YTEwMTAxMDEwMTAxMWMxMjBkMTIxMDEyMDEwMTFj MWMwMTAxMDEwMTAxMDExYzFjMWMwMTE4MTgxODE4MTgxMg0KMTIxMjBkMTIxMjEwMTUxNTFkMTIx MzNkYWViNzg1YjQ2NzcwN2QyMjBlMDExOTAxMGYwMTFkMTAxMjFjMWMxODEyMGQwMTEzMDExNjAx MDFiODczMDExZDAxMDExMDFkMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQw MTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjFjMWMxODEyMGQwZDAx MGY0YWFmMDhiMGIxMWIxZTExMTAxODFjMDEwMTAxMDEwMTFjMTIxMDFkMTAwZDFjMWMxYzFjMWMw MTAxMDExODFjMWMxYzFjMDEwMTAxMDExODBkMTAxMDE1MWUxNjE3NzViMjVhMzY3OTNkYjM4MGI0 DQo3ZDIxMGQxODBkMWIxODFjMWMxYzAxMDEwMTAxMGQxMDEzNGIwMTI2ODk3ZTFjMTAxYzAxMGQw ZDFjMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzE4MTIxMjEyMWMwMTQwODYwNzBjYTc0NzI2MmIx NjExMWQxMg0KMWMwMTAxMDExODEyMWMwMTAxMDExYzFjMWMxYzFjMWMxYzFjMTIxMjE4MWMxYzAx MDEwMTAxMTIxMDEyMDEwZDFmMGY3NDI1YThhOWFhNzFhYjgyYWMzNmFkNTgxOTE1NTgxMDAxMDEx YzFjMWMwMTAxMDEwMTAxMDEwZTI1YTgNCmFlNTAxMjE4MWMxYzE4MWMxYzE4MDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMWMxYzE4MTgxMjE1MDEwZDI0NGNhMjQzYTM2MzY2MjIyNTE5MjAxMDEyMDExODBk MTgwMTAxMDEwMTAxMDEwMTFjMTgxMjBkMGQxMjEyDQoxMjEyMTgxODE4MTgxMjBkMGQxYzAxMDEx ZDBlNDA0ZjJkODgzOWE0M2Y5OTk2Njc3MTMzMmI2MjEyMTAxMjEyMTgxYzFjMWMxYzFjMTkxNzE3 M2JhNTE0MTRhNjExMWMxYzBkMDEwMTFjMTIwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEw MTBkMDExODAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTFjMWMxYzFj MTgxYzIwMDEwZjYxNjM2NjFiNGY3ZjlkNDE3NTFlMjAxMzE1MTUxNTEzMWQxZDE1MTExMjEyMTgx YzFjMTgxMjBkMDEwMTFjMWMxODE4MTIxMjEwMGQxODE4MTgxODE4MWMwMTBlMTc1MDQ4NWQNCjg2 OWU4YzQzOWZhMDkwMTMyMDEzMWQwZDE4MDEwMTAxMTgwZDAxMDEwMTAxYTE5YjAwNzcyNTAxMDEx MzAxMDExODE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzAxMWYwMTIwMDEwZDE4MDEy YjI1DQo1ODFiMTY3NTJjMmM3NTFiMGUxMTExMjAxZDBkMTUxZDBkMTgxYzFjMWMxODAxMDEwMTAx MDEwMTFjMWMwZDEyMTgxMDEzMTMwZDAxMDExODExMmQ3ZDdjOTU5NjUzOTI2Yjk3OTg5OTc0MWMw ZDEyMWMwMTAxMDExYzE4MDExZA0KMTcwMTBmOWE5YjljOWQxODAxMTUwMTAxMGQxYzAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExODIwMDExNTE1MTkxZjBkMDEwMTAxMGQxNzE2MmMwZjE2 MWUxNzFlMWIxOTEzMDExMDBkMTIxYzE4MTINCjEwMWQwZDBkMTIxODE4MWMwMTAxMDExODBkMTAx MDBkMTIxMjBlMmMwMTAxMmM2NjQ3OTA5MTVlNmY4NzNlOTI5MzYwMTgxODEyMGQwZDE4MWMwMTAx MTIxNTE3NjY4OTk0MDA1NzBkMDExNTAxMDExZDAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUw MDAxMDEwZDAxMTgwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDExMzE4MGQxODAxMGQwMTE4MWMwMTFjMTIxMDEwMTAxODFjMTAxNjNiMjIyYjFiMDEw MTAxMDExMjE1MGUxZjBlMTcxMTE1MTAxMjFjMDEwMTE4MWQwZDAxMDEwMTEyMDExMg0KMTExODE5 MTExNTg5NDM4YThiNjc4MzU0ODc4YzFjMGQxNTE3MTExMzE4MDExMzFjMDEwZDQyOGQzZjhlOGYx MDAxMTUwMTAxMTMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMN CjFjMWMxYzFjMWMxYzFjMWMxYzFjMWQxMDBkMGQxZDExMTk1ODc1MTYxZTIwMWQxODAxMDExZDFk MTAwZDEyMWMwMTAxMDExYzE4MTgxODFjMDEwMTAxMGUxMTFkMjAwMTAxMmI2YTgzODQ4NTZhODY3 Mjg3ODgyNjEyMTAwMTEyDQoyMDAxMDExMzBkMDE1NzIyMjc4MjAxMDEwMTEyMTAxMDE4MDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFj MWMxYzFjMWMxODEyMGQxMDFkMTMxZA0KMWQxMDEwMTAxZDEzMWQxZDFkMWQxMDEyMTgxYzIwMjAy MDE1MTMxMDEyMWMwMTAxMDExYzE1MGQwMTEzMTc3ZDNlN2U3ZjgwNmU4MTJmODIyYzExMTIyMDFk MTIxMzE1MTAxMzJlMDEwMTQwMGQxODFjMTgxMjBkMTgxYzAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAw MDA1MDAwMTAxMGQwMQ0KMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMTgxMjBkMTAwZDEyMWMw MTAxMDEwMTFjMTIxZDE1MjAxMzEzMTUxNTEzMWQxMDEwMTAxZDEzMjAyMDExDQoyMDIwMTcxMjFk MTcxMzBkMTIwMTAxMWM3YTMwNWY1NjUwM2UzMDdiN2MyZTAxMDE2MjBkMDEwMTBkMmI0YTE5MGQ3 ZDIwMWQxODAxMWMxODE4MTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYw0KMWMx YzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzBkMGQxMDEwMGQxMjE4MWMxODFjMWMxYzFjMTgxMjEy MTMxMzE1MjAyMDE1MTUxMzEyMGQwZDEwMWQxZDFkMWQxNTEwNzUyYzE4MDEwZTE1MWYwMTE2MDE3 Mjc2Nzc3ODYzNWENCjUzNWMzYjAxMWMyMDBkMDExYzJjNzkxZjEwMTExNTEwMTgwMTFjMTgxODFj MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFj MWMxYzFjMWMxYzAxMDEwMTAxDQoxYzE4MWQxMDBkMTgwMTAxMDEwMTEwMWQxMzE1MTUxNTEzMTMx NzExMTUxZDBkMTgxYzAxMDEwMTIwMGUwMTBkMjExNjAxMjExZDFmMDE2NzZmNTA3MDcxNzI2ZDcz MTAxZjAxMTExZDAxMTU3NDE2NTgwMTE4MWMwMTFjMTgxMg0KMWMwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMw MjAwMDAwNTAwDQowMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzE4MWMxYzAxMWMx ODBkMTAxMDBkMTIxODFjMWMxYzFjMTIwZDBkMTAxMDEwMGQwZDEzMTMNCjEzMTMxNTIwMTExNzE3 MTIxYzE4MGQwZTFmMGQ2NjJiMDEwMTJjMDE2YTZiMmMzNjNmNmM2ZDZlNjAwMTEzMTAwMTE1NjA2 MDIzMWYxYzAxMDExYzE4MTIxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAx MTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMWMx YzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxYzFjMWMxODEyMGQxMDEwMTAwZDBkMWMxYzAxMDEwMTFj MTgxODAxMWMxYzE4MTgxYzAxMDEwMTFjMTgxMjFkMTExZTE5MWI1ODE1MTIwZTE5MWQwMTAxMTU2 MjQxMTM1OA0KMTA2MzY0NjU2NjY3NjgzZTY5MjEyMDEwMTgxYjQxMjEyODFiMWQwZDFjMDEwMTFj MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMxYzFjMWMxYzFj MWMxYzFjMWMxYzAxMDENCjE4MGQxMjFjMDEwMTAxMDEwMTAxMDEwMTFjMWMwMTAxMDEwMTAxMDEw MTAxMTAwZDFjMDEwMTAxMDEwMTAxMTkxZTEwMWUwZTFkMTk1ODAxMTUwMTAxMGQwZTJiNTk1YTVi NWMyZTVkNWU1ZjBkMWMxMzYwNTA1NjI0NjExZTE1DQoxODAxMDEwMTE4MTgwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTFjMDINCjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDExMDEwMTAxMDEwMTAxMDEwMTgxZDExMWUwZTEzMWMwMTAxNTEzOTM2NTI1MzU0MzM1NTU2NTcw MTI2MDExNTAxMGQxODAxMDExYzFjMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAx MGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxYzFjMWMxYzFjMWMx ODBkDQoxMzIwMTcxNzExMjAxNjAxMjc0OTRhNGI0YzAwNGQzMTRlNGYyZDE2MjE1MDBkMTgwMTAx MWMxYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTIxMjEyMGQxZDIwMGUxZTI1 MDEwMTQyNDM0NDQ1NDY0NzMyMDA0ODFkMWINCjEwMDEwZDE4MDEwMTFjMWMxYzAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTEwMGQxODFjMTgxMjEwMWQwMTBmMTgzYjE4M2MzZDNlMjQy ZjMxM2YyNTE4NDA0MTBkMTgwMTAxMWMxYzFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAw MDEwMTBkMDExODAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzFjMWMxYzFjMWMN CjFjMWMwZDBkMGQxMjE4MWMwMTAxMDEwZTAxMTAwMTM0MzUzNjM3MjYzODM5M2ExZTIxMDEwZDE4 MDEwMTFjMWMxYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMTgwZDEwMTAwZDEy MTgwZTAxMTkxOTJiMmMxMDJkMmUyZg0KMzAzMTMyMzMwZTBkMGQxODAxMDExYzFjMWMwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxMjBkMGQwZDBkMDEyNjFkMWQwMTAxMWYx MjE1MjcxYjI4MjkyYTI3MDEwZDE4MDEwMTFjMWMxYzAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAw MDUwMDAxMDEwZDAxMTgwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMxYw0KMWMx YzFjMWMxYzFjMDEwMTAxMDEwMTAxMWMxODEyMDEwMTE4MWMyMTAxMDEwZTAxMTAyMjIzMjQyNTAx MGQxODAxMDExYzFjMWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMTMwZDE4MWQxZTFmMjAxODE4MWMwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDExODAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDExMDEyMWMxMjFkMTAxYzAxMTgxYzAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAy MDAwMDA1MDAwMTAxMGQwMQ0KMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMGQwZDEwMTAxMDEy MWMwMTE4MWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWMwMjAwMDAwNTAwMDEwMTBkMDEx ODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMTIxZDEzMTAwZDEwMTMxODFjMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEwZDAxMTgwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTBkMTIxYzAxMTgxZDE4MWMwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MWMwMjAwMDAwNTAwDQowMTAxMGQwMTE4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTEyMTAxZDBk MWMwMTFjMTIxODFjMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMDIwMDAwMDUwMDAxMDEw ZDAxMTgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDExMDFkMTAwZDE4MWMxODEyMTgxYzAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYzAyMDAwMDA1MDAwMTAxMGQwMTE4MDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFjMWMxODFjDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTFjMDINCjAwMDAxNDAwMDEwMTBlMDExNzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA0MDAwMDA1MDAw ZDAxMDEwMTAxMTIwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWIwNTA1MDAwMDAwMTgwMTBlMTkwMTAxMTgxODE4 MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4DQox ODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4 MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgx ODE4MTgxODE4MTgxOA0KMTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4 MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgx ODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgNCjE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4 MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgx ODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4DQoxODE4MTgxODE4 MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgx ODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4MTgxODE4 MTgxOA0KMTgxODAxMWEwMDAwMTQwMDE1MDEwMTAxMDExNjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTcwMDBiMDAw MDAwMDExMDExMTIxMzAxMTIxMjEyMTIxMjEyDQoxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEy MTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIx MjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMg0KMTIxMjEyMTIxMjEy MTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIx MjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEy MTINCjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIx MjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEy MTIxMjEyMTIxMjEyMTIxMjEyDQoxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIx MjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEy MTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMg0KMTIxMjEyMTIxMjEyMTIxMjEyMTIx MjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjEyMTIxMjAxMDAxNDAwMDAwYzBkMDEwMTAxMGUwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwZjA5MDAwMDA3MDAwODAwMDAwOTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDBhMDAw YjAwMDAwMjAzMDAwMDAwMDQwNDA1MDUNCjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1 MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUw NTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1DQowNTA1MDUwNTA1MDUwNTA1 MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUw NTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNQ0K MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUw NTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1 MDUwNTA1MDUwNTA1MDUNCjA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUw NTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1 MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUw NTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDUwNTA1MDAwNjAwMDAwNDAwMDAwMDI3MDFmZmZm MDMwMDAwMDAwMDAwfVxwYXJ9fX17DQpcYlxmczI4XGluc3JzaWQ3NzU3NTQwIFwnYzIgXCdmZVwn ZjBcJ2U4XCdlNFwnZThcJ2Y3XCdlNVwnZjFcJ2VhXCdlOFwnZTkgXCdlNFwnZTVcJ2VmXCdlMFwn ZjBcJ2YyXCdlMFwnZWNcJ2U1XCdlZFwnZjJ9e1xiXGluc3JzaWQ3NzU3NTQwIA0KXHBhciB9XHBh cmQgXHFsIFxsaTBccmkwXHNsLTMyMVxzbG11bHQwXG5vd2lkY3RscGFyXGZhYXV0b1xyaW4wXGxp bjBcaXRhcDBccGFyYXJzaWQ3NzU3NTQwIHtcYlxpbnNyc2lkNzc1NzU0MCANClxwYXIgfVxwYXJk IFxxciBcbGkwXHJpMFxub3dpZGN0bHBhclxub292ZXJmbG93XGZhYXV0b1xyaW4wXGxpbjBcaXRh cDBccGFyYXJzaWQ3NzU3NTQwIHtcYlxmczI4XGluc3JzaWQ3NzU3NTQwIFwnZDFcJ2YyXCdmMFwn ZWVcJ2U4XCdmMlwnZTVcJ2ViXCdmY1wnZWRcJ2UwXCdmZiBcJ2VhXCdlZVwnZWNcJ2VmXCdlMFwn ZWRcJ2U4XCdmZn17XGJcaW5zcnNpZDc3NTc1NDAgDQpccGFyIH1ccGFyZCBccWwgXGxpMFxyaTBc c2wtMzIxXHNsbXVsdDBcbm93aWRjdGxwYXJcZmFhdXRvXHJpbjBcbGluMFxpdGFwMFxwYXJhcnNp ZDc3NTc1NDAge1xiXGluc3JzaWQ3NzU3NTQwIFx0YWIgDQpccGFyIH1ccGFyZCBccXIgXGxpMFxy aTBcbm93aWRjdGxwYXJcbm9vdmVyZmxvd1xmYWF1dG9ccmluMFxsaW4wXGl0YXAwXHBhcmFyc2lk Nzc1NzU0MCB7XGJcZnMyOFxpbnNyc2lkNzc1NzU0MCBcJ2QwXCdmM1wnZWFcJ2VlXCdlMlwnZWVc J2U0XCdlOFwnZjJcJ2U1XCdlYlwnZmUgXCdlZlwnZjBcJ2VlXCdlNVwnZWFcJ2YyXCdlMH17XGJc aW5zcnNpZDc3NTc1NDAgDQpccGFyIH1ccGFyZCBccWwgXGxpMFxyaTBcc2wtMzkyXHNsbXVsdDBc bm93aWRjdGxwYXJcZmFhdXRvXHJpbjBcbGluMFxpdGFwMFxwYXJhcnNpZDc3NTc1NDAge1xpbnNy c2lkNzc1NzU0MCANClxwYXIgfVxwYXJkIFxxYyBcbGkwXHJpNTE4MFxzbDIxMVxzbG11bHQxXG5v d2lkY3RscGFyXG5vb3ZlcmZsb3dcZmFhdXRvXHJpbjUxODBcbGluMFxpdGFwMFxwYXJhcnNpZDc3 NTc1NDAge1xiXGZzMThcaW5zcnNpZDc3NTc1NDAgXCdkNlwnZTVcJ2VkXCdmMlwnZjAgXCdjYVwn ZjBcJ2UwXCdmMlwnZWFcJ2VlXCdmMVwnZjBcJ2VlXCdmN1wnZWRcJ2ZiXCdmNSBcJ2NmXCdmMFwn ZWVcJ2UzXCdmMFwnZTBcJ2VjXCdlYw0KXHBhciBcJ2NlXCdlMVwnZjNcJ2Y3XCdlNVwnZWRcJ2U4 XCdmZiBcJ2UzfXtcYlxmMzlcZnMxOFxpbnNyc2lkNzc1NzU0MCAufXtcYlxmczE4XGluc3JzaWQ3 NzU3NTQwICB9e1xiXGZzMThcaW5zcnNpZDIyMzAyNDUgXCdkMVwnZTBcJ2VkXCdlYVwnZjItfXtc YlxmczE4XGluc3JzaWQ1MDcwNTg1IFwnY2ZcJ2U1XCdmMlwnZTVcJ2YwXCdlMVwnZjNcJ2YwXCdl M317XGluc3JzaWQ3NzU3NTQwIA0KXHBhciB9XHBhcmQgXHFsIFxsaTEyNDBccmkwXHNsMjM3XHNs bXVsdDFcbm93aWRjdGxwYXJcZmFhdXRvXHJpbjBcbGluMTI0MFxpdGFwMFxwYXJhcnNpZDc3NTc1 NDAge1xiXGZzMjBcY2Y2XGluc3JzaWQ3NzU3NTQwIFwnZDJcJ2U1XCdlYn17XGJcZjM5XGZzMjBc Y2Y2XGluc3JzaWQ3NzU3NTQwIFxcfXtcYlxmczIwXGNmNlxpbnNyc2lkODMyNDcyMiBcJ2Y0XCdl MFwnZWFcJ2YxOiB9e1xiXGZzMjBcY2Y2XGluc3JzaWQyMjMwMjQ1ICg4MTJ9ew0KXGJcZnMyMFxj ZjZcaW5zcnNpZDY1NzcyNzUgKSB9e1xiXGZzMjBcY2Y2XGluc3JzaWQyMjMwMjQ1IDk4NCA1MyA2 M317XGZzMjBcY2Y2XGluc3JzaWQ2NTc3Mjc1IA0KXHBhciB9XHBhcmQgXHFsIFxmaTM5M1xsaTYw MFxyaTBcc2wyMzBcc2xtdWx0MVxub3dpZGN0bHBhclxmYWF1dG9ccmluMFxsaW42MDBcaXRhcDBc cGFyYXJzaWQ3NzU3NTQwIHtcZnMyMFxpbnNyc2lkNzc1NzU0MCBcJ2M4XCdmMVwnZjVcJ2I5fXtc ZjM5XGZzMjBcaW5zcnNpZDc3NTc1NDAgX19fX317XGYzOVxmczIwXGluc3JzaWQyMjMwMjQ1IF9f fXtcZnMyMFx1bFxpbnNyc2lkMjIzMDI0NSA5fXtcZnMyMFx1bFxpbnNyc2lkMjg5NjM5MSAwMH17 DQpcZjM5XGZzMjBcaW5zcnNpZDc3NTc1NDAgX19fX19fX19ffXtcZjM5XGZzMjBcaW5zcnNpZDIy MzAyNDUgX199e1xpbnNyc2lkNzc1NzU0MCANClxwYXIgfVxwYXJkIFxxbCBcbGkwXHJpMFxzbC0x XHNsbXVsdDBcbm93aWRjdGxwYXJcZmFhdXRvXHJpbjBcbGluMFxpdGFwMFxwYXJhcnNpZDc3NTc1 NDAge1xpbnNyc2lkNzc1NzU0MCANClxwYXIgfVxwYXJkIFxxbCBcZmkzNzNcbGk2MjBccmkwXHNs MjM3XHNsbXVsdDFcbm93aWRjdGxwYXJcZmFhdXRvXHJpbjBcbGluNjIwXGl0YXAwXHBhcmFyc2lk Nzc1NzU0MCB7XGZzMjBcaW5zcnNpZDc3NTc1NDAgXCdjZVwnZjIgfXtcZjM5XGZzMjBcaW5zcnNp ZDc3NTc1NDAgX199e1xmMzlcZnMyMFxpbnNyc2lkMjIzMDI0NSBffXtcZjM5XGZzMjBcaW5zcnNp ZDc3NTc1NDAgX199e1xmMzlcZnMyMFxpbnNyc2lkMjIzMDI0NSAzMH17DQpcZjM5XGZzMjBcdWxc aW5zcnNpZDc3NTc1NDAgLjB9e1xmMzlcZnMyMFx1bFxpbnNyc2lkMjg5NjM5MSA5fXtcZjM5XGZz MjBcdWxcaW5zcnNpZDc3NTc1NDAgLjIwMTR9e1xmMzlcZnMyMFxpbnNyc2lkNzc1NzU0MCBfX19f X19fX199e1xpbnNyc2lkNzc1NzU0MCANClxwYXIgfVxwYXJkIFxxbCBcbGkwXHJpMFxzbC0zMTRc c2xtdWx0MFxub3dpZGN0bHBhclxmYWF1dG9ccmluMFxsaW4wXGl0YXAwXHBhcmFyc2lkNzc1NzU0 MCB7XGluc3JzaWQ3NzU3NTQwIA0KXHBhciB9XHBhcmQgXHFsIFxsaTBccmkwXHNsLTRcc2xtdWx0 MFxub3dpZGN0bHBhclxmYWF1dG9ccmluMFxsaW4wXGl0YXAwXHBhcmFyc2lkNzc1NzU0MCB7XGlu c3JzaWQ3NzU3NTQwIA0KXHBhciB9XHBhcmQgXHFsIFxsaTBccmkzODBcc2wyMzJcc2xtdWx0MVxu b3dpZGN0bHBhclxub292ZXJmbG93XGZhYXV0b1xyaW4zODBcbGluMFxpdGFwMFxwYXJhcnNpZDc3 NTc1NDAge1xiXGluc3JzaWQ3NzU3NTQwIFwnY2ZcJ2YwXCdlOFwnZTNcJ2ViXCdlMFwnZjhcJ2Uw XCdlNVwnZWMgXCdmMVwnZWZcJ2U1XCdmNlwnZThcJ2UwXCdlYlwnZThcJ2YxXCdmMlwnZWVcJ2Uy IFwnZjFcJ2YyXCdmMFwnZWVcJ2U4XCdmMlwnZTVcJ2ViXCdmY1wnZWRcJ2ZiDQpcJ2Y1IFwnZjFc J2VmXCdlNVwnZjZcJ2U4XCdlMFwnZWJcJ2U4XCdlN1wnZTBcJ2Y2XCdlOFwnZTl9e1xiXGYzOVxp bnNyc2lkNzc1NzU0MCAsfXtcYlxpbnNyc2lkNzc1NzU0MCAgXCdlM1wnZWJcJ2UwXCdlMlwnZWRc J2ZiXCdmNSBcJ2U4XCdlZFwnZTZcJ2U1XCdlZFwnZTVcJ2YwXCdlZVwnZTJ9e1xiXGYzOVxpbnNy c2lkNzc1NzU0MCAsfXtcYlxpbnNyc2lkNzc1NzU0MCAgXCdmZVwnZjBcJ2U4XCdmMVwnZjJcJ2Vl XCdlMiBcJ2VmXCdlZVwnZjENClwnZTVcJ2YyXCdlOFwnZjJcJ2ZjIFwnZThcJ2VkXCdmNFwnZWVc J2YwXCdlY1wnZTBcJ2Y2XCdlOFwnZWVcJ2VkXCdlZFwnZWV9e1xiXGYzOVxpbnNyc2lkNzc1NzU0 MCAtfXtcYlxpbnNyc2lkNzc1NzU0MCAgXCdlY1wnZTVcJ2YyXCdlZVwnZTRcJ2U4XCdmN1wnZTVc J2YxXCdlYVwnZThcJ2U5IFwnZjFcJ2U1XCdlY1wnZThcJ2VkXCdlMFwnZjB9e1xiXGYzOVxpbnNy c2lkNzc1NzU0MCA6DQpccGFyIH17XGJcaW5zcnNpZDc3NTc1NDAgDQpccGFyIH1ccGFyZCBccWog XGxpMFxyaTBcd2lkY3RscGFyXGFzcGFscGhhXGFzcG51bVxmYWF1dG9cYWRqdXN0cmlnaHRccmlu MFxsaW4wXGl0YXAwXHBhcmFyc2lkNjU3NzI3NSB7XGJcZnMyOFxjZjZcaW5zcnNpZDc3NTc1NDBc Y2hhcnJzaWQyMDQ3Mjc3IFwnY2VcJ2QwXCdjM1wnYzBcJ2NkXCdjOFwnYzdcJ2MwXCdkNlwnYzhc J2RmIFwnZDFcJ2QyXCdkMFwnY2VcJ2M4XCdkMlwnYzVcJ2NiXCdkY1wnZDFcJ2QyXCdjMlwnYzAg XCdjOCBcJ2QxXCdkMg0KXCdkMFwnY2VcJ2M4XCdkMlwnYzVcJ2NiXCdkY1wnY2RcJ2RiXCdjOSBc J2NhXCdjZVwnY2RcJ2QyXCdkMFwnY2VcJ2NiXCdkYy4gXCdjMVwnYzVcJ2M3XCdjZVwnY2ZcJ2Mw XCdkMVwnY2RcJ2NlXCdkMVwnZDJcJ2RjIFwnZDFcJ2QyXCdkMFwnY2VcJ2M4XCdkMlwnYzVcJ2Ni XCdkY1wnZDFcJ2QyXCdjMlwnYzAuIFwnYzJcJ2MyXCdjZVwnYzQgXCdjZVwnYzFcJ2RhXCdjNVwn Y2FcJ2QyXCdjMCBcJ2MyIFwnZGRcJ2NhXCdkMVwnY2ZcJ2NiXCdkMw0KXCdjMFwnZDJcJ2MwXCdk NlwnYzhcJ2RlLiB9e1xiXGZzMzJcY2Y2XGluc3JzaWQyMjMwMjQ1IDEzfXtcYlxmczMyXGNmNlxp bnNyc2lkNjU3NzI3NSAgLSB9e1xiXGZzMzJcY2Y2XGluc3JzaWQyMjMwMjQ1IDE0fXtcYlxmczMy XGNmNlxpbnNyc2lkNjU3NzI3NSAgfXtcYlxmczMyXGNmNlxpbnNyc2lkMjIzMDI0NSBcJ2VlXCdl YVwnZjJcJ2ZmXCdlMVwnZjBcJ2ZmfXtcYlxmczMyXGNmNlxpbnNyc2lkNjU3NzI3NSAsIH17DQpc YlxmczMyXGNmNlxpbnNyc2lkMjIzMDI0NSBcJ2QxXCdlMFwnZWRcJ2VhXCdmMi1cJ2NmXCdlNVwn ZjJcJ2U1XCdmMFwnZTFcJ2YzXCdmMFwnZTN9e1xiXGZzMzJcY2Y2XGluc3JzaWQ2NTc3Mjc1IC59 e1xjZjZcaW5zcnNpZDc3NTc1NDBcY2hhcnJzaWQyMDQ3Mjc3IA0KXHBhciB9XHBhcmQgXHFsIFxs aTBccmkwXHNsLTI3N1xzbG11bHQwXG5vd2lkY3RscGFyXGZhYXV0b1xyaW4wXGxpbjBcaXRhcDBc cGFyYXJzaWQ3NzU3NTQwIHtcaW5zcnNpZDc3NTc1NDAgDQpccGFyIH1ccGFyZCBccWwgXGxpMFxy aTBcbm93aWRjdGxwYXJcZmFhdXRvXHJpbjBcbGluMFxpdGFwMFxwYXJhcnNpZDc3NTc1NDAge1xi XGluc3JzaWQ3NzU3NTQwIFwnYzJcJ2NlXCdjZlwnZDBcJ2NlXCdkMVwnZGJ9e1xiXGYzOVxpbnNy c2lkNzc1NzU0MCA6fXtcaW5zcnNpZDc3NTc1NDAgDQpccGFyIH1ccGFyZCBccWwgXGxpMFxyaTBc c2wtNVxzbG11bHQwXG5vd2lkY3RscGFyXGZhYXV0b1xyaW4wXGxpbjBcaXRhcDBccGFyYXJzaWQ3 NzU3NTQwIHtcaW5zcnNpZDc3NTc1NDAgDQpccGFyIHtcbGlzdHRleHRccGFyZFxwbGFpblxmczIy XGxvY2hcYWYzXGhpY2hcYWYzXGRiY2hcYWYwXGluc3JzaWQ3NzU3NTQwXGNoYXJyc2lkMTY1NDUw NDUgXGxvY2hcYWYzXGRiY2hcYWYwXGhpY2hcZjMgXCdiN1x0YWJ9fVxwYXJkIFxxbCBcbGkwXHJp MFx3aWRjdGxwYXJcamNsaXN0dGFiXHR4MFxhc3BhbHBoYVxhc3BudW1cZmFhdXRvXGxzMVxhZGp1 c3RyaWdodFxyaW4wXGxpbjBcaXRhcDBccGFyYXJzaWQ3NzU3NTQwIHsNClxiXGYzOFxmczIwXGlu c3JzaWQ3NzU3NTQwXGNoYXJyc2lkMTY1NDUwNDUgXCdjZFwnZWVcJ2YwXCdlY1wnZTBcJ2YyXCdl OFwnZTJcJ2VkXCdlZS1cJ2VmXCdmMFwnZTBcJ2UyXCdlZVwnZTJcJ2ZiXCdlNSBcJ2VlXCdmMVwn ZWRcJ2VlXCdlMlwnZmIgXCdlNFwnZTVcJ2ZmXCdmMlwnZTVcJ2ViXCdmY1wnZWRcJ2VlXCdmMVwn ZjJcJ2U4IFwnZWVcJ2YwXCdlM1wnZTBcJ2VkXCdlOFwnZTdcJ2UwXCdmNlwnZThcJ2U5IFwnZWZc J2VlIFwnZjFcJ2YyDQpcJ2YwXCdlZVwnZThcJ2YyXCdlNVwnZWJcJ2ZjXCdlZFwnZWVcJ2VjXCdm MyBcJ2VhXCdlZVwnZWRcJ2YyXCdmMFwnZWVcJ2ViXCdmZSwgXCdlZFwnZWVcJ2UyXCdlZVwnZTJc J2UyXCdlNVwnZTRcJ2U1XCdlZFwnZThcJ2ZmIFwnZTIgXCdlN1wnZTBcJ2VhXCdlZVwnZWRcJ2Vl XCdlNFwnZTBcJ2YyXCdlNVwnZWJcJ2ZjXCdmMVwnZjJcJ2UyXCdlNS4gXCdjZlwnZWVcJ2YwXCdm ZlwnZTRcJ2VlXCdlYSBcJ2VmXCdmMFwnZWVcJ2UyXCdlNVwnZTQNClwnZTVcJ2VkXCdlOFwnZmYg XCdmMVwnZjJcJ2YwXCdlZVwnZThcJ2YyXCdlNVwnZWJcJ2ZjXCdlZFwnZWVcJ2UzXCdlZSBcJ2Vh XCdlZVwnZWRcJ2YyXCdmMFwnZWVcJ2ViXCdmZi59e1xiXGYzOFxmczIwXGluc3JzaWQ3NzU3NTQw ICB9e1xiXGYzOFxmczIwXGluc3JzaWQ3NzU3NTQwXGNoYXJyc2lkMTY1NDUwNDUgXCdkMlwnZjBc J2U1XCdlMVwnZWVcJ2UyXCdlMFwnZWRcJ2U4XCdmZiBcJ2VhIFwnZWVcJ2YwXCdlM1wnZTBcJ2Vk XCdlOFwnZTcNClwnZTBcJ2Y2XCdlOFwnZTgsIFwnZWZcJ2YwfXtcYlxmMzhcZnMyMFxpbnNyc2lk Nzc1NzU0MCBcJ2VlXCdlMlwnZWVcJ2U0XCdmZlwnZjlcJ2U1XCdlOSBcJ2YxXCdmMlwnZjBcJ2Vl XCdlOFwnZjJcJ2U1XCdlYlwnZmNcJ2VkXCdmYlwnZTkgXCdlYVwnZWVcJ2VkXCdmMlwnZjBcJ2Vl XCdlYlwnZmMuDQpccGFyIHtcbGlzdHRleHRccGFyZFxwbGFpblxmczIyXGxvY2hcYWYzXGhpY2hc YWYzXGRiY2hcYWYwXGluc3JzaWQ3NzU3NTQwXGNoYXJyc2lkMTY1NDUwNDUgXGxvY2hcYWYzXGRi Y2hcYWYwXGhpY2hcZjMgXCdiN1x0YWJ9fXtcYlxmMzhcZnMyMFxpbnNyc2lkNzc1NzU0MFxjaGFy cnNpZDE2NTQ1MDQ1IFwnZDFcJ2VlXCdmMVwnZjJcJ2UwXCdlMiBcJ2U4IFwnZjFcJ2VlXCdlNFwn ZTVcJ2YwXCdlNlwnZTBcJ2VkXCdlOFwnZTUgXCdlOFwnZjFcJ2VmXCdlZQ0KXCdlYlwnZWRcJ2U4 XCdmMlwnZTVcJ2ViXCdmY1wnZWRcJ2VlXCdlOSBcJ2U0XCdlZVwnZWFcJ2YzXCdlY1wnZTVcJ2Vk XCdmMlwnZTBcJ2Y2XCdlOFwnZTguIFwnZDJcJ2YwXCdlNVwnZTFcJ2VlXCdlMlwnZTBcJ2VkXCdl OFwnZmYgXCdlYSBcJ2U4XCdmMVwnZWZcJ2VlXCdlYlwnZWRcJ2U4XCdmMlwnZTVcJ2ViXCdmY1wn ZWRcJ2VlXCdlOSBcJ2U0XCdlZVwnZWFcJ2YzXCdlY1wnZTVcJ2VkXCdmMlwnZTBcJ2Y2XCdlOFwn ZTggXCdlZlwnZjBcJ2U4DQogXCdmMVwnZTRcJ2UwXCdmN1wnZTUgXCdlZVwnZTFcJ2ZhXCdlNVwn ZWFcJ2YyXCdlMCBcJ2UyIFwnZmRcJ2VhXCdmMVwnZWZcJ2ViXCdmM1wnZTBcJ2YyXCdlMFwnZjZc J2U4XCdmZS59e1xiXGYzOFxmczIwXGluc3JzaWQ3NzU3NTQwIA0KXHBhciB7XGxpc3R0ZXh0XHBh cmRccGxhaW5cZnMyMlxsb2NoXGFmM1xoaWNoXGFmM1xkYmNoXGFmMFxpbnNyc2lkNzc1NzU0MFxj aGFycnNpZDE2NTQ1MDQ1IFxsb2NoXGFmM1xkYmNoXGFmMFxoaWNoXGYzIFwnYjdcdGFifX17XGJc ZjM4XGZzMjBcaW5zcnNpZDc3NTc1NDBcY2hhcnJzaWQxNjU0NTA0NSBcJ2QxXCdlZVwnZjFcJ2Yy XCdlMFwnZTIgXCdlOCBcJ2VlXCdmMFwnZTNcJ2UwXCdlZFwnZThcJ2U3XCdlMFwnZjZcJ2U4XCdm ZiBcJ2YwXCdlMFwnZTENClwnZWVcJ2YyIFwnZWZcJ2VlIFwnZjFcJ2YyXCdmMFwnZWVcJ2U4XCdm MlwnZTVcJ2ViXCdmY1wnZWRcJ2VlXCdlY1wnZjMgXCdlYVwnZWVcJ2VkXCdmMlwnZjBcJ2VlXCdl YlwnZmUuIFwnY2ZcJ2VlXCdmMFwnZmZcJ2U0XCdlZVwnZWEgXCdlZlwnZjBcJ2VlXCdlMlwnZTVc J2U0XCdlNVwnZWRcJ2U4XCdmZiBcJ2YxXCdmMlwnZjBcJ2VlXCdlOFwnZjJcJ2U1XCdlYlwnZmNc J2VkXCdlZVwnZTNcJ2VlIFwnZWFcJ2VlXCdlZFwnZjJcJ2YwXCdlZQ0KXCdlYlwnZmYgXCdlZlwn ZWUgXCdlMlwnZThcJ2U0XCdlMFwnZWMgXCdmMFwnZTBcJ2UxXCdlZVwnZjIuIH17XGJcZjM4XGZz MjBcaW5zcnNpZDc3NTc1NDAgDQpccGFyIHtcbGlzdHRleHRccGFyZFxwbGFpblxmczIyXGxvY2hc YWYzXGhpY2hcYWYzXGRiY2hcYWYwXGluc3JzaWQ3NzU3NTQwXGNoYXJyc2lkMTY1NDUwNDUgXGxv Y2hcYWYzXGRiY2hcYWYwXGhpY2hcZjMgXCdiN1x0YWJ9fXtcYlxmMzhcZnMyMFxpbnNyc2lkNzc1 NzU0MFxjaGFycnNpZDE2NTQ1MDQ1IFwnY2ZcJ2VlXCdmMFwnZmZcJ2U0XCdlZVwnZWEgXCdlMlwn ZTdcJ2UwXCdlOFwnZWNcJ2VlXCdlNFwnZTVcJ2U5XCdmMVwnZjJcJ2UyXCdlOFwnZmYgDQpcJ2Vj XCdlNVwnZTZcJ2U0XCdmMyBcJ2YzXCdmN1wnZTBcJ2YxXCdmMlwnZWRcJ2U4XCdlYVwnZTBcJ2Vj XCdlOCBcJ2YxXCdmMlwnZjBcJ2VlXCdlOFwnZjJcJ2U1XCdlYlwnZmNcJ2YxXCdmMlwnZTJcJ2Uw LiB9e1xiXGYzOFxmczIwXGluc3JzaWQ3NzU3NTQwIA0KXHBhciB7XGxpc3R0ZXh0XHBhcmRccGxh aW5cZnMyMlxsb2NoXGFmM1xoaWNoXGFmM1xkYmNoXGFmMFxpbnNyc2lkNzc1NzU0MFxjaGFycnNp ZDE2NTQ1MDQ1IFxsb2NoXGFmM1xkYmNoXGFmMFxoaWNoXGYzIFwnYjdcdGFifX17XGJcZjM4XGZz MjBcaW5zcnNpZDc3NTc1NDBcY2hhcnJzaWQxNjU0NTA0NSBcJ2NmXCdlZVwnZTRcJ2UzXCdlZVwn ZjJcJ2VlXCdlMlwnZWFcJ2UwIFwnZWVcJ2UxXCdmYVwnZTVcJ2VhXCdmMlwnZTAgXCdlYSBcJ2Yx XCdmMlwnZjANClwnZWVcJ2U4XCdmMlwnZTVcJ2ViXCdmY1wnZjFcJ2YyXCdlMlwnZjMuIFwnZDFc J2YyXCdmMFwnZWVcJ2U4XCdmMlwnZTVcJ2ViXCdmY1wnZWRcJ2ZiXCdlOSBcJ2VhXCdlZVwnZWRc J2YyXCdmMFwnZWVcJ2ViXCdmYyBcJ2VmXCdmMFwnZTggXCdlZVwnZjFcJ2YzXCdmOVwnZTVcJ2Yx XCdmMlwnZTJcJ2ViXCdlNVwnZWRcJ2U4XCdlOCBcJ2VmXCdlZVwnZTRcJ2UzXCdlZVwnZjJcJ2Vl XCdlMlwnZThcJ2YyXCdlNVwnZWJcJ2ZjXCdlZFwnZmJcJ2Y1IA0KXCdmMFwnZTBcJ2UxXCdlZVwn ZjIufXtcYlxmMzhcZnMyMFxpbnNyc2lkNzc1NzU0MCAgfXtcYlxmMzhcZnMyMFxpbnNyc2lkNzc1 NzU0MFxjaGFycnNpZDE2NTQ1MDQ1IFwnY2VcJ2YxXCdlZVwnZTFcJ2U1XCdlZFwnZWRcJ2VlXCdm MVwnZjJcJ2U4IFwnZWZcJ2YwXCdlZVwnZTJcJ2U1XCdlNFwnZTVcJ2VkXCdlOFwnZmYgXCdlMlwn ZjVcJ2VlXCdlNFwnZWRcJ2VlXCdlM1wnZWUgXCdlYVwnZWVcJ2VkXCdmMlwnZjBcJ2VlXCdlYlwn ZmYuIFwnY2YNClwnZWVcJ2YwXCdmZlwnZTRcJ2VlXCdlYSBcJ2UyXCdmNVwnZWVcJ2U0XCdlZFwn ZWVcJ2UzXCdlZSBcJ2VhXCdlZVwnZWRcJ2YyXCdmMFwnZWVcJ2ViXCdmZiBcJ2VmXCdmMFwnZWVc J2U1XCdlYVwnZjJcJ2VkXCdlZVwnZTkgXCdlOCBcJ2YwXCdlMFwnZTFcJ2VlXCdmN1wnZTVcJ2U5 IFwnZTRcJ2VlXCdlYVwnZjNcJ2VjXCdlNVwnZWRcJ2YyXCdlMFwnZjZcJ2U4XCdlOC59e1xiXGYz OFxmczIwXGluc3JzaWQ3NzU3NTQwIA0KXHBhciB7XGxpc3R0ZXh0XHBhcmRccGxhaW5cZnMyMlxs b2NoXGFmM1xoaWNoXGFmM1xkYmNoXGFmMFxpbnNyc2lkNzc1NzU0MFxjaGFycnNpZDE2NTQ1MDQ1 IFxsb2NoXGFmM1xkYmNoXGFmMFxoaWNoXGYzIFwnYjdcdGFifX17XGJcZjM4XGZzMjBcaW5zcnNp ZDc3NTc1NDBcY2hhcnJzaWQxNjU0NTA0NSBcJ2NlXCdlZlwnZTVcJ2YwXCdlMFwnZjZcJ2U4XCdl ZVwnZWRcJ2VkXCdmYlwnZTkgXCdlYVwnZWVcJ2VkXCdmMlwnZjBcJ2VlXCdlYlwnZmM6IFwnZDYN ClwnZTVcJ2ViXCdlOH17XGJcZjM4XGZzMjBcaW5zcnNpZDc3NTc1NDAgIFwnZTggXCdlN1wnZTBc J2U0XCdlMFwnZjdcJ2U4IH17XGJcZjM4XGZzMjBcaW5zcnNpZDc3NTc1NDBcY2hhcnJzaWQxNjU0 NTA0NSBcJ2VlXCdlZlwnZTVcJ2YwXCdlMFwnZjZcJ2U4XCdlZVwnZWRcJ2VkXCdlZVwnZTNcJ2Vl IFwnZWFcJ2VlXCdlZFwnZjJcJ2YwXCdlZVwnZWJcJ2ZmLn17XGJcZjM4XGZzMjBcaW5zcnNpZDc3 NTc1NDAgDQpccGFyIHtcbGlzdHRleHRccGFyZFxwbGFpblxmczIyXGxvY2hcYWYzXGhpY2hcYWYz XGRiY2hcYWYwXGluc3JzaWQ3NzU3NTQwXGNoYXJyc2lkMTY1NDUwNDUgXGxvY2hcYWYzXGRiY2hc YWYwXGhpY2hcZjMgXCdiN1x0YWJ9fXtcYlxmMzhcZnMyMFxpbnNyc2lkNzc1NzU0MFxjaGFycnNp ZDE2NTQ1MDQ1IFwnY2FcJ2VlXCdlZFwnZjJcJ2YwXCdlZVwnZWJcJ2ZjIFwnZWFcJ2UwXCdmN1wn ZTVcJ2YxXCdmMlwnZTJcJ2UwIFwnZTggXCdlZlwnZjBcJ2U4XCdlNQ0KXCdlY1wnZWFcJ2UwIFwn ZjBcJ2UwXCdlMVwnZWVcJ2YyLiBcJ2NmXCdmMFwnZThcJ2U1XCdlY1wnZWFcJ2UwIFwnZWZcJ2Vl XCdlNCBcJ2VjXCdlZVwnZWRcJ2YyXCdlMFwnZTYgXCdlN1wnZTRcJ2UwXCdlZFwnZThcJ2U5LCBc J2YxXCdlZVwnZWVcJ2YwXCdmM1wnZTZcJ2U1XCdlZFwnZThcJ2U5LCBcJ2VmXCdlZVwnZWNcJ2U1 XCdmOVwnZTVcJ2VkXCdlOFwnZTkgXCdlOCBcJ2Y0XCdmM1wnZWRcJ2U0XCdlMFwnZWNcJ2U1XCdl ZFwnZjJcJ2VlDQpcJ2UyLiBcJ2NmXCdmM1wnZjFcJ2VhXCdlZVwnZWRcJ2UwXCdlYlwnZTBcJ2U0 XCdlZVwnZjdcJ2VkXCdmYlwnZTUgXCdmMFwnZTBcJ2UxXCdlZVwnZjJcJ2ZiLiB9e1xiXGYzOFxm czIwXGluc3JzaWQ3NzU3NTQwIA0KXHBhciB7XGxpc3R0ZXh0XHBhcmRccGxhaW5cZnMyMlxsb2No XGFmM1xoaWNoXGFmM1xkYmNoXGFmMFxpbnNyc2lkNzc1NzU0MFxjaGFycnNpZDE2NTQ1MDQ1IFxs b2NoXGFmM1xkYmNoXGFmMFxoaWNoXGYzIFwnYjdcdGFifX17XGJcZjM4XGZzMjBcaW5zcnNpZDc3 NTc1NDBcY2hhcnJzaWQxNjU0NTA0NSBcJ2NlXCdmMlwnZjdcJ2U1XCdmMlwnZWRcJ2VlXCdmMVwn ZjJcJ2ZjIFwnZWZcJ2VlIFwnZjBcJ2U1XCdlN1wnZjNcJ2ViXCdmY1wnZjJcJ2UwXCdmMg0KXCdl MFwnZWMgXCdmMVwnZjJcJ2YwXCdlZVwnZThcJ2YyXCdlNVwnZWJcJ2ZjXCdlZFwnZWVcJ2UzXCdl ZSBcJ2VhXCdlZVwnZWRcJ2YyXCdmMFwnZWVcJ2ViXCdmZi4gfXtcYlxmMzhcZnMyMFxpbnNyc2lk Nzc1NzU0MCANClxwYXIge1xsaXN0dGV4dFxwYXJkXHBsYWluXGZzMjJcbG9jaFxhZjNcaGljaFxh ZjNcZGJjaFxhZjBcaW5zcnNpZDc3NTc1NDBcY2hhcnJzaWQxNjU0NTA0NSBcbG9jaFxhZjNcZGJj aFxhZjBcaGljaFxmMyBcJ2I3XHRhYn19e1xiXGYzOFxmczIwXGluc3JzaWQ3NzU3NTQwXGNoYXJy c2lkMTY1NDUwNDUgXCdjZVwnZjFcJ2VlXCdlMVwnZTVcJ2VkXCdlZFwnZWVcJ2YxXCdmMlwnZTgg XCdmMVwnZjJcJ2YwXCdlZVwnZThcJ2YyXCdlNVwnZWJcJ2ZjXCdlZA0KXCdlZVwnZTNcJ2VlIFwn ZWFcJ2VlXCdlZFwnZjJcJ2YwXCdlZVwnZWJcJ2ZmIFwnZTdcJ2UwIFwnZjBcJ2UwXCdlMVwnZWVc J2YyXCdlMFwnZWNcJ2U4IFwnZTIgXCdlZVwnZTFcJ2ViXCdlMFwnZjFcJ2YyXCdlOCBcJ2UyXCdl ZVwnZTRcJ2VlXCdmMVwnZWRcJ2UwXCdlMVwnZTZcJ2U1XCdlZFwnZThcJ2ZmIFwnZTggXCdlYVwn ZTBcJ2VkXCdlMFwnZWJcJ2U4XCdlN1wnZTBcJ2Y2XCdlOFwnZTgsIFwnZmRcJ2ViXCdlNVwnZWFc J2YyXCdmMFwnZWUNClwnZjFcJ2VkXCdlMFwnZTFcJ2U2XCdlNVwnZWRcJ2U4XCdmZiwgXCdmMlwn ZTVcJ2VmXCdlYlwnZWVcJ2UzXCdlMFwnZTdcJ2VlXCdmMVwnZWRcJ2UwXCdlMVwnZTZcJ2U1XCdl ZFwnZThcJ2ZmIFwnZTggXCdlMlwnZTVcJ2VkXCdmMlwnZThcJ2ViXCdmZlwnZjZcJ2U4XCdlOC4g fXtcYlxmMzhcZnMyMFxpbnNyc2lkNzc1NzU0MCANClxwYXIge1xsaXN0dGV4dFxwYXJkXHBsYWlu XGZzMjJcbG9jaFxhZjNcaGljaFxhZjNcZGJjaFxhZjBcaW5zcnNpZDc3NTc1NDBcY2hhcnJzaWQx NjU0NTA0NSBcbG9jaFxhZjNcZGJjaFxhZjBcaGljaFxmMyBcJ2I3XHRhYn19e1xiXGYzOFxmczIw XGluc3JzaWQ3NzU3NTQwXGNoYXJyc2lkMTY1NDUwNDUgXCdjZlwnZjBcJ2VlXCdmNlwnZTVcJ2U0 XCdmM1wnZjBcJ2UwIFwnZTJcJ2ZiXCdlNFwnZTBcJ2Y3XCdlOCBcJ2U3XCdlMFwnZWFcJ2ViXCdm ZVwnZjcNClwnZTVcJ2VkXCdlOFwnZmYgXCdlZSBcJ2YxXCdlZVwnZWVcJ2YyXCdlMlwnZTVcJ2Yy XCdmMVwnZjJcJ2UyXCdlOFwnZTggXCdlZlwnZWVcJ2YxXCdmMlwnZjBcJ2VlXCdlNVwnZWRcJ2Vk XCdlZVwnZTNcJ2VlIFwnZWVcJ2UxXCdmYVwnZTVcJ2VhXCdmMlwnZTAgXCdlZlwnZjBcJ2VlXCdl NVwnZWFcJ2YyXCdlZFwnZWVcJ2U5IFwnZTRcJ2VlXCdlYVwnZjNcJ2VjXCdlNVwnZWRcJ2YyXCdl MFwnZjZcJ2U4XCdlOCBcJ2U4IFwnZjJcJ2YwXCdlNQ0KXCdlMVwnZWV9e1xiXGYzOFxmczIwXGlu c3JzaWQ3NzU3NTQwIFwnZTJcJ2UwXCdlZFwnZThcJ2ZmXCdlYyBcJ2YyXCdlNVwnZjVcJ2VkXCdl OFwnZjdcJ2U1XCdmMVwnZWFcJ2U4XCdmNSBcJ2YwXCdlNVwnZTNcJ2ViXCdlMFwnZWNcJ2U1XCdl ZFwnZjJcJ2VlXCdlMi4NClxwYXIge1xsaXN0dGV4dFxwYXJkXHBsYWluXGZzMjJcbG9jaFxhZjNc aGljaFxhZjNcZGJjaFxhZjBcaW5zcnNpZDc3NTc1NDBcY2hhcnJzaWQxNjU0NTA0NSBcbG9jaFxh ZjNcZGJjaFxhZjBcaGljaFxmMyBcJ2I3XHRhYn19e1xiXGYzOFxmczIwXGluc3JzaWQ3NzU3NTQw XGNoYXJyc2lkMTY1NDUwNDUgXCdjM1wnZWVcJ2YxXCdmM1wnZTRcJ2UwXCdmMFwnZjFcJ2YyXCdl MlwnZTVcJ2VkXCdlZFwnZmJcJ2U1IFwnZWRcJ2UwXCdlNFwnZTdcJ2VlXCdmMA0KXCdlZFwnZmJc J2U1IFwnZWVcJ2YwXCdlM1wnZTBcJ2VkXCdmYiBcJ2UyIFwnZjFcJ2YyXCdmMFwnZWVcJ2U4XCdm MlwnZTVcJ2ViXCdmY1wnZjFcJ2YyXCdlMlwnZTUuIFwnY2ZcJ2YwXCdlMFwnZWFcJ2YyXCdlOFwn ZWFcJ2UwIFwnZWZcJ2YwXCdlOFwnZTJcJ2ViXCdlNVwnZjdcJ2U1XCdlZFwnZThcJ2ZmIFwnZWEg XCdlMFwnZTRcJ2VjfXtcYlxmMzhcZnMyMFxpbnNyc2lkNzc1NzU0MCAufXsNClxiXGYzOFxmczIw XGluc3JzaWQ3NzU3NTQwXGNoYXJyc2lkMTY1NDUwNDUgIFwnZWVcJ2YyXCdlMlwnZTVcJ2YyXCdm MVwnZjJcJ2UyXCdlNVwnZWRcJ2VkXCdlZVwnZjFcJ2YyXCdlOCBcJ2U3XCdlMCBcJ2VkXCdlMFwn ZjBcJ2YzXCdmOFwnZTVcJ2VkXCdlOFwnZmYgXCdlMiBcJ2YxXCdmNFwnZTVcJ2YwXCdlNSBcJ2Uz XCdmMFwnZTBcJ2U0XCdlZVwnZjFcJ2YyXCdmMFwnZWVcJ2U4XCdmMlwnZTVcJ2ViXCdmY1wnZWRc J2VlXCdlOSBcJ2U0XCdlNQ0KXCdmZlwnZjJcJ2U1XCdlYlwnZmNcJ2VkXCdlZVwnZjFcJ2YyXCdl OC4NClxwYXIgfVxwYXJkIFxxbCBcbGkwXHJpMFx3aWRjdGxwYXJcYXNwYWxwaGFcYXNwbnVtXGZh YXV0b1xhZGp1c3RyaWdodFxyaW4wXGxpbjBcaXRhcDBccGFyYXJzaWQ3NzU3NTQwIHtcYlxmMzhc ZnMyMFxpbnNyc2lkNzc1NzU0MFxjaGFycnNpZDE2NTQ1MDQ1IA0KXHBhciB9XHBhcmQgXHFsIFxs aTBccmkwXHNsLTJcc2xtdWx0MFxub3dpZGN0bHBhclxmYWF1dG9ccmluMFxsaW4wXGl0YXAwXHBh cmFyc2lkNzc1NzU0MCB7XGluc3JzaWQ3NzU3NTQwIA0KXHBhciB9XHBhcmQgXHFsIFxsaTBccmkw XG5vd2lkY3RscGFyXGZhYXV0b1xyaW4wXGxpbjBcaXRhcDBccGFyYXJzaWQ3NzU3NTQwIHtcYlxp XGluc3JzaWQ3NzU3NTQwIFwnYzggXCdlNFwnZjBcJ2YzXCdlM1wnZThcJ2U1IFwnZTBcJ2VhXCdm MlwnZjNcJ2UwXCdlYlwnZmNcJ2VkXCdmYlwnZTUgXCdmMlwnZTVcJ2VjXCdmYlwnODV9e1xiXGlu c3JzaWQ3NzU3NTQwIA0KXHBhciB9XHBhcmQgXHFsIFxsaTBccmkwXHNsLTEwXHNsbXVsdDBcbm93 aWRjdGxwYXJcZmFhdXRvXHJpbjBcbGluMFxpdGFwMFxwYXJhcnNpZDc3NTc1NDAge1xpbnNyc2lk Nzc1NzU0MCANClxwYXIgfVxwYXJkIFxxbCBcbGkwXHJpMzQwXHNsMjM3XHNsbXVsdDFcbm93aWRj dGxwYXJcbm9vdmVyZmxvd1xmYWF1dG9ccmluMzQwXGxpbjBcaXRhcDBccGFyYXJzaWQ3NzU3NTQw IHtcYlxmczMyXGNmNlxpbnNyc2lkNzc1NzU0MCANClxwYXIgXCdkMFwnZTVcJ2UzXCdlOFwnZjFc J2YyXCdmMFwnZTBcJ2Y2XCdlOFwnZmZ9e1xiXGYzOVxmczMyXGNmNlxpbnNyc2lkNzc1NzU0MCAs fXtcYlxmczMyXGNmNlxpbnNyc2lkNzc1NzU0MCAgXCdmM1wnZjFcJ2ViXCdlZVwnZTJcJ2U4XCdm Zn17XGJcZjM5XGZzMzJcY2Y2XGluc3JzaWQ3NzU3NTQwICx9e1xiXGZzMzJcY2Y2XGluc3JzaWQ3 NzU3NTQwICBcJ2YxXCdlZlwnZThcJ2YxXCdlZVwnZWEgXCdlMlwnZmJcJ2YxXCdmMlwnZjNcJ2Vm XCdlYg0KXCdlNVwnZWRcJ2U4XCdlOSBcJ2VmXCdmMFwnZWVcJ2YxXCdmY1wnZTFcJ2UwIFwnZjNc J2YyXCdlZVwnZjdcJ2VkXCdmZlwnZjJcJ2ZjIFwnZWZcJ2VlIFwnZjJcJ2U1XCdlYlwnZTVcJ2Y0 XCdlZVwnZWRcJ2YzIH17XGJcZjM5XGZzMzJcY2Y2XGluc3JzaWQ4MzI0NzIyIDp9e1xiXGZzNTJc Y2Y2XGluc3JzaWQ2NTc3Mjc1ICB9e1xiXGYzOVxmczMyXGNmNlxpbnNyc2lkMjIzMDI0NSAoODEy fXtcYlxmMzlcZnMzMlxjZjZcaW5zcnNpZDY1NzcyNzUgDQopIH17XGJcZnM1MlxjZjZcaW5zcnNp ZDIyMzAyNDUgOTg0fXtcYlxmczUyXGNmNlxpbnNyc2lkNjU3NzI3NSAgfXtcYlxmczUyXGNmNlxp bnNyc2lkMjIzMDI0NSA1M317XGJcZnM1MlxjZjZcaW5zcnNpZDY1NzcyNzUgIH17XGJcZnM1Mlxj ZjZcaW5zcnNpZDIyMzAyNDUgNjN9e1xiXGZzNTJcY2Y2XGluc3JzaWQ2NTc3Mjc1IC59e1xjZjZc aW5zcnNpZDc3NTc1NDAgDQpccGFyIH1ccGFyZCBccWwgXGxpMFxyaTBcc2wtNlxzbG11bHQwXG5v d2lkY3RscGFyXGZhYXV0b1xyaW4wXGxpbjBcaXRhcDBccGFyYXJzaWQ3NzU3NTQwIHtcaW5zcnNp ZDc3NTc1NDAgDQpccGFyIH1ccGFyZCBccWwgXGxpMFxyaTI2MFxzbDIzMlxzbG11bHQxXG5vd2lk Y3RscGFyXG5vb3ZlcmZsb3dcZmFhdXRvXHJpbjI2MFxsaW4wXGl0YXAwXHBhcmFyc2lkNzc1NzU0 MCB7XGluc3JzaWQ3NzU3NTQwIA0KXHBhciB9e1xsYW5nMTAyNFxsYW5nZmUxMDI0XG5vcHJvb2Zc aW5zcnNpZDIyMzAyNDUge1xzaHB7XCpcc2hwaW5zdFxzaHBsZWZ0NDk4NVxzaHB0b3AzODhcc2hw cmlnaHQ3Mzg1XHNocGJvdHRvbTI3NDJcc2hwZmhkcjBcc2hwYnhjb2x1bW5cc2hwYnhpZ25vcmVc c2hwYnlwYXJhXHNocGJ5aWdub3JlXHNocHdyM1xzaHB3cmswXHNocGZibHd0eHQxXHNocHoxXHNo cGxpZDEwMjcNCntcc3B7XHNuIHNoYXBlVHlwZX17XHN2IDc1fX17XHNwe1xzbiBmRmxpcEh9e1xz diAwfX17XHNwe1xzbiBmRmxpcFZ9e1xzdiAwfX17XHNwe1xzbiBwaWJ9e1xzdiB7XHBpY3RccGlj c2NhbGV4NDRccGljc2NhbGV5NDRccGljY3JvcGwwXHBpY2Nyb3ByMFxwaWNjcm9wdDBccGljY3Jv cGIwDQpccGljdzk3MTBccGljaDk1MjVccGljd2dvYWw1NTA1XHBpY2hnb2FsNTQwMFxqcGVnYmxp cFxibGlwdGFnNDI1NjUwNzcze1wqXGJsaXB1aWQgMTk1ZWVhNTUzZDVmNmM4ZGFkMWM2YzIyOGI3 M2FhZTN9ZmZkOGZmZTAwMDEwNGE0NjQ5NDYwMDAxMDEwMDAwMDEwMDAxMDAwMGZmZGIwMDQzMDAw ODA2MDYwNzA2MDUwODA3MDcwNzA5MDkwODBhMGMxNDBkMGMwYjBiMGMxOTEyMTMwZjE0MWQxYTFm MWUxZDFhMWMxYzIwMjQyZTI3MjANCjIyMmMyMzFjMWMyODM3MjkyYzMwMzEzNDM0MzQxZjI3Mzkz ZDM4MzIzYzJlMzMzNDMyZmZkYjAwNDMwMTA5MDkwOTBjMGIwYzE4MGQwZDE4MzIyMTFjMjEzMjMy MzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyDQozMjMyMzIzMjMyMzIzMjMyMzIz MjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzJmZmMwMDAxMTA4MDE2ODAx NmYwMzAxMjIwMDAyMTEwMTAzMTEwMWZmYzQwMDFmMDAwMDAxMDUwMTAxMDEwMTAxMDEwMA0KMDAw MDAwMDAwMDAwMDAwMTAyMDMwNDA1MDYwNzA4MDkwYTBiZmZjNDAwYjUxMDAwMDIwMTAzMDMwMjA0 MDMwNTA1MDQwNDAwMDAwMTdkMDEwMjAzMDAwNDExMDUxMjIxMzE0MTA2MTM1MTYxMDcyMjcxMTQz MjgxOTFhMTA4MjMNCjQyYjFjMTE1NTJkMWYwMjQzMzYyNzI4MjA5MGExNjE3MTgxOTFhMjUyNjI3 MjgyOTJhMzQzNTM2MzczODM5M2E0MzQ0NDU0NjQ3NDg0OTRhNTM1NDU1NTY1NzU4NTk1YTYzNjQ2 NTY2Njc2ODY5NmE3Mzc0NzU3Njc3Nzg3OTdhDQo4Mzg0ODU4Njg3ODg4OThhOTI5Mzk0OTU5Njk3 OTg5OTlhYTJhM2E0YTVhNmE3YThhOWFhYjJiM2I0YjViNmI3YjhiOWJhYzJjM2M0YzVjNmM3Yzhj OWNhZDJkM2Q0ZDVkNmQ3ZDhkOWRhZTFlMmUzZTRlNWU2ZTdlOGU5ZWFmMQ0KZjJmM2Y0ZjVmNmY3 ZjhmOWZhZmZjNDAwMWYwMTAwMDMwMTAxMDEwMTAxMDEwMTAxMDEwMDAwMDAwMDAwMDAwMTAyMDMw NDA1MDYwNzA4MDkwYTBiZmZjNDAwYjUxMTAwMDIwMTAyMDQwNDAzMDQwNzA1MDQwNDAwMDEwMjc3 MDANCjAxMDIwMzExMDQwNTIxMzEwNjEyNDE1MTA3NjE3MTEzMjIzMjgxMDgxNDQyOTFhMWIxYzEw OTIzMzM1MmYwMTU2MjcyZDEwYTE2MjQzNGUxMjVmMTE3MTgxOTFhMjYyNzI4MjkyYTM1MzYzNzM4 MzkzYTQzNDQ0NTQ2NDc0ODQ5DQo0YTUzNTQ1NTU2NTc1ODU5NWE2MzY0NjU2NjY3Njg2OTZhNzM3 NDc1NzY3Nzc4Nzk3YTgyODM4NDg1ODY4Nzg4ODk4YTkyOTM5NDk1OTY5Nzk4OTk5YWEyYTNhNGE1 YTZhN2E4YTlhYWIyYjNiNGI1YjZiN2I4YjliYWMyYzNjNA0KYzVjNmM3YzhjOWNhZDJkM2Q0ZDVk NmQ3ZDhkOWRhZTJlM2U0ZTVlNmU3ZThlOWVhZjJmM2Y0ZjVmNmY3ZjhmOWZhZmZkYTAwMGMwMzAx MDAwMjExMDMxMTAwM2YwMGY3ZWEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODANCjBhMjhh MjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOWIyNDg5MTQ2ZDI0OGVhODhhMzI1OThlMDBm YzZiOGZkNjNlMmI3ODIzNDQ3NjhlZTc1ZmI2OTI1MWZmMmNlZDczMzlmYTY1MDEwM2YxMzQwMWQ5 NTE1ZTJkN2RmDQpiNDVlOTI2NWYyYjQ2ZDAzNTFiZTkwZjAzY2Q2NThiMjdiNjAwZGM3ZDNiMGFh NjdlMjVmYzU1ZDY3MGRhM2Y4MWZlY2YxMTE5MGQzNWI0ODcyM2ZkZTYyYTNiOGVkNDAxZWViNDU3 ODY3ZDlmZTNkZWE4NzBmM2RhZTljYTRlMw0KMTliNzE4Yzc3Y2E4NjNjZDJmZmMyMGRmMWEyZWJm N2IyZjhkMmQ2MTczZDUwNWQzYWUzZjA1OGYxNDAxZWU1NDU3ODYwZjg1MWYxMzQ4MDViZTIzZGQw M2RjMGJlYjljN2YzYTBmYzJiZjhhMTE3Y2YwZmM0NWI4NzkxNzk1NTkNCjJmYWUzNjkzZWZkN2Y5 MWEwMGY3M2EyYmMzN2ZlMTA5ZjhkNTY3ZjNjMWUzMWI1OWQ5YjgyYTZlNTliMWVmZjNjNzhhNmVl ZjhmN2E0ZmYwZGFlYTUxYTY3ZmU3ZGNmMDNmZWY5NjM5ZmNlODAzZGQyOGFmMGFmZjAwODVhZGYx DQoyZjQ0Y2ZmNmVmODExYTU4ZDRmMmYwYzEyYzYzZmVmYTFiZDdiOGFkMWQzN2Y2OGJmMGY0ZDIw OGY1NWQyNzUxYjA3Y2UwOTUwYjJhOGZhZjIwZmU4NjgwM2Q5MjhhZTU3NDZmODkzZTBlZDdkODI1 ODZiZjY4NjUzZDIzOTk4Yw0KMmU0ZmEwMGUwMTNmODU3NTIwODYwMDgyMDgzYzgyMjgwMTY4YTI4 YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhh MDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGENCjAwMjhhMjhhMDAyOGEyOGEwMDI4YWYz ZWYxYjdjNjBmMGU3ODM1ZTRiNGRlNzUxZDRkNzIwZGFkYmIwZjkwZmEzYjc0NWZhNzI3ZGFiY2Y3 NmZjNTVmOGIxZjNlZWZmODQ3ZjQzOTNhMGNiNDJhZWE3ZmYxZjkzMjNlOGE3ZGE4DQowM2QzZmM0 ZmYxNTdjMjNlMTQyZjE1ZGVhNmI3MTc2YmMxYjViM2ZkZWM4MGZhMWM3MGE3ZDk4OGFmM2U2Zjhh YmUzZWYxYTQ4ZDE3ODFmYzMwNjBiNjI3MDJlZTc1MGU0N2JlZTZjNDYzZTlmMzUyNjlmZTE0Zjg3 M2UwNWJhMQ0KNjcyYzMzZjhiN2M0NjM5ZmIyYzMwZjllNTRmZjAwZDczMWYyMjBlOWY3YzkzNWRi YTQzZjEwN2M0MDhhOGE2YzNjMjNhN2UzMGE5MWE4YmFiYWM3YTdmY2YzNWUzZDMyNDUwMDcwMzNm YzI1ZjExZWIxMTM2YTNmMTBiYzcwYjYNCmYwNjc3M2M3ZTc2ZTQ0ZmM1OGFhMjdlMDA4YTkzNGVk MTNlMTFlOTMzN2Q5ZjRjZDNiNTFmMTY1ZjJmMDQ1YmM0Zjc1ZjllZGRiMWQ3YTJkOTdjMzBmMGZj NzM4YmFkNWZlZDVhZmRlOGU3Y2ZkNWE2MzNlM2U4OWY3MDBmYzJiDQphZmI3YjZiN2IzODE2MGI2 ODIzODIyNWZiYjFjNDgxNTQ3ZDAwYTAwZjNlYjBiZWYxNDg4ODI3ODZiZTFlZTlmYTJkYjkxYzQ5 N2YzYTQ1YzdiYzcxMDI0N2UzNTczZmIxYmUyNDVmZTBkZDc4YjM0YWQyZjlmYmJhNzY5ZGU3Nw0K ZWIyOWZlOTVkZDU1NThmNTJiMTk5NmU5YTFiYjgyNTE2OGM1MmUzY2I3MGM2MjYwMzI1NTgwZTg0 MGVkZDY4MDM5MGZmODU3ZGE4NWNmM2E4ZjhlZmM0YjM3YWFkYmNlOTZlYTQ3ZDExNzNkN2RlOGZm MDA4NTU1YTJjOWNkZDYNCmE5ZTIwYmI3ZmVmY2ZhYWNhNGUzZDM4MjM4YWVhZjQ3ZDYyYzc1ZmQy NmRmNTRkMzI3MTNkOWRjMDI2MzkwMjk1ZGMwMTIwZjA3OWVhMGQ1MmI5ZjEzZGE1YWY4YzJjYmMz NGYxNGRmNmJiYmI2N2I5OGU0MDA2YzAxNGUwODNjDQplNzNmODUwMDYwZmYwMGMyOWVmMDJmZmQw MWU2ZmYwMGMxODVjZmZmMDAxY2EzZmUxNGZmMDA4MjA3MjlhNTVjNDZlM2VlYmFlYTE3Mzk1M2Vh M2Y3OWQ2YjRhMGYxYWRhOGYxN2RmZjAwODczNTJiNzZiMGI4Yjc4N2VkMzA0Yg0KMmM4M2NiYjk4 NzkyY2NhNzhjNjNiODNlODdkMmE3ZjA5NzhhNTNjNWQ2MzcxYThkYjU4Y2QwNjllYjMzNDU2ZDNj YTcxZjY5NTUzODJlYTNiMmU3ZDdkZmQyODAzMWJmZTE1NjY5MzFmZjAwYzdhNmIzZTIzYjMyN2Vm MTgzNTYNCjk0MTZmYWU0OWEzZmUxMDJkNjZkNzlkMzNjN2ZlMjA4ODhlODJlZmNhYmEwM2QzODY1 MWM3ZjNhZTkzYzRiYWZkYWY4NWJjM2I3YmFkNWVhNDhmNmY2ODgxOTk2MjAwYjM2NDg1MDA2N2Rj OGFlNThmYzViZDBlZGFkYzVjNmFiDQphNWViZmE1NDA0MDZmM2FmNzRjOTE1MzA3YTFjYWU3ODI3 OGEwMDkzZmIzM2UyNWU5ZDhmYjM3ODg3NDRkNWQ0MWU0NWZkOTM1YmIxMWY1ODhlMzNmODU2NzZh NTdiYWQ0ZDE5NGYxNWZjMzI4MzU0OGZhMTlmNGY5MjJiYWNmNg0KZTExYzA3MTVlODkyZGU1YjQw ZDBhY2Q3MTE0NGQzYjZjODg0OGUxNGM4ZGU4YTBmNTNlZDUzODIwOGM4MzlhMDBmMDFiZGYwY2Zj MWZkNzY3MzAzYmRlZjg1YjUwM2Q2MWJhMGY2YzQxZjcxMjgyOWY5MTE1MjQ1ZjBjN2M3OWUNCjE1 OGQ2ZjNjMGRlMmY1YmViNWRiOTQ4MTlmNmFiMGY2NTYyZDE5ZmFlNDU3YjhkZjY5ZDY1YTlkYjli N2JmYjM4MmVhMTNkNjM5ZTMwZWJmOTFhZTQyZTdlMTg2OTUwY2NkNzNlMWRiZWQ0M2MzYjcyNGVl Mjc0ZTk4ODg5OGZmDQowMGI1MTM2NTQ4ZjYxOGEwMGUxMmRmZTMzZjhhM2MyYjcyYjY3ZTNjZjBh Y2QxYWU3NjhiOWI3NDI4NWJkYzAyNGEzZmZjMDU4NTdhNWY4NjNlMjI3ODVmYzVjMTU3NGFkNTYy MzcyN2ZlNWQ2NmZkZGNhM2ZlMDI3YWZkNDY0NQ0KNjI1ZDQ5ZTM5ZDFhZGRlZGY1N2QyZWMzYzVm YTU5MTg3N2I3NDU4NmUwYWY3ZGQxMzY1MWZlOGI1YzNkZGY4MDdjMDFlM2JiODdmZjAwODQ2NmY2 NWYwZWViZjFmY2NkNjEzNDY2MjYwZGQ3OTg5YjA0NzZlNTBlMDdhNTAwN2INCmRkMTVmM2U4ZjEw ZmM1MGY4NTJjMTM1ZGI2M2FlZTg4ODdmZTNlMGI5OTAyOGY2OTcxYjk3ZmUwNjA4ZjRhZjUwZjA1 ZmM0ZGYwZTc4ZGQwNDc2MTcwNjBiZjAzMmQ2NTcxODU5MzhlYTU3YjMwZmE3ZTM4YTAwZWNhOGEy OGEwDQowMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhh MjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMmJjZDNlMjBmYzVmZDM3YzI2ZWRhNWU5NDhiYTllYmFj NzYwODEzOTQ4OThmNGRlNDcyNA0KZmYwMGIyMzlmYTUwMDc2MWUyNmYxNjY4YmUxMGQzMGRmNmIz NzhiMDQ2NzIyMzQxY2JjYTQ3NjU1ZWE0ZmU4M2JlMmJjNmFlN2M2MWUzY2Y4Yjc3NzJlOWZlMTJi NTkzNDhkMGY3MTQ5NmYxZDhhOTIzYjg2OTA3N2ZmNjUzOWUNCjc5MjQ1MjY5OWYwZmVlMzUxNjkz YzcxZjE2ZjU0MzFjMGFhMWQ2Y2U1N2RhNDJlNzIxNTgwZmJhM2QyMzVlNGU3OWMxYzgzZGM1YTdm YzI0N2UzMmI0OGVkZjQ3ODliYzI3ZTE0NTFiMjI5MTIzMDk3OTcxMWZmZDMzNWU5MGE5DQplYzdh ZjcxZDY4MDM5YWQyN2MzM2UwY2Y4NmQ3OTFkYWM1NmQyZjhhYmM2MGMzMjk2ZjEyMDc2OGNmMWNl ZGU1NjIxZDNlNjZjOWU2YmFmZjAwZjg0NjdjNWJlMmFjNDllMjhkNmZmYjMyYzFmYWU5M2E0MWRh NDhmNDkyNzNmMw0KMWY0MjE3MDJiYTdmMGY3ODViNDdmMGI1OTliNmQyYWNkNjJkZTc3NGIyYjFk ZDJjYWRkZDlkY2YyYzdlYjUzZWI3YWVlOWJlMWRkMzVhZmYwMDU0YjkxMDQwMTgyMGUwYjMzYjFl OGFhYTM5NjI3ZDA1MDAzNzQ0ZjBmNjkxZTENCmJiMjE2N2EzZTlmMDU5YzNjNjQ0NmJjYjFmNTYz ZDU4ZmI5MjZiNGM5MDNhOWFlNWY0MGYxZjY4YmUyMWQ0ZTRkMmUyZmI1ZDllYTQ4OWU2N2Q4ZWZl ZGRhMDk1OTNmYmNhMWJhOGFlMjNjMTllMTlkMmJlMjU2OGY3OWUyMmYxDQo2NDcyZGZkZmNmNzcz NDQyMTY5ZGQ1NmM5NTRlMDQ2OGFhNDAwNDBjMWNmNWU2ODAzZDBmNTZmMTNkYTY4ZGUyMGQxNzQ4 Yjk4NjZkZGFiM2M5MWMzMzgwM2NiNDY1NWNlZDYzOWNlNGYwMDcxNTk1ZTI5ZjExZWExZTFmZjE4 Zg0KODVhM2RjOWZkOGRhOTRlZjY3NzAwYTBjYWNjNDdlZThlZWY3M2RiZDhkNzFiYTRmODc1YjU5 OWY1YmY4NzlhYzZhMzc4ZjJlODU3MTBkZjY5MWE5MDdkZDM0NDhjMzI5YzllYTU3YTdlM2M2MzAy YWU3OGI3ZTE5NmE3N2RlMTgNCmJhYmI5ZmM0MWE5ZWI3YWY1OWE4OWI0ZmYzMGFjNDkxYmFiMDZm OTYzNWUwYjEwMDhjOWNmNTE0MDBlODdjNWQyNzg0ZmUyNTc4YTc0YWJmOGI1NmQ0ZDJlYmM4YmNi MGI3YjQ4NWVlMWQ1NGFlMWMwNWNlMTU3NzYwNzUwMzNmDQphMzdlMWY2YTBlZmYwMDEyN2M1ZDYx NzdhNWRjZTljOWFhNDUxNmEzMTVhNWUyYTg3YzcyOTIxMjAxM2MxNjM1ZDA0M2EwZWFkNzdlM2Fk MDNjNWJlNGM1NmE1YjQ5NmI1ZDRlMDkxZjBlYTRlMWQ1NDYzMjFiMGU0ZjUzOGMwZg0KYTU2Y2Rj Zjg1ZTE5ZmM2ZDY1ZTI3NWJhOTIzOWVkYWQxZWQxYTI1MDM2Y2E4YzcyMzI3ZDhmM2M1MDA3OThm YzMzYjVmMWM0YmUwODQ4MzQ5ZDc3NGJiNWI0YjA5ZTdiNjU4ZWU2Yzk5OWIyYWU0OTI1Yjc3NGNi N2E3MTQ2OWYNCmUyOWJhZjExZjhhN2UxZTc4ODJmMjA0ODY3Mzc1N2ZhNzVjNzkyZDg4NWRiNjAw MTk0OWNlNDFlYmY1MTVkOTM3YzIzZjBhNGQzNWNiZGNjNTdkM2E1Y2NlZDcxMjQyZjdiMjJjNjVk OGU1OGVkNTIwNzM1ZDJjNWUxOWQxMjBiDQo3ZDNhZGUzZDJlZDk2MWQzNWI3ZDlhMDRlMjE2ZjU1 ZjdmN2EwMGYzMmY4YTU2MTI3OGZmMDBjNDUwNzg1YjQyODIxNmQ0NzRjODVlZTZlZWY1ODkwMjE1 NjQyMTYwYzhmZWZlNDY0N2E3M2ViNWRkNzgwMzVmYjNkN2JjMmI2Zg0KZjY1YjQ1YjE5NmNiZmQw ZWU2YzAwYzdkOTY0NGUwYTYzZDM4ZTNkYWI3MmRiNGZkMzc0YzkyNzkyZDZkMmQ2ZDY0Yjk3ZjMy NjY4YTM1NDMyYjdmNzk4OGZiYzdkY2QyNWE2OTlhNjViNWU1Y2RlZDlkOTVhNDU3MzcyNzMzY2YN CjBjNGFhZjI5MWZkZTYwMzI3ZjFhMDBlMjdlMzQ3ZWZmMDBjMGIxNjk5YmIwNzUyZDQ2ZGFkMDcz ODNjYmVlZTBmZjAwYzA3YmQyN2M2MTNmNjhmMGNlOTVhNDhjOTNhOWViMTZiNmJiNDFjNjQxNmNm ZDBmZGQxZDZiYjhiZmQyDQphYzc1MzM2YzZmYWQ2M2I4ZmIyY2NiNzEwZjk4MzNiMjQ1ZThjM2Rj NTU3ZDVmYzNmYTdlYjk3MWE2Y2Q3ZDFiM2JlOWQ3NGI3NzZmODYyMDA5MTdhMTIzYTFhMDBlMTNj NmZhNGMzZTMxZjg5ZmUxZGYwZGRjNDkyMmQ5NThkOQ0KY2RhOGRkMmM0ZTU0YmFiMTExYWFlNDc0 YzkwNDdhZTA5ZTk5YTZjYmE1NTk3ODFmZTI5Zjg2NmQzYzNhOGY2YjZiYWQyNWM0NTdiNjExYjEz MTMwOGUzMGNiMjAwNGUwMzAzZDQ4ZWMwZmE5Y2U3NTllOTNhYzc4OTdlMjZmOGENCjdjNDlhMjZh NzE1OWRkZTk5M2M3YTc1YjdkYTIyMzI0MzJhYWE3ZWY1MWM2NDEwMzc2ZDM5MWQzZjFjZDc1MWE1 ZjgzMzU5ZmVkOWJjZjEyZWJiYWE1YmRlNmJhNmQxYWQ2YzkyZGUyMjk2ZjY4MDgzY2FlNzI0OTI3 YTkzZWE0DQo3MzQwMTEzZmM0M2Q0ZjUyZDUyZmFkYmMyOWUxNTk3NWJiNWIwOTBjMzNkZTFiZDRi NzhjYzgzYWFjN2I4MWRmOGZjM2Y1Y2Q3NDVlMTVmMTRkOTc4YjM0YjkyZWVkNjI5ZWRlNTgyNjZi N2I5YjViODVkYjI0MTJhZmRlNTYxNQ0KYzM3YzJmZjEzZjg2ZmMzOWYwZmEzZDM3NTNkNDZkNzRk ZDQ3NGY5MjU1YmZiN2JhOTAyNGEyNWRlYzQ5YzFlNWIyMzE4YzY3ZDNiNjJiMjc0ZGQ2NmYzNDhm MDNmOGFiYzVmMDQxMmMzN2JlMjVkNDhhNjkxMDMwZGFlZGJmZTQNCjg5YmViY2IzN2ZjMDdkZTgw M2RhYTM5MjM5YTM1OTIyNzU3NDZlNDMyOWM4M2Y4ZDYzNzg4N2MyNWExZjhhMjE1NGQ1YWMyMzlh NDRmZjAwNTUzYWZjOTJjNDdhODJhZTM5MWNmYmQ3MWI2MWUwOGQzM2UxYmY4N2UxZDZkNzU5DQpk NGVjZDc0ZWI3MTJlYTEwYzUzZTYxYmM2MGJjODI4ZDkwMDk2MzgxOGM3NWY1MzlhN2U4OWYxM2I1 MTRmMGZkOTZhOWUyYWYwY2RmZTlkNjkzYjYxZWZlMzQxZTRjNjE5YmU0NjY1ZGM1ZDU0ODIzZTYy MzE5MzQwMTY1YjRiZg0KMWJmODRkNTliNGRiZjVmMTQ2OTRhMzliMWQ0MDg0YmE1NWY0NTk4NzBl N2ZkZTE1YzVlYTFlMDZmMDdmYzQzOWU2YmFmMGJkYzNmODc3YzRmNmU3N2NkNjEyYzY2MTY1NzE4 ZTVhM2VhYmRiZTY0ZTM5ZTg0ZDdiYTAyMTk0MTANCjQxMDc5MDQ3N2FlN2ZjNGJlMGJkMWZjNGZl NWNkNzUxNDk2ZmE4NDNjZGJlYTE2YWZlNTVjNDI3YjZkNzFjZTM5ZTg3MjI4MDNjOWI0Y2Y4OWRl MmRmODc3YThjN2EyZmM0MWQzZTdiYWI1Yzk1OGFmZTMxOTc2MDNiODZlOTIwDQpmYzk4Njc5ZjRh ZjZhZDE3NWNkMzNjNDNhNjQ3YThlOTM3OTE1ZGRhYzlkMWUzM2QwZmExMWQ0MWY2M2NkNzAxYWE1 ZTZhN2UxZmIyN2QyZmM3ZjY1MGViZmUxOTk3ZTRmZWQ2OGEwZjllMWY0ZjNlMzFkM2ZkZjVlOWY1 MzVjNQ0KNmExZTBjZjEwN2MzOWJhZmY4NGIzZTFjZGY5ZDRiNDM5ODA5MjViNTU2ZjM3MjllZTA3 ZmFjNWY0NjFmMzBjZmQ0ZDAwN2QwOTQ1NzBkZTAwZjhhM2EyZjhlYWRkNjI4ZDg1YTZhYWFiOTky Y2E0NmU0ZTNhOTQzZmM0M2Y1MWQNCmM1NzczNDAwNTE0NTE0MDA1MTQ1MTQwMDUxNDUxNDAwNTE0 NTE0MDA1MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ3NGFmMGJmMWNmOGU3NThmMWNmODkzZmUx MDVmMDJjYjk4OWIyYjc5N2QxM2UwMzI4ZmJjMDMwZTkxOGNmDQoyNDdkZTNjMGY3MDBiNWUzZWY4 YTc3ZGFhZWFhYmUwZmYwMDE3YjlkNGU2NzMxNGQ3OTA4Yzg0ZjUwODdhNzFjZTVmYTBjNzA3Yjg0 ZDBiYzJkYTJmYzI5OGFkMjRiYWI1NmYxMDc4ZGFmYjI2ZGVkZTBmOTk4MWU3MjU3M2Y3MQ0KNDc3 OTA4Y2Y1ZjcxNTczNDhkMzJjM2UxYWM1MTc4NjdjMjk2ZDE2YjNlMzJiZDVkZDNjZWZjMmMyYmZk Zjk0OGNlYzhjNzE4NWVhN2VhNmJiN2YwOWY4MzYxZjBmNzlkYTg1ZTRlNzUwZDdlZjM5YmRkNDY1 MWYzMzlmZWVhMGYNCmUxNDFkODBmNDE0MDE5YmE0ZjgyYWY3NTVkNGExZDdiYzZmM2M3N2ZhODQ2 NzdkYWU5ZjFmZjAwYzdhZDk3ZmJhYTdlZmJmZjAwYjQ3M2QzZDg1Nzc1NTk1ZTIzZjEwZDhmODVm NDQ5ZjU1ZDQwYmY5MzE2MTU1MjM1ZGNmMjM5DQozODU0NTFkYzkzNWM3NWNmYzQ0ZjEwNjg4OTE2 YTFlMjRmMDY0ZjYxYTI0OGMwM2RkNDM3NGIzYmRiMDI3MDBjODgwNjQwZTk5ZjRjZmFmMTQwMWEx YWE3OGZhZWQ3NTRiZGIwZjBlNzg2YWYzNWU3ZDNjZWRiZDk2Mjk5MjE4ZQ0KMjdjNjc2Mjk2ZmJl ZTNiYThlOTVjZDc4YzJkNTJjYmM0ZmUxNWY4OGQ3NTZiNzE2YjYyOGU5MWVhNzZiNzFkNjBkY2Fj YjFjYWNhMzIzMjg1YzgzZGZhN2JkNDllMThmMTE1OGY4MmJjNTdhY2U4ZmFjZGRjMTA2OTlhYzVk M2UNCmFmYTVlYTcyMTBiMGNjYjJlMGIyMTdlODA4ZTMxOWZlYWI5ZDFiN2JmNGYxZTc4ZGI1YWQz NjBiYzNhOGY4NDQ2OTVmNjY5Y2M2MDE4N2VkNGNlMGZjOGUwN2NjNDI3MzljOWMxYzUwMDQ1ZjE2 ZDZkNTM0NmQxM2M0MTYzMmE3DQpmNmJkYTZhMzAxZDM5ZTI2MDVhN2RlYzAzNDYwOGVhYTQxY2Zl MWVmNTY2NmYwNzc4OTdjM2ZlMjJkNDM1MmYwNTVmZTk5MWRhZWE3Mjc5ZDc1YTdlYTQ4ZmU1YWNk ZGRkMGE3MjMzZGM3ZmYwMDU4MGM0Zjg1NWUxMmQyZjQ5Yg0KZWQ0ZWNmNTJkMjczYWQ2ODM3MjYz OGVmZTRkZTUyNDg5ODE2NDc1MGM3NjJiNmRlYmI0MDM4YzY3YWQ2ZGViZGYxN2Y0M2QzZWY3ZmIy ZjQzODY3ZjEwZWFjZGMyZGI2OWMzN2E4M2VlZTMyM2YyY2UzYmQwMDZkNzg0ZmMyOTMNCmU4Yjc5 YThlYjFhYWRmMmRmZWI5YTkzMjliOTlkMTM2MjIyYThjMmM3MWFmNjUxZjk5ZWY1NjdjNDFlMzZm MGRmODVkMThlYjFhYzViNWIzODE5ZjI3NzZlOTRmZDExNzJkZmE1NzExZmYwMDA4ZTdjNDlmMWEx MzJlYmRhZWE3DQo4NmY0ZTkzZmU2MWZhNmZjZDM2ZGY0NjkzM2MxZmM0OGY2MTVkMDc4N2ZlMTNm ODQzYzNkMjA5ZTNkMzQ1ZWRlMDM5Mzc1N2VkZTczOTNlYjgzZjI4M2VlMDBhMDBjNDNmMTkwZWFj YzYzZjA5Nzg0YjU5ZDY1YjM4ZjM0YzdlNQ0KNDNmNWRkY2ZlYTA1MjAzZjE5NzVjZjk4MGQwYmMz YjExZmUxNmZkZjQ4MDdhZmYxYTkzZjk1N2E4ODUwYTAwNTAwMDFkMDBhNWEwMGYyZWZmODU3M2Uz NmQ0NGVlZDViZTI1ZWEwYmJiOTY0YjA4N2M5MWViYzE1NjFkZmRhODENCmYwM2I0Nzk3MWY2ZGYx MWY4OTJlYzAxYzJjOTdhMzAwZmE4Zjk2YmQ0NjhhMDBmMzE1ZjgwZGUwZDM5ZmI0MWQ0ZWViZmJh NjZiYjI3NmZkMzAwNTBkZjAxZmMxZTBmZjAwYTNjYmFhZGIyZjc1ODZmMzAwOWY1ZTQxYWY0ZWEy DQo4MDNjYmJmZTE0OGU5ZjZmOTNhNzc4YWJjNGI2NTgzYmEzMTFkZTBjMmI3YWYwYTBmZWI0MGYw MDc4ZmYwMDRkZTc0OWY4OTU3MzI4MWMyYTVmZGE4OTdkYjkyYzViYjdiNzVhZjUxYTI4MDNjYWM1 ZTdjNjBkMDA5NmI4ZDJmNA0KNGYxMDQ0NDg2NzM2YjI3OTMyMWUzZGY2OGZmYzc0ZDQ5MWZjNmFi MGIwOTE2MGYxNGY4N2I1OWQwYTYzZDVhNmI3MmYxZmUwYzMwNGZlMGI1ZWExNGM5NjI4ZTY4ZGEz OTYzNTkxMTg2MTk1YzY0MTFmNGEwMGU2YWNhNmYwM2YNCjhkZGQyZmVkYTNkMTc1NzlkNTQxMGVm MGM3MjRhODNiNjQzMGRjYmY4ZTJhZDZiMWUxNmI2ZDZiNWRkMTM1MmI4OWU0MDlhNDQ4ZjJjNTZj YTA3OTZlZTQ2MTU4ZjdjYWY1MTVjZjZiN2YwNzdjMjdhYjRmZjZiYjRiNzliNDdiDQplMDc3MmRj Njk5Mjc5NDQxZmYwMDc3ZWVmZTQwMWY3YWM4ZmIyN2M0ZmYwMDAzN2VmMmRlZjIyZjE4Njk0ODM5 ODI2MWU1ZGQyYWZiMWU0YjFmYzU4ZmI1MDA1NWY4YWRlMjNiN2I5ZjEyZTkzZTFjOTk1ZGY0N2Iz Yjg4MmZiNQ0KZDkxMDY1NjM4OGM4YTExNWYxZGIyNzI0NzVjMTA2YjQ3ZTI1Zjg5MmM3NWVkMDE3 YzIxZTFlYjliN2Q0ZjU1ZDY1OTIyNDRiNjkwNDhiMGM1YjgzMzQ4ZTU3ODAwMDFkZmQ3M2RhYTBm MDE3OGE3YzEzNzlhYWViNzFiNDkzZDkNCmViN2FiZGNlZmJjYjNkNjAwNTcyNzE4MTEyOTIzMDU0 NzM4NWViY2Y0YWY0MmQzN2MzN2EyZThhZDMzZTkzYTU1OGQ4NGIzNjc3YmRiZGJhYTEzZjVjMGU5 ZWQ0MDE4ZGFjY2ZhZGQ5NWE2OWZhMjc4NTI3ZDFlNGJlOGQ1NjM5DQo4ZWExMzlkZDFjNmFiYzM3 OTZiYzljZTNmMGY0ZWUyM2YwZWY4YmI1MTk3YzQ3MmY4NWZjNGI2MTBkYTZiNDkwN2RhNjI5MmQx Y2JkYmRjYzU5YzZlNDI3ZTY1MjBmMTgzZTk1ZTZiNjdhMjc4NzdjMzlhNGRmNDVlM2NkMTM1NQ0K NWQ2YTE5ZTViODNhZDViYzczMzliOWY5ODk1NzQ5OTNlZTljNjMyMTg4Yzc1M2Q2OWRlMWFiZjli YzM3YTNjOWUzYWQ1NWFmZjUxZDVmNTU1MzY1ZTFlYjBiYjczMmNlZDA5NmNhMDI0MGU3M2MxMjdk M2E3ZGVhMDBmNzg3NDUNCjkxMTkxZDQzMjMwYzE1NjE5MDQ1NzlmNWRmODUzNTZmMDZkZDRiYWE3 ODFmNmM5NjRlZGU2NWQ2ODEyYmUyMjkzZDVhMDNmZjAwMmNkZmRiYTFlM2QwMGE4ZmUxMWRmNzg5 YjUxZDNmNWE5YmM0MzdlMmYxNTJmZGUyODE4MjhjDQoyYjhjZjlhMTQ4ZWE4MThlMTdiN2NhNzFj NTdhMWM1MzQ1MzI5NjhhNDQ5MTQzMTUyNTU4MWMxMDcwNDdkNDFhMDBmMGVkNzdjMTVhNjc4ZmFk ZGZjNTNlMDUyZGE0Zjg5NmNhNjI2ZWFjOWZmNzJlYjMwZTQ4NjFmYzEyNjdhMw0KNzQzZGZiOTFi YmYwZDdlMmNmZjZkNGUzYzM3ZTI5MWY2MmYxMTQyZTYyY2M4OWIwNWMzMGVkOGZlMTdmNmU4N2I3 YTU3NGZlMjdmMDc0ZDc1YThjN2UyMmYwZTRmMWU5ZmUyMzgzZmU1YWIwZmRkNWRhNzc4ZTYwM2E4 YzBlMGYNCjUxYzU3MGZhZWY4Nzc0YmY4YjE2ZjMxNTg4NjgzZTM5ZDMzZTU5ZWRlNDNmMzY0NzRj OTFmNzkwZjA1NWM3NGM4ZmE1MDA3YjQ1MTVlM2JmMGNiZTI0ZWEwOWFiNDllMGFmMWFiMTgzNWFi NjZmMmEwOWU3M2NjYzdiMjMxZTg1DQpiMWM4NmZlMjFlZmQ3ZDhhODAwYTI4YTI4MDBhMjhhMjgw MGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGFmMmZmOGMxZjEwZTRmMGQ2OWQxZTgzYTMzM2Jl YmZhODhkOTE4ODg2NWExNDI3MWI4MGViYjg5ZTE0N2Q0ZjYxOQ0KMDBjMmY4OTllM2VkNDNjNDFh YzBmODdmZTBiYzVjNWRkZDY2MmJjYjg4ZGJlZWY1ZGQxODNkMDAwMDFkY2RkODY0N2FkNWVkMzM0 Yjg3ZTFiNjlkNjllMTNmMGM0NTA1ZmYwMDhjZjU0NWRkM2RjYjBjYWMwYmRlNTdlZTIzNWUNCjhh M2I5ZmQ2YWY4Nzc0MzFmMGEzYzJkNmViMWRhYTVmZjhlMzVkNmYyZTA4NGUwZWQ2M2M5NTI3YjIy NzU2MzllNGZiNjA4ZjQ0ZjA3Zjg0OTNjMzU2YjcxM2RjZGM3ZGJiNTliZTdmM2FmZWY5OTcwZDJi OWVjM2QxMDc0MDI4DQowMjVmMDk3ODRlZDNjMjlhNmI0NTFiOWI5YmY5ZDhjYjdiN2QyMjhmMzJl NjQyNzI1OThmYTY0OWMwZWMzZjEzNWE5Nzk3ZWIwYWRjNDE2Y2QwY2RhOGE1YmI0ZDE1YTk5MDA2 N2M3MDM4ZWEwMTM4MTlhYzVmMWJmOGRiNGRmMA0KM2U4NGY3ZjdhZTFlNzcwNTZkYWQ4MWY5YTY3 Yzc0ZjYwM2I5ZWMzZGYwMGYzMTdiZTEyZDYzYzQ5ZTFhZDM3YzQ5NmZhYTU5MmY4Y2EwNGYzZWRh ZmVjODZkODY0NDYzYjg0MmM3OWRlOTgzYjQxM2ZkNGU0MDIwZDUyMGQ1ZmMNCjdmZjA3MzRhZDVh ZGE2ODJlMzU5Yjc5MjNkNDkyMzhhMjI4OTI0YjE5NmNjNWI0OTI3MjM5MWVlNDc2Y2Q1OTk3ZTJj NzgzNzU5ZjA4ZGQyZWExM2Y5NTczMzQwZjBjZmE0Y2IxYjE5OGI5MWI0YzYxNzFjZTQ5YzAzZmNi OWM3DQozYmUwNWIxZDZlZmI0ZjlhZGY0NGYxNzVkZTk1YWU1OGM4Yzc1MGQxYWZlZDIzNzg5MjQ2 NjJjYzQwMDAxMDhjYzQ5MGMzM2U5ZTk1ZWIxYTZlOTIxMjNiN2JkZDU2ZGY0ZjliNWE1OGMwOWFm MjBiNjA5OTM4ZmUxMjcyYzA2Mw0KOGViZjk3NGEwMGU3ZmMwMWUxYTY4M2UxOGU4OWE0Zjg4YWM2 MWI4OWEyODhiYjQzNzUxMDdkOTk2NjY1MDQxMDcwNDJiMDFlZDhhOTNjNGZlMzhmMGRmYzNlYjI4 YWNjYzZhNmU5ODYyZDc0YmIxOGM2ZjcyN2E2MTQ3MGEwOWUNCmU3ZjBjZDczZmUyMGY4ODlhYWVi OWFiY2RlMTlmODdiNmFiNzk3ZDE5ZDk3NWFhMzhmZjQ3YjVmNWMxZTg0ZmJmNGUzODBkNWI3ZTBj Zjg2ZGE3Zjg1ZTU3ZDRlZjY2NmQ1N2M0MTM5ZGQzZWEzNzNmMzM2ZTNkNDI2N2VlOGY3DQplYTdm NGEwMGU2NTdjMzVlMzRmODk0ZTI2ZjE2NWM0OWEwNjgwYzcyYmE0NWEzNjI2OTQ3NmYzMWJmYzdk M2VlOGViNWU4YmEwZjg1ZjQ0ZjBjNWFmZDliNDZkMzYwYjM0M2Y3OGM2YmYzM2ZmYmNjNzkzZjg5 YWQ3YTI4MDBhMg0KOGEyODAwYTI4YThlZTJlMjJiNGI2OTZlNjc3MTFjMzEyMTkyNDczZDE1NDBj OTNmOTUwMDQ5NDU3Y2NiZTMwZjhkNTdmNzM3MTI0MWE2ZGM5MzNkODZiNTI0ZjY5NzMxMGM0MzJk YTgwNTUxNTg2NzJkYzljZjNjNzRhZjVhZjgNCjdmZjE1ZjQ4ZjFjNDg2YzUxNjRiNWQ0NjM0NTNl NTRkOGNjZGM2NTk5NzE5ZTA2M2JmYWQwMDdhMDUxNWU2OWYxYzdjNDdhOTc4NmZjMDkxYzlhNjRk ZTRjOTc5NzQyZDY0NzFmNzgyMzQ2ZTRlZDIzYTFjYThlNmI4MWY4MDdlDQozNmI5OTNjNDM3OWEx ZWE3NzM3ZDdiM2RmODU3ODI0OWE2MzIyYzQyMzU3MmRmNzhlNDY3MjNhN2E1MDA3ZDEzNDUxNDUw MDE0NTE0NTAwMTQ1MTQ1MDA3M2RlMjZmMDNmODc3YzVmMDE0ZDYzNGQ4YTU5NzZlZDRiODUxYjY1 NA0KZmEzOGU3ZjAzOTFlZDVjMTk4N2M3N2YwYmM5MzZmZTZmOGFiYzMxMWZmMDBjYjI2M2ZlOTc2 YzgzZDBmNzAzZjExYzc0NWFmNWRhMjgwMzk4ZDBiYzRkZTE5Zjg4YmExNGViNjkyNDU3NzZmMjJl Y2I5YjM5ZDcwZTk5ZWNlODcNCmY5OGM4ZjQzNTg1ZTI4ZjBjZmY2MWZmNmJmOGMyZDg1YzZhMTdk NjdhNzdkOWY0OWIyNThiNzJkOTcxYjcyOGEzOTI3YjkzZDQwY2QyZjhiN2UxOWFkZWVhM2ZmMDAw OTE3ODUyZWJmYjE3YzQ3MTY1ODRiMTcxMTVjN2I0OGEzDQpkN2Q3MWNmNzA2OTNjMjFmMTIyN2Jh ZDU4Nzg2M2M1ZjYyNzQ4ZjExMjhjMjA2MTg4NmViZGUzM2VhN2QzMjQxZWM3YjUwMDcwZDc3Mzc4 ODc0NGY4N2JhNjY5OTcwOTNlOGQ2OTI0NjJkYWNmNGJiNjNmZTlmYTljZWRjYjE3Ng0KMWZlYTkw YjFjOTAzZTZjMWMxM2M4YWViM2MzMzYxYTZmYzE2Zjg3YjI1ZDZiNzc0Y2Q3OTcyYzI1OTYxNDcy ZGJlNjIzODhhMzVjZTA5MWQzNzc3ZWE3ODAzMWQ5ZGRmODYzNGU3ZjEzMmY4YTRkYjQ5NzNhYWRi ZGFiNDE2ZTgNCmQyN2M4YmQ0ZmNhMGYwYWM3MjQ2N2QwZDc5MGY4OWVjMmY2ZjZlZWNlZWZjNjE3 YjZmNjlhZWViMGM2MWI1YjY3OTQ3OTNhM2Q5MGU2NTkzMjc4MzIxNWUwMWY1M2M3MjM4MDBmNjhm MGVlYmQ2N2UyN2QwMmNmNTliMGYzM2VjDQpkNzQ5Yjk0NDhiYjU4NjA5MDQxMWVjNDExZTljNTY1 NzhiZmMyNDc1YzE2ZmE5ZTk3MzI1OGY4ODZjMWJjY2IzYmNkYjljZmFjNmZlYThjMzgyM2I3NWY2 M2M2NmFkZjE2NzRmZjBlZTlkYTZlOWZlMTFkMDJlMzUxYjYyZTk2Yg0KNmFmODMxNDUyNjMwMzZj NDA4ZGQyMWVkOTAzMDA5MWM5Y2UyYmQ1ZWRhNTc5ZWQ2Mjk2NTgxZTA5MWQwMzM0NGU0MTY0MjQ3 MmE0ODI0NjQ3YjFhMDBmMWFmMTE3ODdlZGJlMmQ2OGIzYzkxZGI0N2E1NzhlNzQ3NmYyYWU2ZGQN CjliMDQ5MWZjMjRmNzQ2ZWFhZGRiZDcxOWFkMmY4NTVmMTMyN2Q1ZTU5M2MyYmUyN2ZmMDA0NmYx MDU5OTMxMjk5N2U1MzcxYjcyMDgyM2ZiZTMxY2ZhZjVmNWFlYTNjNjNlMTZiYWJkYjhiN2YxMTc4 NzllM2I2ZjEyNjllYTdjDQo5NzYxZjJkZDQ3ZGUxOTNkNTRmNjNkOGZhNTc5ZDc4ZDc0NDRmMWZm MDA4NzIxZjFkZjg1ZTE5NmQzYzQ5YTZiNjJmMmQ5MDYyNTBmMWZkZTUzOGU3N2E2MzIzYjkxYzdh MGEwMGY3NWEyYjg2Zjg1ZmYwMDEwMjBmMWRmODcwNA0KOTIxNTRkNTZkNDA0YmM4NDcxOTNkOWMw ZmVlYjYwZmQwODIzZWJkY2QwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwNzNkZTM2 ZjE2NWE3ODJmYzJkNzVhYzVkNjFkOTA2YzgyMWNlMGNiMjlmYmFiZmQ0ZmEwMDQNCmQ3OTBmYzNm ZDI5NmRhMGJmZjAwOGI1ZTM5OTc3NDhmOTk2Y2Q2NDFjZTdhMDY1NTNkY2YwYTgzZDM5ZjQzNTE2 YjMyNGJmMWEzZTJjNDVhM2RiNDhjN2MzNWEzOTI2NTk1MGYwZTAxYzMzMDNlYWM0MDU1ZjYxOWY1 YWVmMmRhDQowODdjNmZlMzc0OGUxOGQwNzg1ZmMyZWUyMzhhMzQwMDQ3NzE3ODA3NjAzODJiMTBj MDFlZTdkMjgwMzQ3YzE3YTFkZjVkNWZjZmUzMmYxMTQ1YjM1OGJmNDA5NmY2Y2RjZmQ4MmRiYWFj NjMzZDE4ZjU2M2VhN2ViNWQwZjg4Yg0KYzQ5YTZmODViNGJmYjdlYTcyYjJjNjVjNDcxYzcxYTk3 OTI1NzNkMTExNDcyNDlhZDZhZTQzNWVkMWFmMjZmMWY2ODdhZjQ4YjE0YmE0ZTk5NmI3MjY1MGVk ODMwYzg0MGMzYWFmZjExMjAxMWVjMzI3YWUyODAzM2JjMzlhYTcNCjg0M2M2NWUyN2JjYmY2YjVi OThmNWU0YjYxNmQyNjlmYWI0N2I2NDg2MmU3M2I2MzI0ODAxYjc3Y2Q4ZmM3MTkzOWE3NmZhMGVi OWYwZTc1ZDhkYmMzZjE1YzZhYmUxNmJkOWMyNGJhNjA2Y2M5NjBjYzdlZmM0NThlMzY2NDljDQo4 MzhjNzdmNWFlMzM1MWQzNjBmMTBmODI2ZjdlMjBjYjc0ZjA3ODhmNTJiZjQzYTMzNDEzMTEyNDQw NDgyMzhlMTUwMGYyNDgwNDlmY2ZiMWFmNmNkMDZkNzU0YjFkMWExODM1YWQ0OTM1MGJlNGNmOTk3 MjkwODg4MzBlZGYyOA0KZTNhNTAwNTkzNmI2MzZkNzUzZWE0NjBiNzhhNzY4YzJjZDcyNTQyYjE0 NWM5MDE5YmQwNjRmNWFmMjhkNTc1ZWQ2N2UyYzZhMzczZTFlZjBhNDhkNjdlMWE4NWM0N2E4NmIx YzgzMzBlZjFjN2VhMDhmY2ZiZTAxZTU3NWZkNTMNCjUwZjhhZmFmNDllMTZmMGZjOGYwZjg2NmQy NTAzNTVkNTIzNmUyN2M3NThhMzNkMDhmY2YzZDdhMGU3ZDRiNDdkMWVjMzQxZDJhMGQzMzRjYjY0 YjdiNDgxNzZhNDZiZmNjOWVlNGY1MjRmNWEwMGFmZTFjZjBkNjk1ZTE0ZDIyDQozZDMzNDhiNTU4 MmRkMzk2M2Q1YTQ2ZWVjYzdiOTNmZTc4YWQ2YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDJiZTc2Zjhj ZGYxNjA1Zjc5ZmUxN2QwNjY0NmI1ZTk3NTc3MWJlN2NjZmJhYzE1MTk0ZjE4M2I5NTgxZWJkMmJl ODlhZg0KOWNiZTI0N2MxNjZiNWQ0YjQ5MWUxM2IyYmZiOTM3YjJjYmY2Yzk2NDNiZDIxYzk0ZGE0 ZTA3Y2EzZTY3M2RmYTUwMDc4NzU1YmQzMzUyYmJkMjM1MTgyZmFjYTY3OGE3ODVjMzI5NTYyMzM4 MzljMWMxZTg3YjhhZGFmMWJmODINCmFmZmMwOWFkNDVhNWVhMzcxNmQzY2QyZGJhZGMwNmI3MmM1 NDI5NjY1YzdjYzAxY2U1NGQ3MzU0MDFlZTNmMTU3YzZkYTdmOGFmZTEzNzg3Y2ZmNjhkOTRiYWJi ZGNjNTNkZDViNWJiOGNjNjdjYTkwMzdjYjkyNDAwNDgxY2ZhDQpkNWNmZDlmYmMxZmE3NGFlZGUy ODZkNGEzOWFmZTEwNTEyZDYxN2U2MDBkYmQwZjlhMzFmYzQwMDJiY2Q3ODE1NWRkMzc1NmJmZDI2 NzU5YWM2ZWU2ODA4NzU3MjIzOTE5NDM5NTM5MWI4MDNjZDAwN2RlMzQ1NzMxZTAwZjE0Mg0KNzhi N2MyMTY1YThiNWM1YmNiNzg2MzAyZWQ2MGU5MWNiOGM5NWM3NmUwOGUyYmE3YTAwMjhhMjhhMDAy OGEyOGEwMDI4YTI4YTAwMmI5YmYxOWY4MjM0OGYxYmU5MjZjZjUxOGI2Y2M4MDliNmJhNDFmYmM4 MWJkNDFlZTNhNjQNCjc0M2Y5MWFlOTI4YTAwZjJhZjBjZjhjZjU3ZjA5NmI1NmZlMGVmMWViMjg5 MWM2ZGQzZjU4YzlmMmVlNDY3MDAzOTNmYzVkMDY0ZjNlYmQ3MjdiNGQ3ZmMyNWEzNmIxNzRiYWI1 Y2U4OTY3YThlYTk2YjBiMjViMGJhMzg1M2RjDQoyYjcwNDYzM2RjODM4YzlhOWZjNTNlMTZkMmZj NjFhMjRiYTU2YWIwNmY4OWY5NDkxNzg3ODlmYjMyOWVjNDdlYmQwZjE1YzI3ODI3YzRkYWFmODU3 NWE4YmMwN2UzMjZmZGY4MThkMmY1MzY2ZjkyZWQzYjI5MjdmOGJiMGVmZA0KYmQwOTAwZGNmMDc3 ODJlZWFkYjUwNmYxM2Y4YTFlM2JhZjExNGU5YjUxMTc5OGFjMjNlZDE0NDNhMGUzYTkxZWZlYTQ5 ZWUxOTk1MTRiMzMwNTAzYTkyNzE0YjVlNDlhMTc4NzdmZTE2YzI0OWUyNWYxNTVjNWM0OWE0YmNm MjQNCjdhNzY5MzE0YzYzODkyMzQ2MmJiOWY2OWM5NzI0MWVlM2E3YTEwMDAwN2FkMDIxODAyMDgy MGYyMDhhZjNlZjE0ZDlkYzc4MzM1ZTdmMWJlOTMwYjQ5NjUyODA5YWU1OWM2M2ZkNjQ2M2E0ZWEw N2YxYTczOWY1MTlmNzM1NWZjDQozMTZmMGY4NGJlMjhkY2Y4NDc0ODk2NjdkMWE1ZDJjNWYwYjU3 OTVhNDE2NzIwOTM2ZTE0YjEyNDJiMDM5YzdhOTE1ZTkyY2FhZWE1NTgwNjUyMzA0MTE5MDQ1MDA3 Y2Y3ZTM0ZDMyNWY4N2ZlMjZiMmY4OTNlMGU2NDk3NDViZQ0KMjBkYzQ1MTFmZGQ5ZGZjOTFjNzQ0 N2VhM2ZiYWRmODBhZjc1ZDBmNTliM2YxMGU4OTY3YWI2OWYyNmZiNWJhOGM0ODg3YjhmNTA3ZGMx YzgyM2Q0NTc5ZjU5ZTk1NjlhMjZiMWE4N2MzY2Q1OTM3Zjg3NzViOGU0OWI0OTJjNzgNCjhjOWU2 NDgwMTNkMGE5YzNhZmE3ZDZiOTZmODY1YWFkZTdjM2JmMWY1ZWZjM2RkNzI2MjZkMmUyNWRkNjEz M2YwYmJjZmRkMjNkMDM4YzcxZDk4NjNhOTM0MDFlZjU0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE1 ZTYxZjFiYmM2DQo5Mjc4NmJjMjZiYTZkODRhNTc1M2Q1NDk4NTBhN2RlNDhiZjhkODdiOWM4NTFm ZWYxYzc0YWY0ZTY2NTQ0MmNjYzE1NTQ2NDkyNzAwMGFmOWVmYzM4YWRmMTUzZTM4NWQ2YmIzMGYz NzQ0ZDFjODMwZWVmYmE1NTQ5MTEwZmM1Yg0KMmZmODFhMDBkZWQyYjQ2YjlmODdiZTAwZDNiYzNi YTUyZWRmMTc3ODk1ZjY5N2VmMDFkYjk3NzNmZWNjNGE3ZjMyNGY3YWY1M2YwZWU4MzY1ZTE4ZDAy Y2Y0N2IwNTIyZGVkOTM2ODI3YWI5ZWFjYzdkYzkyNGZlMzVjOTc4MzENCjRmOGEzYzYxYWJmOGQ2 NDJjZDY0YjlkMzc0OTA3YTE4NTBmZWYyNDFmZWYzOGUwZjVjMDM1ZGVjZTY0MTAzODg0YTA5OGE5 MTFmOTlmNzRiNjM4Y2ZiNTAwNzBiZTM3ZDdkYWUzYzQ5YTJmODMzNGZkNjNmYjNlZTc1MzkxOGRk DQpjZjA0ODA0ZjBjNGE4NTk0MmU3YTMzOTVjMDNkYmYxMTU5NWFhZTgxZTI1Zjg3YjYzMmViOWEx Nzg4NzUyZDY2YzJkNTdjZGJkZDM3NTc5N2NlNjkyMzFmNzlhMzcwMDZkMjA2NGY0ZWRkZmE1MmQ5 Njk5YTQ3OGZmYzMyOGJlMg0KYTZmYjJmODlmNDk5M2M4YmFiYjUyYjZmM2RiNGUwZTU0YWIwZTBh OTE4MjNhODNmNWFlNmZjNDdhYjc4YjJkMmQ2NmQxZjU4ZjEwNDVhOWY4NWJmZDU1ZjZhZGE0ZGJh NDk3NTFjNjc4MjkyYTg2ZmRkZTQwMjBiNjBmN2ViNDANCjFkZTc4NjNlMWY3ODM2MmJjYjRmMTU2 OTVhN2I4MzczMWFkZGRiMjQ5MjMxOGUxMzIyODZkY2E4NGUxNDkwNDdkM2I2MmIyM2UyMmViZGE4 Nzg4MzU5OGJlMWU3ODY2NDAyZjZlZDc3NmE3NzQwZjE2YjZlN2E4M2U4NDgzZjkxDQowM2Y4Yjhk MmYxMWY4ZWY0N2YwYmZjMzhiNmJmZjBmYzkxNWRhY2QxYWRhNjkzMTQyNzcwNzcwMzZhOGM3NWMy ZTM5MWVkOGVhNmFkZmMzN2YwNmI3ODViNDQ2YjlkNDE4Y2ZhZjZhNDdlZDFhOGRjM2YyYzVjZjNi MzNlODMyNw0KZWE3MjY4MDM3ZmMzOWUxZGQzYmMyYmExZGJlOTNhNWMyMjJiNzg0NzI3ZjhhNDZl ZWVjN2JiMWZmM2M1NmFkMTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDA3MjdlMjRiNmYxZTRk YTlhYjc4NmFmZjQ1ODJjN2NhMDBhNWUNCmM0ZWNmYmYyNzI3MmEzMThjNjNmNWFmMjdmODk5NjVm MTY4MWQyZjc1Y2NiNzdmZWI3ZmU0NWQ4ZTc1ZGJmNzNmZDZlZDFkZmY4N2U4ZDVmNDI1NjI3OGMz NTA4NzRjZjA3NmFmNzUzNWRhNWE4NWI0OTQyNGFkMjZjYzM5NTIxDQo3MDdkNDkyMDBmN2EwMGY4 YWI1N2JhZDU2ZTc1MDc1ZDZhN2JkOTZmNjBjYzJlMmYxZDlhNDhmMDRlNTRlZWU0NjA5M2M3ZDZh OGQzZTY5YTViOTlkZTc5ZTU3OTY1OTE4YjNjOGVjNTk5ODllYTQ5M2Q0ZDMyODAwYTI4YTI4MA0K M2U5N2ZkOWJiZmU0NGRkNTdmZWMyMDdmZjQ1YTU3YjNkNzgwZmVjZGRhNmRlZWRkNWI1NWZiNWZm YTA2N2VjZGY2NmRjZGZlYjdlNTZkZjhlOWQzOGNmNWFmN2VhMDAyOGEyOGEwMDI4YTI4YTAwMjhh MjhhMDAyOGEyOGEwMDINCmI5OWYxY2Y4MzJjM2M2ZmUxZjkzNGZiYTAxMmU1MzJmNjk3MjA3Y2Qw NDlkODgzZTg3MDAxMWRjN2JlMmJhNmEyODAzY2ZiZTFhZjhiZWY3NTE1YmFmMGM3ODhjMDhiYzQ5 YTQ3ZWVlNjBjNzliODhjNzQ5MDdhZjZjOWY3MDdiDQpkM2FlZmMwOWFmZTlmNzc3ODdjMjNlMmFm ZWM5YjJiZTlkYTc5YWQ2NWIzNDk5NjI3NmZiY2QxMTM4MmI5M2NlZGU5ZWUyYWJmYzUxZjBjZGRi NDU2ZmUzM2YwZjgzMWY4ODM0NmZkZTdjODNmZTNlMjAxZjc5MTg3N2MwMjRmZA0KMzIzYjhhZWJi YzI5ZTI0YjNmMTZmODZlY2Y1OWIyMzg4ZTc0ZjlhMzI3MjYzNzFjMzI5ZjcwN2ZjNjgwM2NjMjBi YjlmYzJiYTg2YTFhMGY4MWI0ZWI4ZjEyZjhhZTQzYmI1NWQ1ZWYxODZjOGRmZDE5ODkwM2Q3MGI5 MThmNTINCjQxYWFmNjQ5ZTM0YmI5NmVlZGU1ZjExNmIzNjVlMzZiMzgwNWRhZTlkNzI2MjZiMmJi OGYzZDIzNTQxYjRmM2YyZTczYzEyM2RmMWIxYTNmODkyMWY4NmQyZWIzYTRlYmRhNjZhMjVlNmQ0 MjZiY2I3YmNiNWI1MzJhNWRhNDhkDQo5MDcyM2EzOGU4NDFmNGViNTZiNDliYWJmZDViYzRmMzdj NDBmMTA1YTNlODVhMjY5ZDYyZjBkOWMxNzdjNGFjYWM3MmQyMzhmZTFjZTMwMTdhZjRjN2I4MDVi NWI4YjVmOGIzZjBmOTY3YjQ3ZmIwZWI1NmFlMjQ4YzA2YzQ5Ng0KMzc5MWU3MTllZTA2NzNkNDcy YTdkNmI4Y2YxZGQ4YjdjNDFmODczMWY4YTJkZTA2YjZmMTM3ODdkZGEyYmQ4NTM4NzQ2OGNmZWYx NzhlNzhmYmViZWQ5ZjVhZjY0ZDE5YjRhYmNiMjRkNWY0YjgyMDU4ZjUxNDViODMzNDcxMDQNCjY5 NDExOTA1YjAzMjRmM2RlYjkwYmQ0NWYwOWZjNGU0YmI3NTFmZDhmZTI5NTViNWI4MDQ3Y2IxZGUy MGMyMTNkYjBlYjk1ZjcyMjgwMmY3YzJmZjAwMTg4ZjFhNzgyYWQ2ZmE2NzA2ZmUwZmY0N2JjMDM4 ZmRlMmZmMDAxN2ZjDQowODYwZmUyNDc2YWVjZWJlN2FmMGMzYjdjMmJmOGUxNzdhMDRjZGU1Njhi YWI5MDIwMmM3ZTUwMTg5MzExZmMxYjI5Zjg5YWZhMTY4MDBhMjhhMjgwMGEyOGEyODAzY2VmZTM0 ZjhhMGY4NmZlMWVkZDI0MGU1NmVmNTEzZjY0OA0KODgzYzgwYzMyZTdmZWY5MDQ3ZDQ4YWU1NzRl ZDIyZTdjMjFmMDdmNGFkMDJjMzExNzg4N2M1MzMyYzQ1YjFmMzI3OTgzMmNjN2I4MDkxMGMxZjQy NzM1NTNjNzQwNzhmN2UzYmU4ZGUxNzUzYmVjNzRjMDFlZTQwZTQ2NzFlNjQNCjlmOTgwOGJmNWFl ZWY0ZDAzYzQ3ZjE3MzUyYmY2ZjlhY2JjM2I2ZWI2NTZkZmRkZmI0NDgzNzRhYzNkYzJlMTRkMDA3 NjVhNGU5OTZkYTJlOTE2OWE2NTlhMDRiN2I1ODk2MjhjMGY0MDMxOWZhOWViNTlmZTI5ZjBhNTg3 OGI3DQo0ZjhhZDZmYTRiYTg1YTA5MDRkMDRmNmIzMThlNDhhNDAwODBjMDhlMzNjOWVhMGQ2YTVm NWY1YjY5OTYxM2RmNWVjY2IwZGFkYmM2NjQ5NjQ2ZThhYTA2NDlhZTFiZmUxNzFmODcxMGM1MmRj ZDllYjU2YmE3Y2M3Zjc1YThjZg0KYTdiYWRiYjhmNTBkZDcxZDNiNzdhMDBlNGI1MWYwMzZiN2Ex ZWI1MmVhN2FlNjkxMWY4ZWY0Zjc1NDhkYTQzOTViYjg1NTc4MDdjYmNlZDkwZTBmNWU1OGUzYTgx NWViMWExZTg1YTNlODVhNzM0NWE1ZTk3MGU5ZDA0ZGZiZDkNCjYyNTQwYmM5MDNlZjYzMjMyMDcx ZDZhZmQ5ZGU1YjZhMTY3MTVkZDljZjFjZjZkMzI4NzhlNThkODMyYjAzZGMxMTVjMmZjNWRkN2Fl NzRmZjBiYzdhMjY5NjQ5ZDYzNWQ5NDU5NWIyMmY1ZGFkODBlZGVkYzFjNjdiNmVhMDBlDQo3N2My MTYzMDc4ZmYwMGUyMDRkZTIzNGI2OGEyZjBjZTgxMjM1YWU5MTZkMWEwNTQ3OWIzOTY5NDI4MThl ZmJiZWE1N2QwZDdiMWQ2Mzc4NGZjM2I2ZGUxNGYwYmQ4NjhiNmQ4MmI2ZDE4MGVlMDdkZjczY2Iz N2UyNDkzNWIzNA0KMDA1MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1NDM3NzcyOTY3NjUzZGQ0 ODE4YTQzMWI0OGMxN2E5MDA2NGUzZjJhMDA5YWJlNjFmOGY1ZTJkZDVlZTdjNWY3MWUxYWYzY2M1 YTY1YTJhMzA4YTI2NjVmMzhiYTIzZmVmMDYNCjcwZDgyMzhlMzhjOWFlOTc0ZmZkYTNlZGJmYjZl ZjdmYjRiNGI5N2ZiMjc5ZmIxZmQ5YTIxZTdmNWUzY2NkZDI2ZGU5ZTk1ZTBmYWJlYTU3M2FjNmFi NzE3ZDc3NzMzZGM0YjJiOTNlNjRlZTVkZjFkODEyNDllODMwM2YwYTAwDQphNTQ1MTQ1MDAxNDUx NDUwMDdkMjFmYjM3NWVkYjdmYzIzN2FiNThmOWYxZmRhZmVkN2U3NzkzYjg2ZmQ5YjEwNmVjN2E2 NzhjZDdiNzU3YzgzZjA3YmM1NmRlMTdmMWNkYjg3NmI1OGVkNmZmMTZkNzMzNWNiNmQxMTI2NDFk Yw0KMGU0MDA3MjA3NWUyYmViZDQ3NTkxMTVkMTgzMmIwYzg2MDcyMDhhMDA1YTI4YTI4MDBhMjhh MjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGViNWU0M2E3MjlmODVmZjE0ZmZiMmI4NGYwZDc4 OTljYmRhMGNlMTZkYWU3OGMNCmFmYjAyNDgwM2Q5OTdmYmE2YmQ3YWI5MGY4OTdlMTNmZjg0YmZj MTk3MzY5MDBjNmExNmU3ZWQzNjRlMzgyMjU1ZTgwMWY3MTkxZjhlN2I1MDA0YjE3YzQ2ZjBiYjRk YWI0MzczYWFjMTY1MmU5OTcwZjA0ZDFkZGI4OGRkOGE4DQplNTk1NDljYjJmNTAzMDM5YzU3OTg1 ZGY4ZTNjMzllM2FkNjk2ZWZjNGRhZGMxNjNlMTdiMzdkZDZiYTRlNTllNWJjNzA3MDFlNjU0MDcw M2QxM2FmZTFjOWVlN2MwZmYwMGYwOGY3YzQxZjBhZDllYjVhYTY4OWE2NWRlYWFhYg0KZjY3YmU3 YjhiMjhkYTQxMmEwYzFjOTIzM2NmMDdmMWFlYWFlYWRiNGJkMGI0YmJjYmY4NzRjYjY0NGI2ODVl NzY1ODYxNTUyZGIxNDllYzNhZjE0MDE5ZmUxYWYxY2Y4NzdjNGY3NTI1OTY4OTNjYjI3OTA5OWM5 YjU5MjM0ZGENCjMwMzBhNTk0MGUzMjM4YWIzZTMxZjBmMmY4YTNjMmI3ZGE1NjQyNGQyMjZlYjc5 NGZmMDBjYjM5OTc5NDYwN2I2MTgwZmMzMzVjZGY4MzA3OGMzYzRiMjY5ZmUyOWQ1ZjVhODJkMzRk OTkzY2ViN2QyMmNlMTA1NTkxOTRlZDMyDQo0ODc5MjcwNDFjN2FmYTc0YWY0MWEwMGYwM2Y4ODEw Y2JlMzhmODQxYTc3OGFjMjE0ZDZmNDY3MzFkZTA1MTg3NDY1NmQ5MjgyM2I2MTgyYjhmNDFmNWFm NTdmMDA3ODkwNzhiM2MxMWE2NmFjNTgxOWU0ODgyNWM3YjRhYmYyYg0KN2U2NDY3ZTg0NTczZDY5 NjcwNjk5ZjEyNzVmZjAwMGRkYzJmZmM0YWZjNDk2NjZmYTI4Y2ZkZGYzNzFlNWNlYTNkZDgxMGM2 YjkzZjgxZjc1MmY4NzdjNTVlMjZmMDM1ZTM5ZGY2ZjMzNGQwNmVlMzc2ZDNiMTg4ZmE4ZDg3ZTgN CjBkMDA3Yjk1MTQ1MTQwMDU0MTc5NzcwZDg1OGRjNWU1YzM2ZDg2ZGUzNjk2NDZmNDU1MTkyN2Yy MTUzZDcwMWYxOWY1N2ZlYzhmODVkYWFlZDYyYjI1ZGVkYjU0Yzc3ZGU3ZTZmZjAwYzc0MzUwMDc5 ZmZjMWE5ODE2ZjE5ZmM0DQo0ZDRjMGZmOTY4NDMzNzZlYjJjODA3ZmUzODJiZDQzZTE5NjlkMmQ5 NzgxZWNlZWFlOTQ3ZGJiNTM2NmQ0NmU5YmJiM2NjNzdmM2ZmMDAwMTJhM2YwYWYzY2I0ZDJkYjRk ZjgxM2UxYmYwZmE4Mjk3M2UyNGJkODIyOTU5NDYxYg0KNmNiMjc5ODRmZjAwZGZiNTAzZTk1ZWUx MWM2OTBjNDkxYzZhMTUxMTQyYTgxZDgwZTk0MDFjNjdjNTRiNmQ1NmZmMDBjMTE3MTYxYTQ2OTZk YThjZjNiYTE3ODk2NDU1MmE4YTQzZTc2OTNmMzhkY2FhMGE4ZTcwYzZhOTVhZmMNCjU3ZjA5NGRh NjdkOWY1ZjJmYTNkZDA4YjZkYzY5YmE4NWFiYTk0ZWM1NzA1NzBjM2ZjZTA1NjNlYmZlMjRiY2I1 ZjhiZjM1ZWRiNzg3ZjUwZDYyY2Y0NWIwNWI1OTA1ODgwY2QwY2IzMTBlNWI2ZmYwMDE3YzgwMGMw ZTk1YWIxDQo3OGY3ZTFmNzhkNjY0ZDFmNTQ4ZTMxNzZlYzExNmNiNTViNDI4ZTFkYjgwMDY0MTAx YjM4MWMxY2QwMDVhZjg1MTY3MjVhZjg1ZWYyNTViNzdiNmQzYWVmNTI5ZWU3NGRiNzdlMWEyYjU2 MjM2MGM3NmU0MzFjN2JkNjFlODdmZg0KMDAxNTk3YzcyZDViNTkyNDNlOWZlMWI4NDU4ZGE5Y2Yw NjY2Yzg3M2U5YzdlZjA3ZmRmMzU3NzUxZjBiNjkzZjBjZjRhZDRmYzRkYTJkZGVhMTZkMGRhZGFj OGNiYTY5YmE2N2I2Nzk1ODYxMDk1MzkzZjc4OGVmZGVhZjdjMWYNCmQwOGU4YmYwZWVjMjU5YmU2 YmJkNDczN2QzYmY3NjMyNzJiOWZmMDA4MGVkZmM3MzQwMWRlNTE0NTE0MDA1MTQ1MTQwMDUxNDUx NDAwNTE0NTE0MDA1Nzk4ZmM2NmYxMTQ1NjNhMzU4Nzg3ZDZlMmY2ZGFmMzU3Yjg0NDQ5NmQ5DQpi NmUyMzBlYTFjMTZjZTQ2NDM3YTFjZjdhZjRlYWYwOGY4YjVhOTZhZGE2N2M0ZmYwMDBkZGM1ZWQ4 ZThmNzdhNmY5OGQxZDg0NzM0NmNlZDg2ZjI4NDhkMjAyNDBkYzE4ZTU0OGZjNjgwM2QwZGZlMTVm ODUxZmMyYmZkODNmZA0KOWQwODFlNDA4N2VkYzIwOGJlZDNjN2YxNmZkOWY3YmRmMTVmMjdmOGI3 YzM3NzVlMTFmMTJkZGU4Yjc4ZjFiNGQwMTUzOThkYjcwMmFjYTE5NzljMGU3MDQ2NzhhZmIyM2M0 N2UyZWQxYmMyZDYxNzE3NWE5NWU0NDFlMDhmY2QNCjM2YzkyMjc5Y2ViOWM3Y2E4NDhjZmYwMGY1 YWJlNjNkNmEzOWJjNzVhMmY4YjNjN2JhYTViY2Q2ZjcxMGM5Njg5NjdlNGExNDgyNTUyYzYzNmZi ZDkyNDgwYWJkMWI4MjRkMDA3OWNkMTVkNTZiYmUwMGQ1ZmMzZGUxM2QyYmM0DQo3NzkyZGEzNTk2 YTYxMGMwYjEzYjE5MDZmNDJlMzcwMmEwMGUwNzYyNmI5NWEwMDI4YTI4YTAwMmJlYmFmODQ1ZjEw MDc4ZGJjM2VmMDRmMDg4YjUwZDM5NTEyNzExYTE1OGNhYjE2MDliNzJjNDkzODRlN2RlYmU0NWFm NDZmOA0KMjNhY2M5YTVmYzQ4YjI4NjRkNDBkYTU4NWM4OTA1YzJiNGJiMjM5MDg4ZGY2NmVjOWMx YzEzYzY3YjlhMDBmYWUyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhh MjhhMDBmMjhkMGJmZTI4ZGY4ZTMNCmFiNjhhNDg0ZDNmYzQ3MGZkYmFkODY3ODEzOGM5NjAzZWJm YmMzZmYwMDdjZDc3NWUyYWQ1YjUxZDJiNGQ0M2E2NjgxMzZiNTcxNzEyNzkyMjA4ZGQ1MTU3MjBm MmU1YmEyZjFkNzFlOWViNWM2ZmM2YWIzOTZkMzQ0ZDJmYzVkDQo2NGFiZjZkZDAyZjYzOWMxM2Zj NTFiMzAwNTdlODViNjdlMTlhZjQ3YjNiYzhlZmYwMDRlODJmNmRiZTY4ZTc4OTY1OGYyNzE5MGMz MjNmOWQwMDc4ZGU5ZGUxYWYxMGU4YmEzNDdhNmY4OGZjNzU2N2UxNWQxZGE0OTFhMGIxYg0KN2I5 NDEzMjJiMzY3Y2IxMzNlMDgwMzljNjMzNWViOWExY2Q2MTJlOGQ2YWJhNmVhMjlhOGRhYzUxODg5 MmU1Njc1OWI3ZWQxOGM5NzVlMDlmNTM1ZTEwM2MzZDY3YWJmYzMyN2Y4ODE3YjFmZjY4Zjg4NjFi ZjE3OTdhMjcyNWMNCjA0OGU2YzM0MWIwOWMwNTA5Y2UwOGU5ZWQ1ZGM3ODU3ZmIyMmQzZTJjZGY1 YWY4NGZjOWZlY2E5YjRiNTllZmUyYjUzZmI5OGFlMzdmYzk4YzcwYWM1NDljODFmZTM0MDFhOWYx MzU0ZTliNjVhNDc4YWEyNTAyNWQxMmZlMzk2DQo1NzFkN2VjZjIxZjJlNTFmODg2MDdmMGFmM2Zm MDA4ODY1N2MxZmYxY2JjMzllMmE4Yzg1YjRiZjA4YjNiYWY0MzhmZGRiOWY3ZjkxOTRkN2I1NmJm YTU0N2FlNzg3YjUxZDJhNTFmMjVkZGJiYzI3ZGI3MjkwMGZlMDc5YWYwZA0KZjFkMjQ5ZTI3ZmQ5 ZWY0MmQ2MjQ0MjZmMzRiNzQ4ZTc2MjA5NjFiNDk4MWYzZjU2MDg0ZmQyODAzZTgzYTJiMDNjMTFh YmZmMDA2ZWY4MWY0NWQ0YjcxNjc5YWQyM2YzMDlmZWY4MWI1YmZmMDAxZTA2YjdlODAwYWYwZmZk YTINCjZlNjRiOTg3YzM3YTBjMjRlZmJiYmE3OTMxZGIyMzZhMmZmZTg2N2JkN2I4NTc4NGY4ZjMx YWJmZWQxYmUxNGIwZTE5MmQ1MjE3MmE0ZjFiODNiYzg3YTdiMDVmY2E4MDNiNGQ0MmRhMzkzZTI5 Zjg0MzQ0ODU3MTZkYTNlOWQzDQpkZWY5NjNhMGUwNDI5YzdiNzM4YWY0MmFlMTM0MmZmNGRmOGM1 ZTJjYmE2MzlmYjA1OWQ5ZDlhN2IwNzUzMjkxZjk5MTVkOGVhNTczM2Q5ZTk5NzU3MzZkNjhmNzkz YzUxMzNjNzZlOGMxNGNhYzA3MGEwOWU5OWU5NDAxZTZkMA0KN2M0NGQwN2MyZDdmN2QyZWE3ZTE1 ZDdmNDU5MzUwYmFkZjNkY2NmNmE1ZTI5YTRjNmQwNDM2NDllOGE0ODAwNzQwNGQ3NTFhMjc4Yjdj MWZlMzhiODQ0ZDNhZTJkYWZlZTZkYjEzODQ5NmRjODc4NDgyMzBjMzdhZjA0MTIzOTENCmRlYjgw ZjE1NzhlZTRkNDM1N2YwZGZmNmJmODViNWZkMmFjYjRlZDQ3ZWRiNzcyNGY2ODU5MzI4OGRiMzZi MmU3M2M5ZTdkYmQ2YmQyYmMzMWUyMWYwZTc4YTkyN2Q0ZjQxOTIyOWQ5MGY5NTM0YTJkZGEzNzUy NzlkYTRiMjgzDQplZjQwMWM3ZmM2YjllNGJkZDI3NDNmMGI0MGM0NGJhZTZhNTE0MmQ4ZmYwMDll NmE0MTI3ZjA2Mjg3ZjBhZjRjODIxOGVkZTA4ZTA4OTc2YzcxYTg0NTUxZDgwMTgwMmJjYzM1YTVm ZWQ2ZmRhMjNjM2Q2YmY3ZTJkMmY0YzkyZQ0KZDk0ZjY2NjJlYmZmMDBjNDFlMzM1ZWE3NDAwNTE0 NTE0MDA1MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1NzIxZTMxZjg3YmE3NzhkMzUyZDI2ZmFmNmVl ZWEwOTM0YzcyZjEyYzNiNzBjNDk1M2YzNjQxZmVlOGU5NWQ3ZDE0MDENCjkzYTk3ODViYzNmYWNk ZDBiOWQ1MzQ0ZDNhZjZlMDI4NDEyZGM1YjI0OGMxNDc0MTkyMzM4ZTRmZTc1YzU3OGFmZTFmMzVi ZmMxYmJlZjBiNjg3MjE5MGM0NGRjNDdlNzc1NjAyNWYzNGE4MGFiZDdhODAzMWU5NWU5NzQ1MDA3 DQo4OWZjM2ZiOTg3ZTIzNzgxYTVmMDY3ODg3NDQ5ZWRlNWQzMjJmYjM0Nzc1ZjY1Zjk2MmQ4YTg4 MzBjZjlkYjMwYzljOGMwYzBhZjFkZjg5NWUwZDRmMDQ3OGIyNGQzMmQ4ZGQ0OTY3ZTVhMzQzM2Rj MmUzY2MyNTQxNmMxMDAwMw0KODI3MWM1N2Q4OTY1YTZkOWU5ZGY2OGZiMWRiNDcwN2RhNjc2Yjg5 YjYwYzc5OTIzNjM3MzFmNzM4MTVlMDVmYjRiZmYwMGM4NDNjM2JmZjVjYTdmZTY5NDAxZTExNDUx NDUwMDE1M2Q5NmZmMDBiNzViZjk3Yjc3ZjlhYmI3NzcNCjRjZTc4Y2Q0MTVkMzdjM2ZiZGQxYWMz YzZkYTc1YzZiZjZkZjY5ZDM5NTk4M2M1YjM3ZTU4YTkwODcxZWNjNTRmZTE0MDFmNjg1ODFiYzNh N2RiOWQ0NDQwMmY3Y2I1ZjNjNWI5MjYzMGY4ZTc2ZTc5YzY3YTY2YWM1MTQ1MDAxDQo0NTE0NTAw MTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDA2NTc4OTc0ODVkN2JjMzFhOWU5MmY4ZmY0 YmI2Nzg4MTNkOTg4ZTBmZTA3MDZiOTVmODMzYWJiZWFkZjBjZjRmNDliM2U3ZDgxNmIyOTAzNzUx YjBmY2EzZg0KZWY5MmI1ZGZkNzk2N2MyZjVmZWNjZjFlN2M0MGQwZmVlYTQ3YTgyZGRjNDgzYjJj OWI4ZmU4MzY1MDAyNzg4MjVmODYzZTE3ZjE1NmE1MzZhMTcyZjZmYTlkZjQwZjE1ZWQ5YzAyNTY1 OTk2NTFmMzE2NDUwNDY0ODM5ZWRlYmQNCjY5ZGUwYmYxNzY4MTBhZGE2OWJlMGRmMDU2YjRiYTZk YzRjMTVlZjQ1YTZjODdhZTBiYjQ4NTg5NmM3Y2RkN2QzMTVkNWY4OWJjNWZlMThmMDc1Y2MzMzZi MzNhNDE3NzcyYTdjYWQ5NmVkMjQ5MjA1ZWJjYTgzYzBjZjczNWU3DQpkZTA3ZjFhNmEzYTQ2ODc3 M2E2NjlkZTBkZjEwNmEzMWE1ZjVjM2RhMzhiN2YyYTJmMjVkY2IyMDJjZGQwZjI3M2M3MTQwMWVk MTVlNDcwNjlhMmViYzNmZjEzZmMyODU3NzE4NmVhNmJhODIzMjMwMTQ0ZDFmOWE4MDc0ZTM3MA0K MzhhZjVhODljYzkxMjM5NDI4NTk0MTJhZGQ0N2IxYWUxYWQxNDVhN2M2ZWQ1NmRjN2RjZDRiNDM4 YWU1ZDdiMTY4ZTUzMWU0ZmUwYzI4MDMxM2Y2N2RkNDhkZTdjMzg2YjU2MjQ5YjJiYzkyMjAwZmY3 NTgwNzFmYWIxYWY1NmENCmYwOWZkOWY4ZmYwMDY3NmJmZTMwZDExOGU3Yzg5OTM2ODA3ODFiMWE0 NDNlZmYwMGRkZmNhYmRkYTgwMGFmMGFiMTFmNmZmZGFiNmYyNGNlZjViNDgwZWQyOWQxN2ZkMWQ1 NGU3ZjE3MjNlYjVlZWI1ZTE3ZTAzYzVlN2VkMWRlDQoyZWI4NGY5NTYxOGU2NDIwZjUyNDQ5MWFm ZjAwMzE0MDFkY2ZjM2FjNGZhYmY4ZGFmODljYjQ5YWY0YjBlNTdlZTk1OGQxMDBjN2JmMjczNWI5 ZTMxZjExYjc4NWZjM2VmN2IwZGI3ZGFhZjI1OTUyZGFkMmRmNzZkMTI0Y2U3Ng0KYTgyN2IwY2Yy N2U5NTg5ZjBhYmY3OWEwNmFmNzYzODViYmQ2ZWY2NjBiZGQ0MTkzMThmZDJiNzdjNWRlMWI1ZjE0 ZTgwZjYwMmU1ZWQ2ZTEyNDQ5ZWRhZTUwNjRjMzMyMWRjOGQ4ZWZjZjUxZTg2ODAzOGRkMmI1N2Y4 ODAzYzUNCmRhYTY4YmE4NWU2OTMzNWUyZThkZjZkYjY4MjI4NGFjMjkzMzNlZDUwNWJlZjEwMzA3 M2ViOWFlYWZjMTFlMjBmZjAwODQ5YmMzYzJmZTRiMTE2NTc4OTMzZGJkZGMwMzA0MmNjODcwZDgy M2E4Y2ZmM2FlMTYwZDJiZTJjNWE3DQo4OWFmNzU1ZmIyZjg3YTdiYmJhYjU4YWNmZWQzZTZiODhl MzU0MjQ4NzBiZDdhYjEyNDc0Y2Y2YWVlM2MxMWEzZGI3ODc3NDA4ZjRkMWE5NDU3ZDdhZWVmNzM3 NTMyYjBmZGU0YWVkOTc2MDA3NDE5MzhhMDBlNGJjMjQzZmI0Yg0KZTNiZjhkNzUxMjMwMmNhZGUw YjM1MDdhZjIxNzI3ZjM4Y2ZlNzVlYTc1ZTViZjBiODZmZjAwMWVmYzQ2OTlmZTY5M2ZiNTE1Mzcx ZWJiNDE5MzAzZjBhZjUyYTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGENCjI4 YTAwMjhhMjhhMDAyYmNiYmUzYzY4ZDBkZmYwMGMzZjkyZjEyYzA1YzVmNWI0YTgyMjkxNjNkY2Yx YTE2MWJmMThlNDBjMGU3ZTk1ZWEzNGM5NjI4ZTc4NWUyOTUxNWUzNzUyYWVhYzMyMTgxZTA4MzQw MWYwZDc4NWY0ODhmDQo1ZmYxNTY5N2E0NGQyYjQ1MWRlNWNhNDJjZTgzMjU0MzFjNjQ2NmJkZWZm ZTE5YjM0NGZmMDBhMGY2YTFmZjAwN2VkMmJjYWVmMmUzNGVmMGJmYzcxOTZlMGM0YjZmYTc2OWZh YzE3MzFjMjljMjQ2YWZkMTU0N2I3NmFmYWZlMw0KOTE2NTg5MjQ1ZmJhZWExODdkMGQwMDdjNDNl MzJmMGViNzg1YmM1NTdmYTQ4MTNiNDMwNGE1NjE5NjY0ZGE2NDUxZmM0M2IxZmMyYjE2MDk0YzE3 MTFjYzAwMjYzNzBjMDFlZjgzOWFmYTJmZjY5MWIyYjZmZjAwODQ3YjQ5YmUNCmYyMjNmYjVmZGFm YzlmM2I2OGRmYjM2MzFkYjlmNGNmMzhhZjljMjgwM2VlOWYwYzZhZDI2YmRlMTZkMmY1Njk2MjU4 YTRiY2I1OGU3NjQ0MzkwYTU5NDFjMGZjZWI1NmJjZTNlMDg3ODg2N2YxMDdjM2I4NTY3ODYzOGJm YjM2DQo1MTYxMWVjY2ZjZWE5MWExMGM3M2RmZTZhZjQ3YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4 YTAwMjhhMjhhMDAyOGEyOGEwMDJiY2IyY2M3ZjY2N2VkMjNhODQ3OGY5NzU0ZDE5NjVlM2IzMjk1 NWZmMDBkYTY3ZDdhZDdhOWQ3OQ0KNmViNjNjYmZkYTM3YzMyYzlmMjk5NzRhOTk1YzhmZTIwMDRh NDAzZjhkMDA2ZjdjNDRkNTdjNTVhMWU5ZDZkYTg3ODViNDViNWQ1MjQ0NjYxNzI5MmM0Y2VlOGI4 ZTBhODU2MDRmN2M4MTlhZTYzNDFkNWZlMjE3OGJhZDhjYmENCjZmOGE3YzJiMTg1ZTY0NGI3Yjc5 MWE1ODhmZjc1ZDFjMDJiZjhmYTU3YTA3ODllZWI1ZmI0YjA4NWJjMzk2OTYzNzU3OGYzMDUzMTVl NGE2MzUyYmI0OTI0MTFkZjgxYzdhNjZiY2M3NWJmMDNmYzQyZjEzZGZjN2E4Yzk2ZGUxDQo2ZDFm NTE1MjE5MzUwYjE5NmUxMmU1MDBmZTE2NjUzODZmNGU0MWY2YTAwZjYwZDNkMmVlM2QzYWQ5MmZl NThlNWJjNTg5NDRmMjQ2MzBhZWUwN2NjNDBlYzA5ZTcxNWM3NmJkZmU4ZGYxODdjMjMzMmZmY2Jk NTlkZWRiYjkzZA0KMzBhMTFjNjNkZjM5YWU5ZmMzYjZmYWFkYTc4N2VjZWRmNWNiYjhlZWY1Mjhk MzZjZjNjNDMwYjIxYzljMWU4M2I2M2I1NzMxZTM2ZmRjZjhlM2MwNzc2Nzk1NWJmOWUxZGJkZjMy NDJjMDFmYzMxNDAxYzI3YzNmMWY2MWZkYTMNCjNjNWY2YjlkOGIzYTRmMjZkN2UwYjEzMjIzZjFm ODMxM2Y0YWY3NWFmMGFkMzczNjdmYjU2NmEwOTIwYzliODgwZWRkYmRiZjcwYWRjZmUwYTZiZGQ2 ODAwYWYwYmY4NjdmZjI1ZmZjNmZmZjAwNmYzZmZhM2QyYmRkMmJjMmJjDQowOTliNGZkYTQzYzVi NmU4NzI5MmM3M2JiMTZlYmNjOTFiN2YzMzQwMWRkZmMyNWZmOTEzNjZmZjAwYjA5NWU3ZmU4ZTZh ZTgzYzRkYTBjZGUyMmQzNjNiNDgzNTlkNDc0OTY0OTg0YTY3YjA5N2NiNzYwMDExYjQ5ZjRlNzNm NQ0KMDJiOWZmMDA4NTVmYmJkMDM1N2I0MWNhZGE2Yjc3YjA4NmVlYzA0OTljZmViNWI3ZTJmZDI2 M2Q1ZjQ2NThlNmQ3ZWZiNDM4YTE5OTY1NmJiYjNiOTEwMzYzMDU3NmIzMWZlMTI1ODcxZWEwNTAw NzM1ZmYwMDBhYmY1MGZmMDANCmEyODdlMmRmZmMwZGZmMDBlYjU1NWY4MjllMWRkMjJkYmMwN2E0 NmI5MGU5ZjBhNmE5NzEwY2E5MmRjODFmM2JhZjlhZGMxZmZiZTU3ZjJhNzQxZjBlODVkNGY3MTA1 YmZjNGJmMTY0YjM1YjMwNDlkMTM1NGM5OGQ4OGM4MGMzDQoxYzFjMTA2YmI1ZjBiZjg3YWRiYzI5 ZTFiYjNkMTJkMjU5NjU4MmQ0MzA0NzliMWI4ZTU4YjczODAwNzUzNDAxYzJmYzFlZmYwMDkwOGY4 ZTc3N2RmZjAwZWRlOWIzOWViOGM5YzdmNWFmNTFhZjJkZjg1Yzc2NzhmN2UyMzQyZg0KZjJjOWZk YThhZmI0ZjVkYTRjOTgzZjhkN2E5NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTUxY2QzYzM2 ZDFmOTkzY2E5MTI2NzFiOWQ4MjhmY2NkNDk1ZjE4NzhjN2UyMzZiZGUzMmJhYmFmYjU1ZDRiMGU5 ZjMzYWI4YjANCjU5MGI0NDg1NDAxYzY3ZGMxM2Y4ZDAwN2QxMWE5N2M3MGYwNjY5NWE5ZGQ2OWYz Y2Q3OGQzNWI0YWQxMzk4ZTBkY2E0ODM4MzgzOWU0NTcyM2UyOWZkYTIyZGFkZGVkN2ZlMTE3YjQ0 YmI1NjBkZTc5YmQ4ZDkzNjllMzZlZGMzDQo3M2RmZjRhZjlkYThhMDBmNjhmZjAwODY5MWYxMTdm ZDAxNzRiZmZjODlmZjAwYzU1NGQ2OWZiNDdlYjRkN2IwMmRkZTkxYTcyNWIxOTE0NGNkMTg5MGIy YTY3ZTYyM2U2ZWI4Y2Q3ODhkMTQwMWY1NmZmYzJmZmYwMDAzZmYwMA0KY2Y1ZDQzZmYwMDAxYmZm YWY1MTVjZmVkMDFlMGQ1YjU5OGRiMzVlYjRlMTE4YzZhZjZjNDI5NmM3MDBmM2QzMzVmMmJkMTQw MWVkYmYwZmYwMGMyYmEwN2M0NWJlZDQzYzYxZTIyYmM0YjdiOTZkNTE5ZGFjNDQ4YTIyOTE3MGEN CmY4MjFiZTZjMTJjNDc1ZWQ1ZjQyNDdhYTY5OGExNjM4ZWZlZDMwMzBhYWEyNjVmYzA3NWFmODNh OWQxYzhmMGNhOTJjNmM1NWQxODMyYjBlYTA4ZTg2ODAzZWEwZjhlZmE2NGZhZmU5ZGUxZWQxNmM5 YTIzN2I3NWE4ODU4ZDFkDQpmNmY1OGRiOTNlZGVmNWU2N2YxYTdjMGJhNmY4NDI1ZDE2ZWI0ZjQz MGI1ZmM2ZWIzNWJhZTNjYjQ2OGQ2MzA0YWY3ZTRiMTI3MzVjODVhNzhlZjVhNWYxNjY5OWUyMWQ0 ZWVhNWQ0ZWViNGY2MDYzMTcwZTc5MDMyNzZlN2IwYw0KOTM1ZDZmYzQzZjg4N2EzZmM0M2YwYWU5 ZjM1ZDBiOGIzZDc2YzVhNGQ5NmQxNDdiYTE3MGVjODBlNWM5YzhjMmE2N2E3NTM0MDFkYmZlY2Uz YWVkOTFkMTc1MWYwZjY2NGZiNzhiODdiZGM2ZGY5N2NhZGIxMjc1ZjVjOGU5NWUNCmU3NWYxM2Y4 MDdjNGYyNzg0ZmM1ZjYzYTkxYjk5ZTFiNDEyMmFkZDg4NzkzMjQ1OTA0YWUzYmY0MWM1N2Q3ZmUx N2YxMzY5ZmUyZWQwZTNkNWY0Y2YzN2VjYjIzYjIyZjlhOWI1YjJhNzA3OGEwMGQ5YTI4YTI4MDBh MjhhMjgwDQowYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYWYyZWYxODdmYzk3NGYwMjZkZmJkZTRk Y2VlYzc1YzZjNmViZWRkNmJkNDZiY2I3NWIzZTY3ZWQxYmUxOTU0Zjk4YzVhNTRjY2UwN2YwODIy NTAwOWZjNjgwM2I2ZjE2Nzg1ZWQ3Yw0KNWJhMzBiMGI5YjhiOWI1NzhlNTU5ZWRlZTJkOWY2NDkw Y2FhMGVkNjA3ZGIyN2ZmMDBhZGQ2YmNjZjQ4ZjBhNmE1ZTMzZjEyNmI3YTQ3OGM3NWFiYWJhN2Yw ZmM3MGRiNWIzZGE0YWQwYWJiM2FiMzg5OTgwZWFmODJiZjk3N2ENCmY1NGQ3ZmMzZGE2Zjg5YjRm NWIxZDUyMjkyNGI3NTkwNGEwNDczM2M0NzcwMDQwZTUwODNkY2YxNWMxNmE1ZjBkN2UxYzU4NWUz YzM3MTcxNzFhN2RjMDgwZGQ0YjlkNGE1NTJkMTI5MGE1ZDhiMzFlMDEyMDdlMzQwMWQxZmMyDQpm ZDRhZjM1NWY4NzFhM2RkNWZjYWYzNWNlYzkyMjc5NWNlNTlmNjQ4YzgxODllZTQ4NTA2YTlmOGY3 ZmU0NjVmMDM3ZmQ4NjNmZjAwNjkzZDc1MWEwNjkzNjNhMWU4NTY3YTZlOTg1OGQ5NDA5ODg0YjNl ZjI1NDljZTczZGZhZA0KNzJkZTM1MWU3NzhmN2MwNTZjYzcxMWI1ZjVjNGM3MWQ3NzI0MjRhZmYz YTAwZTE4N2ZjOWQ5OWZmYWUxZmYwMGI2OTVlZTk1ZTE1YTZlNmYzZjZhY2Q0MWU0MzgzNmYwMWRi YjdiZmVlMTU3OWZjMThkN2JhZDAwMTVlMTU2MjcNCmVjMWZiNTZkZTQ3OGQ4Yjc3MDFkYTEzYTM3 ZmEzYWIxY2ZlMjg0ZmQ2YmRkNmJjMjNjN2E0NjkxZmI0Njc4NTM1MGM2MTJlOTIwNDJjNDcxOTY3 Nzg4ZmU4NTY4MDNiZGY4N2JmYjhkNjNjNmQ2NGRmN2EzZDc2NDliMDNhMDU5DQoxMTE4NjNmMjM5 YWQ5ZjFhNjlkNzVhOTc4NmVlMjFiNzdjYzZhYWNmM2RiMGI1NDlkYWU5MDI5ZmRkMjg2MzgwNDlj NjBmNjIwNTYyZTg0N2VjNWYxOGJjNTk2Y2MzMWY2ZmIzYjNiYzRjZjcwOGE2MjI3ZjMwMmJhMWYx NWY4OQ0KYWNmYzI1ZTFlYjhkNWVmMTVhNDU4ZjBiMWMyOWY3YTU5MGYwYTgzZGM5ZmVhNjgwMzk2 Zjg3OWUxZmQ2YjRiYjg5YmZiNGU1YmZiNzA4YjFjYTUzMzA5ODZlOWU0NDA1OGIxMDgyNDJlODQ2 ZDI1OGYzODFlYjhhZjQzYWYzMTgNCmI0YWY4YTdlMjM4YmVkNzc3ZTIyYjNmMGQ0NzJmY2M5NjU2 ZDY4YjNiYTBlMzAxZDliYmZhZTBmZTFkODU4YjBkNzNjNTNlMTFmMTI2OWZhMzc4YmFlZWRmNTRk M2Y1NDkzYzhiM2Q1NjE4NDQyY2IzOWU5MWM4ODM4MTllODMxDQpmYWYzODAwYTVlMTIzZmQ5YmYx ZGZjNmJhNzEzOTE3YjZmMDVlMjkzZDc4MGI5MWY5Yzg3ZjJhZjUzYWYyY2Q2OWJmYjI3ZjY4OGYw ZjVkN2RjOGI1NGQzMjRiNDY2M2RkOTRiYjdmZjAwMTAzOGM1N2E5ZDAwMTQ1MTQ1MDAxNA0KNTE0 NTAwMTQ1MTQ1MDAxNWYwMGY3YWZiZmFiZTAzOTIzNzhhNDI5MjIzMjM4ZWFhYzMwNDUwMDM2OGEy OGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMmJlOGZmMDBkOWRmYzUwNmViNDdi YmYwZTRhOTBjNjINCmM4ODk2MTZkZmYwMDNjYmJkOThiNzFlZDgxZDNkNmJlNzBhZDNmMGZlYmQ3 ZGUxYWQ2YWRmNTRkM2E2NjhhNzg0ZjU1MzhkY2E3YWFmZTIzOGEwMGZiYWU4YWUwZmMwYmYxNTc0 M2YxYjNjNTY1MDk3ODM1NGZiM2Y5ZDM0MGNhDQo3NjI5Y2E4MmFhYzcxYmI5NjE1ZGU1MDAxNDUx NDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE1ZTU5NjY3ZmI0ZmY2OTFkNDI0Y2ZjYmE1ZThj YjE3MWRkOThhYjdmZWQ0M2U5ZDJiZDRlYmNiM2UxN2I3ZjY5ZjhmM2UyMA0KNmI5Zjc5MjRkNDE2 ZDIyNzFkZDYzZGMzZjUxYjI4MDNkMTZkYjU4ZDNlZjM1NGJkZDMyZGVlNTY0YmNiMjA4NmU2MjAw ZTYzZGUzMmI5MzhjNzIyYmNkZmM2NWUxMGQ3MmY3NTliYWI5YjY0YmViZWIyNGQ5MzAxMzRkMDQ4 NjQNCjJkMmFlZTg2MjQ2NTNiNTE0MGRlNDNlNDMxNTUxOGUyYWNmYzM1ZDRhYzJmM2M0N2UzNGQ0 OWVmMmQ4NWQ1ZGVhZWQwYTQ2ZDMyZjk4NjI4ODA1NDM4Y2U3MWM5YzU3YTZkMDA1M2QyZWQ2ZWFj YjRkODZkZWY2ZmRlZmVlMTMzDQpiYWU1ZTI0OGNiZjI0OGY5NTAwNTE4MTgxYzBlZDVjOGViZGZl OTNmMTg3YzIzMGFmZjAwY2JhZDlkZWRjMzgzZDMwYzExMDYzZGYzOWFlZWFiODRiNDYxNzdmMWJi NTViODFmNzM0ZGQwZTJiNjc2ZWMxYTQ5NGM5ODNmODI4YQ0KMDBlMTdlMWZlMmY3ZjY4YmYxN2Rk MDVkY2IwYTVjNDc5N2VhYWMyNTQ0ZTNmZWY5MjNlOTVlZWI1ZTE1ZmIzZjBmZWQxZDczYzYxYWUz MmZmYWY5ZDAyMTFkM2U3NjkxZGI4ZWJmZGRhZjc1YTAwMmJjM2ZmNjg5YjY5MmRhMWYNCjBkZWJk MDgzYmVkMmU5ZTNjZjZjOWRhZWJmZmEwMWVkNWVlMTVjMDdjNjdkMjNmYjVmZTE3NmFiYjU0YjQ5 NjliNmU5MzFkYjYxZjliZmYxZDJkNDAwY2Q0MmVhMzhmZTI5Nzg0MzVhODRlNmRmNThkM2E3YjMz MjAzZjI5MTgxDQozNDYzZjFlNzE1MmZjNWFiNTlkYmMzM2E3ZWFiMGMwNjc0ZDE3NTRiN2Q0YTc4 OTU3MjVhMjhmNzA2YzBmNjBkOWZjMGQ3MTU2OWFhMzZhNWYwMjdjMzdlMjA1MjVlZTdjMzc3YjA0 YjJhYTljYjZkOGE0ZjJjOGZmYmY2YzBmZA0KMmJkYmQxZTM5ZTE1NzQyMWUzOTE0MTA3YjEwNjgw MzJiNGNmMTU2ODNhYzY5YjE1ZmQ5NmFkNjkyNWJjOGJiODM3OWFhMDhmNjYwNGU0MTFkYzFlOTVj MDc4YmY1ZGIyZjFkNzhhN2MzZmUxNmYwZjRlYjdjNmQzNTE4YjUxYmUNCmJiYjc2ZGQxZGJjNzFl NzhkYzM4ZGM3M2Y5ZTNkNmFiNzhiZjRiZjgzMWE1ZGZiNWM2YWYwZDg4YmQwYzRiNWI1OTRhZTU5 OWJkMGM3MTljMGZjNzE0Nzg3N2M1M2E5NmExNjFmNjdmODY3ZTA0ODJjYjRkNzYyM2ZiNDJmYzg4 DQo2MjI0NzA0OTU1Zjk5Y2Y2Y2U0OWEwMGQwZjhkNzA0OTY1YTRlODdlMjk4MTQ5OTc0M2Q0YTI5 OWIxZmYwMDNjZDg4MDQ3ZTJjMTA3ZTM1ZTk5MDRkMWRjNDExY2YxMzZlOGU0NTBlYWMzYjgyMzIw ZDc5ZGU5MzcxNzlmMTI3ZQ0KMTVlYjFhNTZhYmU1MmViMjhkNzE2MzcyMTQ2ZDU0OWQwZTUwZTNk M2VlN2ViNTczZTBmZWJhNzVhZjg3NzYxMTRkZjJkZGU5ZDliMTlkM2JhOThmODVjZmZjMDc2ZmUz OWEwMGVmMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMmINCmU1ZWY4ZmRlMThmZWNiZjE4MmViNDky YzkyYWVhODM3YzhiZTVlMTYyMjhhODgwNjdiZTcxOWFmYTg2YjM3NWNkMDM0YmYxMjY5YWRhNzZh ZjY4Yjc1NjhjYzFjYzZjY2NhMzIzYTFjODIwZDAwN2MyNzQ1NzdiZjE3N2MxZDYzDQplMGJmMWEw YjJkMzlkOGRiNWQ1YjhiYjQ4YzhlMjEwZDIzYTg0MDcyNDkwMDI4ZTRkNzA1NDAwNTE0NTE0MDA1 MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQwMTNkOTVlNWM2OWQ3YjA1ZWRhNGFkMGRjYzBl MjQ4YTQ1ZQ0KYWFjMGU0MTE1ZjVkN2MyZWY4ODU2OWUzNWYwZjQ0OTI0Y2FiYWJkYWEyYTVkNDI0 OWM5M2YzMDU2MDQ4MWJiMjEwYjFjNzRjZDdjN2Q1ZDJmODAzYzQ1Mjc4NWJjNmJhN2VhYjE1YmE1 YzNhMzE4YmNiNzYyYTNlNzA1MzM5ZjYNCmRkOWEwMGZiNjY4YTI4YTAwMjhhMjhhMDAyOGEyOGEw MDI4YTI4YTAwY2FmMTJlYWViYTBmODYzNTNkNTlmMWZlODk2Y2YyODA3YmIwMWMwZmM0ZTA1NzFi ZjA5ZWRhMGYwYjdjMjRiNmQ0YjUyOTg0MmIzYWM5YThkY2NiMjc2DQo1NmU0MzdmZGYwMTdlYjU1 ZmUzNTVlNGI3N2EyNjk3ZTExYjI2NWZiNmViZjdiMWMwMDFmZTE4ZDU4MTJkZjQwZGIzZjBjZDMz ZTJjNGI2M2E3Zjg2M2MzZGUxMjZiYTRiNGIzZDQ2ZjIwYjU5NjQ5MWMyMDRiNjhiMDVjOTI0Zg0K MThmOTI4MDM5ZTZiZWY4NDNlMjVkNTJkZTFiYmYwY2RkNTg3ZGI1ZjZkYmRmNDk2Y2Q2ZDBjY2M0 ZjA0MzIzNzczZGM4ZmFkNzU2N2UwZmRhZDk3Y2RhMGY4YTdjNDVhNDkxZjc2MzhhZjBiYzRiZmYw MTIzMjdiNzdlZDUxZmMNCjU5OTZjNzU0Zjg3YjY5YTRlOWIyNWJjY2RhYTVmNWI1OWQ4YjQwNDMy MmI2ZjA3MjA4ZWMxNTQ4ZTNkNmJkMmQ1NzZhMmFlNzM4MThjZDAwNjdlODc2MTc3YTVlOGQ2ZjY3 N2RhOTRiYTk1Y2M0MWI3ZGRjYTgxNWE0Y2IxMjMyDQowNzFjMDIwN2UxNWU2OTZmYTk4YjdmMGY3 YzRlZjE1ZWVkYTY2Yjk5YWRhMDkxYmEzMDg2M2YyOTMxZWRiOThkN2E1Nzg4NzU1NGQwZmMzOWE5 NmFhZTQ2MmQyZGE0OWI5ZWU1NTQ5MDNmMTM4MTVlMWRlM2E3OTNjMzFmYjNkZQ0KODVhM2M4ZTQ1 ZTZhOGU5MjRlYTQ5MGM3NzEzM2JlN2U4YzUwMWZhZDAwNzViZmIzZWU5YTZjZmUxYzM1ZDMwMjFh ZjZmMjQ5NDEzZmRkNTAxMDdlYWE2YmQ1YWIwM2MxMWE0N2Y2MTc4MWY0NWQzNzY5NTc4NmQyM2Yz MDFmZWYNCjkxYjliZmYxZTI2YjdlODAwYTgyZjJkMjFiZmIxYjhiM2I4NWRkMGRjNDZkMTQ4YmVh YWMzMDQ3ZTQ2YTdhMjgwM2MwM2UwZDQyMDM3OGNmZTFkZWE2NDdmY2I0MDE1YmJmNThhNDIzZmYw MDFjMzVlYTFmMGNiNTE5NmY3YzBmDQo2NzZiNzRjM2VkZGE2MzM2OWQ3NGJkZDVlMTNiMzlmZjAw ODA4NTNmOGQ3OWE3OGU4OGYwMTdjNzdkMWJjNTBhMzY1OGVhNjAyNWM5MWMwY2UzY2I5M2YyMDUx YmViNWRlNjlhNDc4NzNlMmU2YTU2MGRmMjU5Nzg4YWRkNmY2ZA0KYmZiYmY2ODhjNmQ5NTQ3Yjk1 YzMxYTAwZTkzNGZmMDAwOGY4N2I0YmQ0MjdkNDJjZjQ3YjM4YWY2Nzk1YTY5MmUzY2EwNjQyY2M3 MjQ4NjNjOGU0ZjQxYzU3OWY2OTllMjFkM2ZlMTVmODlmNWRkMTdjNDBmMjU5ZThkN2Q3MjcNCjUw ZDMyZTQ0MmVlOWYzZmYwMGFjOGZlNTA3MTgyMDcxZmUzNWViNDQ4NTA0OTIwMDFjOTI3YjU3MDNh ZmZjNGZmMGRjNTcyMzRhZDNhZGU0ZjEyZWE0NGZjYjY3YTdjNDI2MDA4ZWVjZGY3NDczZTk5MjNk MjgwMjk3YzMwYjg5DQozNTZmMTM3OGMzYzQzNjc2YjNjMWExNmE1NzMwYjU5OTk5MzYxOTVkNTA4 OTFjMGViODI3MDczZWZlYTBkNTRkMGZmZTI4ZGY4ZTVhYjY4YzcwOWE3Zjg5MjExN2Q2YTMxYzA5 OTcyNWM3YTczZmJjM2ZmN2NkNTVkNzM1MWY4YQ0KMzZmYTUwZjE0ZGRhNTk2OTlhN2U5ZDIyNWMz ZThkNjg3N2NiMmMyMTg2ZTEyM2Y0ZTE3M2QwZjZlODMxNWIxZjEzNzRmM2UyM2YwMzU4ZjhhYjQx NjJkYTg2OTdiMzUzYjE5NTdlZjE4ZjAxOTg3ZmRmMzgzOGZmMDA2NzE0MDENCmU5MzQ1NjM3ODRm YzQ1NmRlMmJmMGJkODZiNTZkODBiNzMxODJlODBmZGM3MWMzMmZlMDQxMTViMzQwMDUxNDUxNDAw NTE0NTE0MDA1MTQ1MTQwMWUxZmYwMGI0N2U5MzYzZmQ4MWE2ZWIxZjY3NWZlZDAzNzRiNmJlN2U0 ZTdjDQphZGIyMzZkYzc0ZmJkY2Q3Y2UzNWY0Y2ZlZDFlZTlmZjAwMDg1Njk5MWVlNWRmZmRhMmE3 NmU3OWM3OTcyNzM4YWY5OWE4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEy ODAwYWIxNjEyYTQxYThkYjRkMg0KMWMyNDcyYWIzMWY2MDQxMzU1ZThhMDBmYmMzNDdkNWFkMzVk ZDIyZDc1NGIwNzY3YjViOTRmMzIyNjY1MmE0OGZhMWU5NTdhYmU1ZmY4NzNmMWIyZWZjMzM2NzY1 YTFlYWQwMmRjZTljYjMyNDZiNzI1YjY5YjU4MzIwMzdjYWENCjg0YmUzOTNjZjI3YTU3ZDM3NmI3 MzBkZTViNDc3MzZmMjA5MjE5MTQzMjMwZWUwZDAwNGI0NTE0NTAwMTQ1MTQ1MDAxNDUxNWM4N2M0 YmYxNjdmYzIyMWUwY2I5YmM4MGU3NTBiODNmNjZiMjQxYzkzMmI3NDIwN2IwYzlmYzMxDQpkZTgw Mzk3ZDBiZmUyYjJmOGUzYWI2YjQ3MGZhN2Y4NzIxZmIwZGIxYzcwNjczOTBjNDdkM2Y3ODNmZWY5 YWQ3Zjg4OTczMjY5Nzc5NjVhOGVhZmE1NWE2YWJlMTJkYmU0ZGZjMzI1YTg5NjRiNjYyNzg5ODY3 M2YyOGUwMWM3NA0KZmNiMTY3YzFmYTRjM2YwZTdlMWFjNjZmMjE5OWVlMjM4Y2RkNWYwODU0Yzky NDkzMzYzMjAwZmUyM2QxNDdkMmFiNDlmMTJiZWRiMDQ4OTZkZTA1ZjE1NWRjNGYxZmZjYjRkMzgy MjM4MjNhN2NjZGM4M2Y0M2Q2ODAyODRkZjANCjczYzFmYTlhZGI2YWZlMWRiOWJiZDJhNDZkYjNk YjVjZTlmNzA0YTY3MTkwYzAzNjdiN2ExMTVkMGY4NWI0NmYxOGU5MWE5NDkxNmI3ZTIzYjdkNjM0 YmYyOGY5NGNkNmMyMjljM2U0NjMzOGUwOGM2ZWVmOWNlMmI4NmYwZTZiDQoxYWQ3ODBmNTRiODdi ZmYwZjZhMWE2ZjgyNmUyNTUwOGI3MTIyNDg3NGU5MWNmNTFiNTg5ZjI4OWZjMDEzZjlmYjMwMjE4 MDIwODIwZjIwOGVmNDAxYzJmYzRkNjNhOTU5NjkxZTE1ODk4MTk3NWJiZjhlMjk1MDc1ZmIzYzY3 Yw0KYzk0ZmUwMTQwZmM2YmNmZjAwZTIxODVmMTg3YzcyZjBlNzg1NjMwMWFkMmMwMjM0ZThiZDA2 N2Y3OGUzZGJlNDU1MTVkYWRhNWU0MWE5ZmM0OWQ3ZmM0OTcwZGZmMTJiZjBkZDk5YjE4YTQzZjc3 Y2RjNzk5M2IwZjc1MDAyOWENCmU0YmUwN2RhY2JlMjJmMTU3ODliYzczNzg5ZjNkYzRjZDBjMWJi OWRiYjhlZjYwM2U4MzYwZmExMzQwMWVlNzQ1MTQ1MDAxNDUxNDUwMDc5ZTdjNjhmMGMxZjEyN2Mz ZGJhNzg2M2RmNzdhNzlmYjVjMjAwZTQ4NWZiZTNmZWY5DQoyNGZkNDBhZTUzNGVkNWVlN2M1ZmYw N2Y0YWQ3ZWMzMTJmODg3YzJkMzJjYTU3M2YzM2Y5NjMwY2E3YjkwZjExYzlmNTIzMTVlZGFjYWFl ODU1OTQzMmIwYzEwNDY0MTE1ZjNkZjg3MThmYzJiZjhlMTc1YTE0YzdjYWQxMzU4Mg0KMDQzYmJl ZTg1NjI0YzQ3ZjA2Y2E3ZTI2ODAzZGIzMWE1NzhkN2MyNGJiYzBiOGQzMzUzYjYwNDgwYzQxMmFj MzNkNDcyMDhmZDA4YTliNDVmMGVlOGZlMWNiNDE2YmEzZTlkNmY2NzE2MDAyMjI0YzE2YzdmNzli YWIxZjcyNGQNCjcyNWUwZDYzZTE2ZjE3ZWFkZTBhN2M4YjM2MDc1MmQyNzNkMDQyZWRmYmM4ODdm YmFlNzgxZTg0ZDZmZjAwOGJhNWYxNGFlOWQwYzVlMTRiN2IyN2JjOWE0ZjJlNDllZWRmMGI2ZWE0 MWY5ZjFmYzU4M2RiOWZhMWEwMGIxZTI1DQpkN2Y0MmQwMzQ4OWE2ZDdlZjIwYjdiNDkxMGEzMjQ4 NzI2NTA0NjBhYWE4ZTViYWY0MDJiOTFmODQzNzEzYjc4N2E3ZDNlM2QzYjUxOGY0MzgxYzlkM2Fl YWZjMDU2OWEzNjY2M2I0Mjc1ZGEwNjMwNzljZTRmNGU4Mzg5ZjEzZg0KODNhZTM0NmYxM2Y4NjAx ZDY1YjVhZjFhNWZkZjc5OWU3NmEwOWJlZGQyMjU1NmNmZWViOWRhYTA5MWZmMDA3YzkyMzE4YWVk NmUwZmM1ZDgyZGE0YmQ2N2YwYmM4ZDAyOTdmYjE1YjQ3MzEzMzgwMzNiNDE2ZTg0ZjQxNDAxOTUN CmUxYTc2Zjg2N2YxMjJlN2MyNzcwNzZlODFhZTQ4NmU3NGI5MGYwMjI5OGUzMzE2N2ZmMDAxZGZj MTdmYmM2YmQ3NmI4YWYxOWY4NWE0ZjFlZjgxYTM4ZTZiNzZkM2Y1ODQ0NWJhYjYwY2MwYjViY2Uw Njc2ZWUxZGJiMTIzZDhmDQo2YTVmODZmZTMyNmYxNTY4OGQ2ZGE4Mjk4MzVlZDM0ZmQ5ZjUxYjc3 ZTE4MzhlMzdlM2QwZTBmZDBlNDUwMDc2OTQ1MTQ1MDAxNDUxNTk3YWY3ODhiNDlmMGNlOWRmNmZk NjJmMTZkNmQ3Nzg4ZmNjMmFjZGYzMWU4MzBhMDllZA0KNDAxYTk1MTVkNWNjNTY1NjkzNWQ0ZWRi NjE4NjM2OTI0NmMxMzg1MDMyNGUwN2IwYWYxZWYxMmZlZDBkYTQ2OTNhOWE1YmU4YmE3MmViMzZh NjIwZTZlNTZlNWEwYzM2NDgyYmI1YTMyNzgwMDFjZmJkNzgxZjg4YmM1ZmFmNzgNCmIyNTgyNGQ3 MzUwN2JiNzgxNGFjNDRhMjI2ZDA3YWZkZDAzZDA1MDA2ZWZjNThmMWE1YWY4ZTNjNjNmNmZiMTg0 YTVhZGI0MWY2NDg5Y2IxM2U3MmFiYmIwN2MxMDBhZTQzNzQzZDMxNWMzNTE0NTAwMTQ1MTQ1MDAx NDUxNDUwDQowMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNWViYmYwN2JlMmE4ZjBi NGNiYTE2YjUyMzFkMWU1NmZkY2M4MTdmZTNkOWJlNjYzYzJhOTY3ZGNjNTQ3NWUzYWQ3OTE1MTQw MWY3ZjUxNWYzZDdjMGNmODk3ZTRjYQ0KOWUxM2Q2NmUzZjc0ZDg1ZDNlNDZlY2M1ODAxMTAwYWJk ZjcxM2I4OWVkOGFmYTE2ODAwYTI4YTI4MDBlOTVlNDNhNzMxZjhhMWYxNGZmMDBiNTc4N2YwZDc4 NjVjYTVhMWM2NTZlNmU3OGNiN2I4MDQwMjNkOTU3ZmJjNmI1ZmUNCjI4Zjg5YWVkNjJiN2YwNjc4 N2M5OTNjNDFhY2ZlZWZlNDNmZjAwMWVmMDFmYmNlYzdiNjQwMjNlOTkzZDg1NmJjNWEzZThiZTA4 Zjg3Y2JhMTFkNjIxZDI2MGYyNWExZmI3Y2IyMjQ2YzY0NjFmMzM4ZGM3MWJiMjQ5MWU5YzdhDQo1 MDA1M2YwZWViN2E5NzhhYmUyMGVhYjc3Njc3NmQxZjg2ZjQ5NTM2MmE4YjgyYjc3NzM5Y2JiNjdk MTdhNzFlZGVhNjkzNWZmOGI5ZTFlZDAzNTdiOGQzOWEwZDQ2ZjhkYTEwMmYyN2IyODNjYzhhZDhm M2MzYjY0NzIzYmZhNw0KZDQxMTVjNGMxYTk3OGM3ZTFhZjgyZTZiNWQyZWNlYzdjNDNhMDg4ZTQz NjNhYWU5ZTdlNjg4YjEyNzdjOGEzM2I4MDM5MjdmNTZlZDVkMmY4M2I1Y2YwOTc4NmJlMTJjOTdk NmJhOGMxN2YxNDEwMTlhZmNlN2Y3OTM0ZWZmMDANCjc4M2E5ZTQxNjYzYjQ2NDc0YzUwMDc1MWFi NWI1YTdjNDNmMDQzNDNhNmVhOWU1ZDg2YTQ4YjliODhlM2RjNWEzY2ZjY2EwMWM2MDljMTFjZjIz ZDJhNWYxNTZiNzBmODNiYzFiNzU3ZDEyMDJkNmYwODhhZDIxMzkzZTY0ODdlDQo1OGQzZDRmMzhm YzMzNTk5ZjBhYjQxYjlmMGZmMDBjM2ViMGI3YmM1ZjJlZTI3MmQ3NGYwZjQxMGY5ODc3MDQwM2I2 MDYzOGY1Y2Q1MmJkNzVmMTY3YzRlNGI0NzYxZmQ4ZmUxNjU1YmFiODI0ZmNiMjVlMzhjYTAzZGIw OGI5Ng0KZjYyNjgwMzg1Zjg4MzM0OWUwN2Y4NDNhNzc4NTE2NDMyNmI3YWNiZjk5Nzg0NzJlZWNj NzdjYTQ5ZWY5NjJhODNkNDdkMmJkNWJjMDFlMWIxZTEzZjA0Njk5YTQ5NTAyNzhlMjBmNzFlZjJi N2NjZGY5MTM4ZmEwMTVlM2ZlMTgNCjQ2ZjhhOWYxYzJlZjVmOTk3Y2RkMTc0ODIwYzAxODdjYTQy OTIyMjFmOGI2NWZmMDM1ZjQyZDAwMTQ1MTQ1MDAxNDUxNDUwMDE1ZTYxZjFiYmMxNzI3ODk3YzI2 YmE5NTg0NDViNTNkMjg5OTkwMjdkZTc4YmY4ZDQ3YjhjMDYxDQpmZWU5Yzc1YWY0ZmEyODAzYzYz NGFkNjZlN2UyMTc4MDM0ZWYxMWU5NGRiYmM1ZGUxYTdkYzUzYmNlNzZlMWQwZmYwMGIzMmE4ZmNj MTFkYWJkNTNjM2RhZWQ5Zjg5NzQxYjRkNWVjNTg5ODJlMTM3NmQ2ZmJjOGMzODY1NmY3MA0KNDEw N2U5NWUxZGFjYzUyZmMxN2Y4YWYxZWIzNmQxM2ZmYzIzM2FjMTIyNjhlMzFmMmEwMjcyY2EwN2Fh OWY5OTdkYjIzZDZiYmNiNjllMWYwNDc4ZGQyNDg2NDQzZTE3ZjE0Mzg5MjE3NDM5OGVkZWYwOGVj NDcwMTY1MTgyM2QNCmM3YTUwMDVlZjBmNzg0YWZjN2M0MmQ3YmM1N2FlOThlNDljYmZkOTc0YzU1 M2I4NDU2YzAwMzkxOWU4NGU3MDdkZjc3NjM1OWQ3M2UzN2YxMWY4YjM1N2I5ZDMzYzAzNjM2ZGY2 NGI1OTNjYWI4ZDZhZmIyNjBkYzNhYWM2MDdkDQplZmFmZTgwNjA5ZWU3YzQxMTVkY2ZlMWFkNTYx ZDNkOGFkZWM5NjczMmRiOTA3MTg5MGExMGJmYWUyYjlhZjg0NzI2OWVmZjBjYjQ3OGVjMDJhZjkz MTk4ZWUxMDBjMzJjZTBmZWYwMzBlYTBlNzllN2IxMWRhODAzMjZlZjViZg0KMWM3ODBjNDdhODc4 OWFlMmNiNWNkMDc3ODRiOWI5YjU4M2M5OWVkODMxYzA3MmEzODY1MDRlMzhlN2E1NDFlM2ZkMWVm MzQ3ZDRhZGJlMjU3ODUwMjQ5NzE2ZjEwM2E4NDA5Zjc2ZjJkYjAwZWVlM2E5MDMxY2ZhMDA3Zjg3 OWQNCjhmOGIzZTIwYjNkMmZjMTM3ZGE2MzExMzZhNWFhYzQ2Y2VkMmQxMGU2NDkxOWZlNWM4NWVi ODE5ZmNmMDNiZDY4Njk5YWJlOTdlMTFkMWZjMzNlMWFkNmI1MmI3ODc1MzkyY2UxYjY0ODk5YjNi ZGQxMDI5ZTdiMDI0NjAxM2Q0DQpmMDI4MDM1ZmMzOWUyMmQzYmM1NWExZGJlYWRhNWNjMjViNzk4 NzIzZjhhMzZlZThjM2IzMGZmM2M1NmFkNzhmNmJmYTVlYTFmMGEzNWU5M2M1M2UxZjhkZTZmMGNk ZGNhMGVhYmE1YzZiYzQxOWViMmM2M2EwMWY5NjNhNzQzYw0KN2E5ZThmYWM1ODZiZGE1NDFhOWU5 OTcyOTcxNjkzYWVlNDkxN2Y5MTFkODhlODQxZTk0MDE1M2M1OGRhZDJmODViNTAzZTFkMTlkNWM0 N2ZlOGEzZTRmYmQ5MWZkZmY5N2E2N2FkN2NkMWFlZmMzM2Y4YTVlMjVkNjI3ZDViNTUNCmQxMGNm N2IzZWRmMzI0MTNkYmE2NzZhODUxYzJiMDFkMDBhZmFjMjhhMDBmOGZiZmUxNGI3YzQyZmYwMGEx NzliZmYwMmEwZmZlMmU4ZmY4NTJkZjEwYmZlODVlNmZmYzBhODNmZjAwOGJhZmIwNjhhMDBmOGZi ZmUxNGI3YzQyDQpmZjAwYTE3OWJmZjAyYTBmZmUyZThmZjg1MmRmMTBiZmU4NWU2ZmZjMGE4M2Zm MDA4YmFmYjA2OGEwMGY4ZmJmZTE0YjdjNDJmZjAwYTE3OWJmZjAyYTBmZmUyZThmZjg1MmRmMTBi ZmU4NWU2ZmZjMGE4M2ZmMDA4YmFmYjA2OA0KYTAwZjhmYmZlMTRiN2M0MmZmMDBhMTc5YmZmMDJh MGZmZTJlOGZmODUyZGYxMGJmZTg1ZTZmZmMwYTgzZmYwMDhiYWZiMDY4YTAwZjhmYmZlMTRiN2M0 MmZmMDBhMTc5YmZmMDJhMGZmZTJlOGZmODUyZGYxMGJmZTg1ZTZmZmMNCjBhODNmZjAwOGJhZmIw NjhhMDBmOGZiZmUxNGI3YzQyZmYwMGExNzliZmYwMmEwZmZlMmU4ZmY4NTJkZjEwYmZlODVlNmZm YzBhODNmZjAwOGJhZmIwNjhhMDBmOGZiZmUxNGI3YzQyZmYwMGExNzliZmYwMmEwZmZlMmU4ZmY4 DQo1MmRmMTBiZmU4NWU2ZmZjMGE4M2ZmMDA4YmFmYjA2OGEwMGY4ZmJmZTE0YjdjNDJmZjAwYTE3 OWJmZjAyYTBmZmUyZThmZjg1MmRmMTBiZmU4NWU2ZmZjMGE4M2ZmMDA4YmFmYjA2OGEwMGY4ZmJm ZTE0YjdjNDJmZjAwYTE3OQ0KYmZmMDJhMGZmZTJlOGZmODUyZGYxMGJmZTg1ZTZmZmMwYTgzZmYw MDhiYWZiMDY4YTAwZjkyMzRjZjg1MWYxMmY0OGQ0ZWRiNTFiMmQwOWEzYmFiNjkxNjU4OWNkY2Ri YjZkNjA3MjBlMGJlMGQ3ZDNkZTE2YmNkNmFmNzQwYjcNCjk3YzQxYTZmZjY3ZWEyM2U0OTYyZjM5 NjRkZDhlMzdlNTc4MTllYjhlZDViMzQ1MDAxNWNjZjhlN2M2NzYxZTA4ZjBmYzlhODVkMTBmNzJm OTRiNGI2MDdlNjllNGVjMDBmNDFjMTI3YjBmN2M1NWNmMTRmOGE3NGJmMDdlODkyDQplYWJhYWNm YjIyNGUxMjM1ZTVlNTdlY2FhM2I5M2ZhNzUzYzU3MDllMGJmMGQ2YTdlMjhkNjIzZjFmNzhkMDA1 OTcwNWI0Y2QzNWM3ZWVlZDIzZWNlNDFmZTJlZTNmMzNkYjAwMTczYzA3ZTFlOTNjMzdhNmVhNWUz NWYxN2NjYg0KZmRiNzdkMTliOGJiOTVjN2ZjN2FjMjA2N2NiMWU5YzAxOTAzZDAwZWQ1NDdjMjlh NDViZmM0ZWJmYjlmMTk3ODhhZGUyYmFkMzhiMzViZTkzYTdjYWMxZDIxODgxYzE3NzUwNzFiZDg4 ZTg3YTdlNThlODM0NGYxNmRlZjhiYmMNCjViNzMxNjhmMDViYzllMTZiMjU2ODZlMmY2NDA0ZmRh YTYyM2VlYzVkOGFhZjczYzgzOWY3MTU4YmUyMmY4NjlhOGU5NjZmNzU0Zjg3NWE4YjY5Mzc5NzJh YzJlMmMxNTgwODI2YzgzY2E4M2MyMzhjZjFkODc2ZGI0MDA5ZjBlDQphY2VkYjRlZjg4OWUyZmIy ZjBmNmU1ZjBkYzA2MjUzMTg2Y2M2OTc1OGY5YzI2N2QzOTA3ZjBlZDhhZGVkNTNlMTVmODRmNTRk N2VkNzVhNmQzOTZkZWVlMDk4NGNmZjY3YzIyNGU0MWM4MGViZDBmMzgzZDg5ZWY1OTFmMGFiYw0K NDFhMWRhNjk3MTc4NDhkYjRiYTRlYmI2ODBmZGE2Y2VmMzg5Mjc5M2FiNDhhZGZjNzllYmY0ZjYw MGQ3YTUzMzJhMjk2NjIxNTQwYzkyNGUwMDE0MDFjZmY4Y2ZjNGEzYzJmYTAzZGNjMzExYjhkNDI3 NzE2ZDYxNmNhMzI2NjkNCmRiODU1YzdhNzczZWMwZDc5NTc4ZWVmOWJlMWY3YzM5OGZjMmY2ZjNi NWNmODliYzQwZWQyZGVjYzljYmJiNDg3Zjc4ZGM3M2NmZGM1ZjZjZmE1NzRiNjdhYWRhNmI3YWNl YTFmMTBmNTY3ZDllMWRkMTIzOTIxZDI0MzBlMjQyDQozODkyNzAwZjUyYzcwOGJlYmY1YWU1YmUx OTY5NTc5ZjExM2M3ZDdkZjEwYjVjODQ4YjRiNzk3NmQ4NDJmY2FlZjFmNzQwZjUwODMxY2Y3NjM5 ZWEwZDAwN2EzZmMyZmYwMDA3MGYwNWY4MmFkNmM2NjQwMmZlN2ZmNDhiYzIzOQ0KZmRlMzdmMGZm YzA0NjA3ZTA0ZjdhZWNlOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAzOWVmMWI3ODRlZDNj NjllMTZiYWQxZWViMDhjZTM3YzEzNjMyNjI5NDdkZDZmZTg3ZDQxMjJiYzg3ZTFmZWFhOTczMDVm ZjAwYzINCjVmMWNjNWI2NDRjYzU2NmQyMWU3M2Q0MmFiMWVlMzg2NDNlOWM3YTBhZjdmYWYyZmY4 YzFmMGYyNGYxMmU5ZDFlYmRhMzJiYzdhZmU5YzM3YzY2MjM4Njk5MTRlNzY4M2Q3NzAzY2E5ZmE4 ZWUzMDAxYjNlMGFkNzJmYWQ2ZmU3DQpmMDZmODhhNWRmYWM1ODI2ZmI3Yjk2ZTNlZGY2ZGQxNjQx OWVhYzNhMzBmNTFmNWE0ZDYzZTFhNTlkZTZhZDNlYTlhM2ViMWFhNjgxNzk3MjczNzI3NGU5YjYy NGU3ZmJjYzlkMzc3YjhmN2Y1YWUzYmMzYmFlMGY4YWZlMTZiNw0KNjhlZTkyYzNjNzFhMTM3OTkw NGM3MDM3MzBlMGIxMWRkMWZhMzBjNzA3ZGIwMGZhMjc4M2ZjNTg5ZTI1YjQ5ZTFiOTgzZWM1YWNk OGJmOTM3ZjYyY2Q5Njg5Yzc3MWVhODdhODM0MDFjMzVmZTkzYTE3YzNhYmY4NjdiNjRiY2YNCjEz ZjhlMzUwZjkyYzg1ZjRiZTZjYjlmZWZmMDBhMjIwZjVlYmQ0NjcxOWM2MWU4N2UwODdkN2JlMmFj NzI2YjE3NmRhYTVlZTk2MTZlZjU4YjkzZmVhODVjMWU2MmI2OGM3Zjc1N2E5ZjVjNjM4ZTk1ZGZl YWJhNTY5MWYwZjZjDQo3YzRkZTM0ODJkZTdiY2Q0ZTY1Njk0YzkzMzE5NTk3MzgwYjFhOWVhYjFl ZWM2N2QwNzdjMDE1Y2FmODIyN2YxNGRiNzg1ZmNhZDJiNGM0YjAzNzBjZjdiYTllYmRhZDgyODFl NDdlNWQ5MjJlMTk4MDFkMGI2MDcxOTNkNjgwMw0KZDdhZWU2YjQ4YTIwOTc5MmMwOTFjY2MyMjAy NjYwMDM5NmUwMmYzZDQ5ZTk4ZWY1ZTRiYWI2ODNhY2ZjMjdkNDZlN2M0M2UxNDhkYWYzYzM1MzM4 OTM1MGQxZjkyNjExZGU0OGZkMDAxZjk3N2M4MWM3M2ZhN2Y4MjY0ZjhhMWUNCjIxZmVkMWJhZDVi NTNiYmQwYWNkYzg2ZDRlZTViNjM1ZTM4ZWEyMDhjNjE2MjhjNjNhZTA5ZjdlYzNkNTdjMjllMmQ0 ZjEyZWFiYTlkYWU5OTY2Y2ZhMWU5ZGI2ZGUyZDQ1YTUyYzI3OTQ3ZGU1NWM4Zjk4MDE4ZjliM2Y5 ZTY4DQowMzViYzM5ZTI1ZDJiYzU3YTQ0N2E5ZTkxNzRiM2RiYmYwYzNhMzQ2ZGRkNTg3NjIzZmNm MTVhZDVlNWRlMjBmODc3YWFlODdhYmNkZTI2Zjg3Yjc0YjY3N2QyMWRmNzVhNWI5ZmYwMDQ3YmFm NWMwZTgwZmI3NGU3ODJiNWI3ZQ0KMGNmODkzYTdmOGEyNTdkMzJmNjE2ZDJiNWY4MGVkOWY0ZWI5 Zjk1YjcwZWE1MzNmNzg3Yjc1MWZhZDAwNzZkNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUw MDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQNCjUxNDUwMDE1Y2RmOGNmYzZmYTQ3 ODIzNDkzNzlhOGNiYmE2NzA0NWI1YWExZmRlNGVkZTgwNzYxZDMyN2EwZmM4NTYwNzhiN2UyNjJk OTZhM2ZmMDhlZjg1MmQ3ZmI2YmM0NzJlNTQ0NTE3MzE1YmZiYzhjM2QzZDMzYzc3MjJhDQoxZjBj N2MzZmZlY2JkNDFiYzVkZTM3ZDUxMzUxZDc0MGRkZTY0Y2UwNDE2NjNkMTMzODFjNjdhZjAwNjc4 MWRjODA1MWYwZGY4M2I1NWYxNTZhZjBmOGNmZTIwNmMwNjI1ZGY2MWE0OTE4OGFkNTdhZWU3MDdi ZjQzODNmOGY0Yw0KMGI1ZTJmZDUyZjNlMjE3ODJiNTI4N2MwOTdjZDMwYjdiOGYyMmVjMmExOGZl ZDcxZTNlNjQ4YTUzYzc3ZWJkZjFlODc5Y2NmMTdhZjhjZmUyNDViZWFiNjFhMWRiY2JhNTY4ZDY1 YmEzMmI3NmE2MjkzNTM5NTRmMjgzYTE1OGYNCjgzY2Y3M2Q3ZmQ5ZWJmZTFjZjg5MzRjZDZmYzNh YjY3Njc2MDM0YmJhZDM3ZmQxYWViNGMyMzZiNWIzMGY2ZWI4M2NlMDllYmNlNzljZDAwNzIzNjdm MTEyZDY3ZjBjNTg3ODY3YzA5YTU0YjA2YmQyMmI1YWFkOGNhOWI3ZmIzDQpiNmYwZjI0YTQ4YzFj NjczOWVlN2FmMzkxNWQ3NWEyNjk3ZjBiYmMwZjJjZmE5ZWE1MzVjMDQ2NjllZTJlMjc3ZGQyNWNj ZWRjOTBhMDllYTRmNDFmODllZTZhYjc4YzdjMDJmYThkZmE3ODkzYzM1NzAzNGJmMTNkYjI5Mjkz YQ0KODAxMmU0N2Y3MjUxZGYzZDMzZjllNzAzMTliZTFkZDAzYzQxZTMwZDZhMGYxMGY4ZWFkMTZk MTM0ZjZkOTYzYTQwYzE4YzQ4MDYxYTc2ZTRlNzI3M2I3ZGIwN2RjODA3NjdhNTI1YWViYjZkYTY3 ODgyZWI0NjE2YmE4MTgzMzENCjhiODQ1MzM0MDFjNzJiYjg3NGNmZjVlODM5MTVjYjc4YTZmMmUz YzY3YWYzZjgyMzQ5OTlhM2IyODgwN2Q3MmYyMzNmZWFlMzNkMjA1MjNmOGRmOWNmYTBjZmI4YWQy ZjE4ZjhhYWVhY2FlNmRmYzM5ZTFlOGQyZTdjNDdhODI5DQpmMjk1OGZjOTZiMWY3OWE0ZjQwM2Iw ZWU3ZjJhZjNhZjFhZWI4OWUwMGYwZTQzZTA0ZjBiY2QyZGRmODkzNTI2Y2RlNWNhMWNjYzVlNGZi Y2M3MWNlZjdjZTA3NzAzOWY0MzQwMTlmZTM0ZDRlNWY4ODFlMjViMmY4NmRlMGUwOQ0KMTY4YjYy NDBiODk2MjFmYmIxYjM4Mjc4ZWE4OWQwN2Y3OWJmMDM1ZWViYTFlOGQ2N2UxZWQxMmNmNDlkM2Uz ZDk2YjZiMTg4ZDA3NzNlYTRmYjkzOTI0ZmE5MzVjYjdjMmZmODdmMDc4MTNjMzgyMzkwMmJlYWI3 NDAzZGU0YzMNCjljMWVjODBmZjc1NzI3ZWE0OTNmNGVlNjgwMGEyOGEyODAwYTI4YTI4MDBhMjhh MjgwMGEyOGEyODAwYTI4YTI4MDNjNGJlMjY3ODA2ZmZjM2ZhYzBmODgxZTBiYzViZGRkYWU2NWJj Yjc4ZDdlZjc1ZGQyMDFkMDgyMDlkY2JkDQpjNjRmYWQ1ZWQyZjU1OGJlMjQ2OWQ2OWUyY2YwYmNi NmY2M2UzM2QzMTM2Y2Y2Y2U3ZTU5ZDRmNTg5ZmQ1MWJhYWI3NjNlODc5MWViZmQ2YmMyZmM3M2Uw NmQ2M2MwYmUyNGZmMDA4NGViYzBiMTYyMjVjYjVlNThjNDk5MGFhNw0KZWYxMGEzYWM2NzFjODFm NzRmMjNkODAzZDU3YzI5ZTJhYjNmMTVlOTY2NTQ0ZmIzZGVjMGM2MmJkYjE5MGZlZjJkYTUwNzA1 NTg3YTY3YTFlZjU5M2UzMWYwNjZhMWUzMmQ2MmMyZDZmMzUzMTE3ODYyMjFlNjVkNTljMjBhYzkN CjcxMjAyMzZhYjM2N2VlN2U1OGM3YWUwOGU1YjQ3ZDRmNGZmODkzMWM1ZTI3ZjBhZGNjNWEzZjhj NmM5NzE3MTAzOWNhY2U5ZmRjOTQwYzZmOGNmMTg2ZWEzZWEyYmI3ZjA5ZjhjNjFmMTA4OTZjMmYy MDNhN2ViZDY5ZjJkZTY5DQpkMjlmOTkwOGZlMjVmZWYyMWM4YzMwZjVhMDBlMmZjN2ZlMmFiMThl ZTYxZjAxNjkzYTk1YTY4ZjZhOTE4MWE5ZGU2ZjExYWRhNWI4YzdlZWEzZTk5NzYxYzYwNzZmYzcx M2U5N2YxMGY0YWI1ZDM2MGQxM2UxZmYwMDg2MzUzZA0KNmExYjY1ZjJlMzY4YTIzMGRiOGY3Njkx Yzc1Mjc5MjQ4ZTczNWQyYzFmMGJmYzFiMGViMzczYWIzNjg3MDRmNzc3MTI5OTVkYWU0OTk1NDMx ZTQ5MGFjNDgxY2U0ZjRlZjU5M2UzMmQ2MmYzNTRkNGUyZjAwZjg1NWM0MTc5MzINCjA2ZDQ2ZWEy MTgxNjE2YzdkMzE4YzNiMDNjMGY0M2VmOTAwMTliZTA2ZjFiZjhjYmM0OWUyNGQ1YWUzNTFiNGIw ODc0MGQzMTFkMjYxNjg4ZDI5Njk0MGNlZDhkODEzYmQ4NzM5YzcxZTlkNDFhYmY3OWE1ZjgyN2Uz MDY5YzJmDQo2ZDJlMGM3YTk1YmYwYjcxMDlmMmFlYWQ1ODc0MGViZDQ4MDdkNzhlYjgzZGViYjdk MGI0M2QzZmMzN2EyZGI2OTVhNjQwMjFiNWI3NWRhYTNiYjFlZWNjN2I5Mjc5MjZiYzhlM2QwZGJl MjRmYzQ1ZDU3NWRkMDZmMWY0NGIzZA0KMmQ0ZGFjM2E5NTkyODBmNzc3MTljYjMzN2Y3OTQ3NDNl YTMxZWI0MDFhMmJlMjRmMWE3YzM1NzEwZjhiMmRlNGQ3ZjQwNTM4NWQ1ZWQxNzMzNDQzYjc5OGJm ZTNlYmY3OGY0YWY0NWQwN2M1MWEyNzg5ZWQ3ZWQzYTM2YTUwNWUNCjIwZmJjMjM2Zjk5M2ZkZTUz YzhmYzQ1NzIxMzc4ZWVlYmMxMTYzNmY2OWUzZjY4MjZiOWI4OWRlMjgyN2QzZDBiNzlkMGFhZTRj YWYxZmYwODE5MDA4MTlmNjE4MTU0ZTZmODc5ZTBmZjE3ZWRmMTA3ODM3NTVmZWNhYmVlYWI3DQo5 YTRjOWI1NDFmNDc4YzExODNlYTNlNTNlYjQwMWVhNTQ1Nzk0ZmZjMjQ3ZjEyN2MxNjRjNWFmNjg0 OWUyNGQzYTNmZjAwOTg4NjliZjJjZGI3ZDVhM2M3MjdmMDAzZGNkNzQxZTFmZjAwOGIxZTEwZjEw YzgyMDhmNTIxNjU3OA0KNGUwZGFkZmFmOTJlMGZhNzNmMjkzZWMwOWEwMGVkYThhNDBjMTgwMmE0 MTA3YTExNGI0MDA1MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1MzI1OTYzODYzNjkyNTkxNjM0 NTE5NjY3MzgwMDdkNjgwMWY0NTcwM2FkZmM2MWYNCjA5ZTkzM2ZkOTJkMmUyNmQ2MmY4OWRhYjZm YTZjN2U2OTI3ZmRlZmJiZjkxMjdkYWIxZmVkOWYxM2ZjNzNmYmJiN2IzOGJjMWZhNTM4ZTY3OThm OTk3NGNhN2QwNzA1NGZlMGE3ZGU4MDNiNWYxMzc4ZTNjM2JlMTA4MGJlYjFhDQo5NDUxNGJiNzcy NWJhOWRkMmJmZDEwNzNmODljMGY3YWUwY2NkZTNiZjhhMDQ4YjcxMmY4NTdjMzEyN2ZjYjU2MWZl OTc3MjllYzNiMDNmODBlN2FiNTZkNjk1ZjBlZmMyM2UwNWI1YjhkN2Y1M2RmN2Y3NzAyOTllN2Q0 YjUwYw0KY2NlYjhlNGIwMTgzODNlZjgyN2RlYWJhNzg5M2M1YmUzZjUxZmYwMDA4YTViOGQxMzQz N2ZmMDA5OGJkZjIwNjk2NjFkMGY5NTE3NmZhOWZkMGYxNDAxYTQzNGZmMGQ3YzFmZjAwMDY1ZGVh MTY1YTc0Y2QxNDJhMGNkMjIyZjkNCjkzNGVjNDgwMzczNzYxOTNlYzA2N2E1NjRlOTllMWFkNGJl MjI3ZDk3YzQxZTMyOWEzNWQyNTgyY2Y2M2EyNWI0YmJhMTBiZDU1ZTY2MWY3Y2UzYjc0ZmQ0NTQx ZTE3MzcxZTE5ZjE3NmExZjBmZmM0OTc3MzZhOTYxYWE0NmQ3DQozYTc1Y2RlOTJlNjcwNDdlZjYy NjI3YmYwNGUzZWJmZGUxNWNkY2ZlMWViZWQwYmM1OTY3ZTAxZDYzNWRiYmI2ZjA1ZGY0OGYyNTg3 OTY3MDY2YzkwN2VjY2YyNzU1MDBmZTc5ZjdlMDAzZDdiNDFmMTQ2ODlhZWRjZGVkOGU4ZA0KNzBi NzBiYTc5NThlNDc4OTBmOTQwOTFjMmFiNzQzOGM3NmU5NWNjZjhlM2MxZDdjOWE5YzdlMzNmMDkw ZjJiYzQ1NmEwNzlkMDAzODRiZjg4NzU4ZGM3NzM4MTgwN2Q4NzcwMDhiNWFiZjg5ZjQwZjg3ZjY5 NmJlMWZkMWI0ZWYNCmI0ZWEyZWI4YjNkMjJjMTdlNzYyN2Y4OWNmZjA4Y2Y1NjNjZjUzY2Q3NTNh MmNiYTljZmEzZGFjYmFjZGI0MTZkYTgzMjY2Nzg2MDcyZTg4ZGU4MGZmMDBmYWZlYTY4MDEzNDJk NGE1ZDYzNDNiM2Q0MjdiMDllYzI1Yjg4ODNiDQpkYWRjMGMzYzY3ZDBmZjAwOWU5ZDg3NGFjNWYx N2Y4YjhlODdmNjdkMmY0YTg1MmZiYzQzN2VkYjJjZWNiNzgxOGViOTkyNGY0NDE4MjQ5ZWZkM2Q0 ODgzYzUxZTMxOWFkNzUxNGYwZTc4NmUxOGVmZmM0OTM4MDdjYjZjZjk1Ng0KODg3ZmU1YTRjNDc0 MDA3NDFkNGYxZWEzM2M0NmJiZTIyZDJmZTEzZGJjYzE2NTFhZjc4ZTc1MzNiYTc5ZTQxZjM2NGY0 YzgxY2FhMGUwMmEwZWI4MWY1YTAwNjc4ODc1ZmI2Zjg0OWExY2YxYzc3MzFlYWJlMzlkNWNmOTk3 MTcNCjBjMzcxMDRmZjExMWQ5MTdhMmFmN2Y0ZWI1YTdmMGFiZTE5Y2ZhNDRiMjc4YWJjNGZmMDBl OTNlMjBiYzI2NTUxMmZjYzZkZjc2NDkyNGZmMDA3Y2U3OWY0ZTllYjU1N2UxOTdjMzZkNDFmNTY5 M2M2YmUzNTUzM2ViNTcyZGU2DQpjMTA0ZTM5ODRmNjc2MWQwMzYzODBiZmMyM2RmYTdiMTUwMDE0 NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwNzhh ZjhmYmUxNjVmNjk1YWFhZjhjM2MwMDFlZGI1Mzg1Y2NiMw0KNTljMjcwMWZkNGEwZTljZjM5NGU4 NzNjMGVjNTM0MmYxNGU4YmYxNWEyYjQ4ZWVhZTliYzNmZTM2YjFjOGI3Yjg4M2U1NjI3OWM4NWNm ZGY1M2RlMzI3M2Q3ZGNkN2I1ZDc5YTdjNDFmODQxYTc3OGIxZGI1NGQyOWQ3NGNkNzUNCjRlZjEz YTcwOTJiMGU5YmMwZTQxZmYwMDY4NzNmNWEwMGQxZDI3YzZiN2JhNTZhNTBlODNlMzc4MjNiMGQ0 MjQzYjJkNzUwOGZmMDBlM2Q2ZjdmZGQ2M2Y3MWZmMDBkOTM4ZWJlZTJiYjI4NmM2ZDJkZWVhZTJl YTFiNjg2M2I4DQpiOWRhNjY5NTEwMDY5MzY4YzBkYzdiZTA1NzgzNjk5ZjEwMmUzNGU2OTNjMGRm MTZiNGIzMjQwY2ExMTZmMjU0ZGM0YWU3MDE5ODhmYmMzZDI0NWU0NjM5YzljOTFkYzVhN2ZjMjQ3 ZTBkYjQ4ZWUzNDc5NWJjNTllMTQ2MWJlMg0KOGQyNDBmNzk2ZjFmZmQzMzZlOTMyOGVjM2FmNjFk MjgwMzQzZTI2NmExYWMxZDJlZDNjM2RhMGMxMzlkNDM1Yjk0ZGI3ZGE5NjM2ZDk2ZDFlM2U3NjJj MzgwNzZlNzFkZjE5M2RhYmE0ZjBlZTgzNjNlMTZmMGY1YTY5MTYyYTENCjZkZWQ2M2RiYjhmMDU4 ZjU2NjNlZTRlNDlhNjc4N2JjNTNhM2Y4YTZjY2RjZTk1NzhiMmVjM2I2NTg5ODZkOTYyNmVlYWU4 Nzk1M2Y1YThiYzY1YTZlYTlhYzc4NDc1MmQzNzQ2Yjk4YWRlZmFlNjEzMTI0YjI5MjE0MDNmNzg2 DQo0MDI0NjU3MjMzZGIzNDAxZTRkNjVlMzRiNmI5Zjg5MTdkZTM2ZDU3NDlkNDY3ZjBmYzI4ZGE3 NjlkN2YwNDA2NTg2MTU1M2YzYzhjMDczODZjOWU3ZDA5MWNmNmVjOWZjMTVlMTNmMTViMmY4ODNj MjdhYTFkMzJmODljZmRiYg0KNDc5ODI4NjNlOTIyMGUwZmI4MjAxZjVhYTFlMWFmMTdkYjc4MGY0 NmIwZjBkZjhhZjQ0YjhkMDU2ZGUzMTBjNTc2MDc5ZDZiNzA3YmI3OThhMzgyNDkyNDgzZDMzNWRi Njg1YTE3ODZlZDJlYWUzNWFkMDZkMmM5MWFmZDE0NDkNCjNkYTExYjI0MDA5MjA4ZGJmMmY1Mjcy NDc1ZTMzZDI4MDMxM2M0NWUzMGQ3ZmMyYjdkNzMzZGQ3ODVlNmJlZjBmYzI4MWZlZGQ2NzNhYjRh OGExN2U2MmYxOWM3N2M5YzhjMGM1NjU4ZDViZTE2ZmM0ZDU1OGFlYmVjMTJkZTRhDQowMDA5NzJi ZjY3YjkwNGY0MDFiODI3ZmUwMjQ4YTlmZTJmZGRjZDczYTE2OWZlMTViMjdkYjdkZTIwYmM0YjU1 YzdmMGM0MDg2NzZmYTBmOTQxZjYyNmJhZDNlMTRkMDVlMmQzZDY1ZDJhZDI1NmQzYzQ2MmRhNDky MTUyZjE2Yw0KYzZkYzM3NTE4YzBhMDBlMThmYzFjNmQyNThjOWUxMmYxNzZiM2EzMzY3M2U1MTkz Y2U4N2U5Yjc4ZmQ3MzQ4MDdjNjVkMGZlNTA3NDJmMTE0NDNmODliZjczMjExZTlmYzBhMGZlNzVl OWViMmM2ZjIzYzY5MjIzM2M2NDA3NTANCmMwOTUyNDY0NjQ3NmUyOWY0MDFlNWRmZjAwMGIxYmM2 ZGE3MWRiYWI3YzM0ZDQxYjZmMGNmNjEzNzljM2QzODBhYTdiZmJkMDNlMzhlOGYxNjNlZGJlMWNm MTI1YTAyMzg2OTJjODYwOWY0MWYzNTc0ZGUyOWYxZWU5ZmUxYWJlDQpiN2QyZDJkNmVmNTNkNjZl OTc3NDFhN2Q5NDdiZTQyYmNmY2NkZDk1NzgzY2ZiMWUzODM1OTdmZjAwMGIzYzY5YjdmNmY2ZGUy OGYwZTZhNWEwYzU3MmUyMzhhZWU3MmIyNDFiOGY2Njc1Mzg1ZmYzZDI4MDI4MmZjNzlmMDY4Yw0K ZmRhMDZhNzZiZmRkMTM1YTExYmJlOTgyNjg2ZjhmMWUwZjI3ZmQxZTJkNTZlNTdiYjQzNjc5MDBm YTcyNDU3YTVjODIyMjg1ZTQwODU1NDY3MmMzODAyYjk5ZjA2ZjhlYjQ0ZjE5OGJkNWQyMTY3OGNk YTMyZjk4OTM0NDEwYjANCjYwNzZiMmUwOWM4MzgzY2QwMDcyZmYwMGYwYmJiNGZiOGM4ZDNiYzJi ZTI1YmQyNGVkOGNjNzY2MzBjZGU5YzMxM2ZhNTAzYzdmZTNmZDRiOGQyN2UxYWRjYzQwZjJhZjdm NzQyMmY3ZTQzMDVlZGVmZDZiYjBkNTNjNTcwZTk3DQplMzBkMTNjM2QyZGFjODViNTY1OTlhM2I4 Y2UxNTRjNmJiODhjNjM5M2QzZjNhYjllMjViZmJiZDJiYzJmYWFlYTM2MDkxYzk3NzY5NjkyY2Yx MjQ4YTU5NTk5MTRiNjA4MDQxMzljNjM4MzQwMWMwZmQ4YmUzMTZiZDgxNzNhOQ0KNjhiZTFlODRm MGMyZDYzZjNhNGM3YjY3NzBmZjAwYzc4NTM4N2MxOGQzYWVjOGJhZjE2Nzg4ZjU4ZDZlNDVlNWJl ZDE3MjYzODg3ZTFjOTFmZjAwN2Q1MmY4OGJjNmZhYzQzZjBiYmMzZGUzMWIxOTk2MmRkMzVhY2Jh OTI0NzENCjA2NTY4OThlMjQ1MWJiMjU0NmVjMGNmNWU3YWQzZmM2OTBjMWUyZGY4OGRlMTlmMGFk YzMzY2RhNGZkOWE2ZDQ2ZjYwNDY2MGIyYTgxYjYzZGM0MTFjNmUxZmFkMDA1OTliYzRiZjBkZmUx YjIzZDlkOWZkOGEwYmE0NWRhNmRhDQpjMjJmMzY3NmM3Mzg2MjMyNzNkZmU3MjJhYzc4NmZjNjNl MjVmMTZkZWQ5ZGVlOWZlMWI4ZWNiYzM3MjEyY2Q3NzdkNzAzY2U5NTMwNzA1MTE3MzhlNzFkNzIw ZjNjZDc1MTY5ZTFiZDEyYzQ0ZmY2NWQyYWNlMjMzYWVjOTk5Ng0KMTVkZDIyZTMxODYzZDQ4Yzdh ZDcxM2YwOWE1OTM0NzdkN2JjMTM3MmVjNjVkMTJmMDliN2RjN2VmNWJjOWYzMjExZmE5M2ZlZjBh MDBmNDc5YTE4ZWUyMDkyMDk5MTY0OGE0NTI4ZThjMzIxOTQ4YzEwNmJjY2ZjMDMzY2JlMGMNCmYx NWRmN2MzZGJlOTE4ZGI3Y2Q3OWEyY2FlNzNiZTE2MjRiNDc5ZjUwNzNmOTM3YjU3NDVlMmFkM2Zj NjdhYWRmYzU2OWExNmFkNjNhNGU5NmQxZmVmZWU4YzQ2NGI5ZGQ5MzkwODBmY2I4YzYzOWUwZmJk NTFmMTlmODI2ZmY1DQo2ZjBmZTkyZmE1ZGYxNmYxMTY4YjI0NzI1OWRlZGMxYzE5MDhjMDYwZTQ3 Zjc4MGM5ZTM5MjNkY2QwMDU5Zjg5M2UxNzlmYzQ1ZTFkMTczYTZiMThmNWNkMmRmZWQ3YTdjY2Jm NzgzYWYyNTdmZTA0MDYzZWI4YWFhYjA1ODdjNQ0KZGY4Njc2ZWQ3NzEzZGI0YjNhODcwZGI0ODZi NWI5NWUzNzJlNzE5YzFjZmQ0MWY3YWVlNjEzMjk4MjMzMzg0MTM2ZDFlNjA0MjRhODZjNzM4Mjdi NjZiMDdjNDllMzNkMWZjMmViMWM1NzUyNDkzZGZjZGM1YmU5ZjY4OWU2NWMNCjRjN2QxNTA3M2Y4 OWMwYTAwODdjMjllMGFkMjNjMWI2OTJjYjBiM2NmN2QyOGRkNzdhOGRkMzZlOTY2M2RjYjMxZTgz ZGJmZjAwZDc1OGI3N2UyYmQ1YmM2NTc1MmU5N2UwN2RiMWQ5YTM3OTc3NWFmY2E5OThhM2Y1NTgw N2ZjDQpiNDdmN2U4MzhmNTA2YThlYTk2N2E5Zjg4MmM5ZjU0ZjFmZGVjM2EwNzg2NjJmOWZmYjI2 MjlmZTc5YmQzY2Y5MDc1ZmY3MTdhZmQ0NTcxNWE4NzhjZmM0MWYxMTZlYmZlMTEzZjg3MzYwNzRk ZDBlMTAyMzk2ZTk1N2NhYzI3Yg0KOTFmZWFkN2QxNDdjYzcxZjUxNDAxYTFhZWY4ZDc0Y2YwMGRi YmY4NWJjMGExYjU2ZjEyZGVjYzQ1ZDVlYmZlZjlkYTYzYzEyYzdmOGU0Y2Y0NWU4M2JmNzA3Nzdl MWFmYzI2ZmVjNTljNzg5M2M1MjdlZGJlMjI5OWNjYjg5MWYNCjc4Yjc2M2RmM2ZjNGZlZmQwNzZm NWFkZWYwMDdjMmVkMTdjMGI2ZWIyYzZhMmVmNTU2NWM0OTdiMjJmMjMzZDQyMGZlMTFmYTllZTZi YjlhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhDQowMDI4 YTI4YTAwMjhhMjhhMDAyOGEyOGEwMGM0ZjEzNzg0ZjQ1ZjE3ZTk4NmM3NTliMzU5ZTMxOTMxYjhl MWUyMjdiYWI3NTA3ZjQzZGYzNWUzNTczZTEwZjFlN2MyNGJhOTZmZmMyNTc0ZmFiZTg2NThiY2I2 NmViYjg4MWZlZA0KMjBlZjhmZTI0ZTc4ZTQ2MmJlODBhMjgwM2M0NzQ5ZjEzNzgzM2UyNGRlNDc3 NTE1Y2NiZTE1ZjE4MjhjMjVjNDRlMTFhNDNjNzFiYjg1OTQ3NGY5NWIwZGM1NzVmZjAwZjA5Mzc4 YjdjMmI4OGZjNTFhMjdmNjlkODI3NWQ1YjQNCjgxYjg4MWViMjQwN2U2MWVhNGFlNDUyNzhkYmUx MGY4NzNjNjQ1ZWViY2JmZWNlZDRkYjkzNzc2Y2EzZTczZmVkYWY0NmZhZjA3ZGViY2YzNzdjNTVm ODRmZjAwMjZkZmY4NDgzNDM4ZmExYzM0Y2E4YTNmZjFmOGYwM2VhYTNkDQplODAzZGFmNGRkNjM0 MWYxODY5MmVmNjM3MzY5YTk1OTQ4MzZjODljMzhlN2IzYTFlNDdkMDhhYmZhN2U5ZDY3YTU1ODQ1 NjM2MTZkMWRiNWFjMjA4OGUyOGQ3MGFhMzM5ZTA3ZDQ5YWYxMmQzZmM1NWYwZTdjNzU3NGI3OTI0 Zg0KNzFlMTFmMTE5ZWI3NTA0ZGU0MTYzZWYyMGY5MWM2NzFmN2MwMzVkYmE0ZGYxMDdjM2U4YWVh MmMzYzVkYTdlMzJhZjFiMGI1YmFjN2FmZmNmMzZlM2QzMDRkMDA1ODZmMGU2YTVhOGZjNWQ0ZDdl ZmUxNTVkMmY0Y2IwZjI3NGYNCjIyNDA3N2NhZjlkZWM0NzUxODA0OGZjMDU2ZWY4YWVjZWYzNTFm MGRkZDU4ZDhkYjQ3NzEzNWMwMTE5NDkyZTVhMDAxNDkxOTZkZWEwOTE4MWNmMTU4YjY1ZjEzZmMz ZjI0ZTJkNzU3ZmI1NjgxN2E3OGYyMzU2ODRjMTlmYTNmDQpkYzIzZjFhZWJlZGVlNjBiYzgxNjdi NjllMzllMjZmYmIyNDRlMTk0ZmQwOGEwMGYyY2Y4NmYxNmFmMjZiM2Y2YTdiOGJjZmIxZGQ4OTJl NWVlN2VjYTBhNWVlY2ZkYzI4OTI0NmY5OTU4NmMwZTAwMDM3MDI0ZjcyMDdhYzUxNA0KNTAwNzk4 N2MzNzgxNmZiZTIwZjhmNzVhYjk2NTkyZjEzNTEzNjMxOTI3MjYzODkzMjAwMWU4MGUxN2ZlZjlh ZWZiNWRkMGI0ZmYwMDEyNjhmM2U5NWFhNDFlNzU5Y2Y4ZGU5OTIwZjA0MTE4MjM5MWM4MWQyYjg5 ZDQ3YzNkZTINCjVmMGJmOGQyZmJjNGJlMTRiNTgzNTJiM2Q1MDI5ZDQzNGI5MjUxMTM5OTE3ODBm MWI5ZTAxZTRlNzNlYTdhZjZhYmE5N2ZjMjc5ZTNkN2I2ZDM0ZTkzMmY4NTM0OTEyYWM5Nzc3NjZm MTVlZTI0MGE3MjE2MzA5Y2FmMjNhZmQzDQplODQwMzUzZTI3ZWE4M2MzMWYwZDI1YjNiMjk3Y2I5 ZWU5NjNkMzJkNWE0OTMyNDZmMWI0OTJjN2I4NDBjNzI3ZDJiOTE5NmU3NDBmMDI3OGJmYzIzN2Zh NGVhZjYzNzE2NzI1YWFlOGJhODg4NmU1MWNlMzAwYTRhYzAxZmVmMA0KMzkzZTgzMWRlYmE4ZjEw Nzg2ZWUzYzRmZjEyNzQ0YjZiZmQzOWE2ZjBlNjkzNjkyNGNlZDcyMDNjNzcxM2IwZGExNDgzOWRk ODE4M2NmYmQ1YmYxNDdjMzFmMGRlYWRlMThkNDJjYjRmZDA3NGFiM2JlOTIxM2Y2NzllMGI1OGUN CjM2NDkwNzJiZjMwMDA4MTkwMDFmNjI2ODAzMTdlMzBiNWU2OWZhOGY4Mzc1YWQzYTM4OWVmNmRi NTQzNmYxMDk3MjEwOTk1NzE4NjIzOTAwZWRhYjc3NWEzZmM1MmQ2NmNlN2I1YmRkNjNjMzdhN2Mz MzQ2ZDFiOGI0YjY5MjUyDQo1NGYwNDdjZmVhMDkxNTU3NWVkMDNjNTVlMjdmODQ5YTVkYWRjZDg4 OGZjNGQ2NTM0MTI5OGE1OTkwZWY3OGRiNmVmZGUxYjAwOTUyNWJhZjcyMmJkNDY4MDNjODNjMTM2 MmRlMjZmZDllZWViNDM5MTRiNWM0NTE1Y2RhODU2Yw0KZTQ0OGFlY2M4MGU3ZDBlZGFjMWYwYWU4 N2FlNDVlMGJkM2ZjNzllMGViZmI4YmFkNjBjM2U1ZWExNjE3YWMyNjE3MmIxYjE1MmFhNGZjY2Jk MzIxNzNkMzE4ZWQ5ZjU3ZjA1Zjg1NWZjMjU2OWFhNWI5YmI1Yjg4ZWYzNTI5YWYNCjYyNTU0MmEy MTU3YzYxM2E5Y2UzMWVkZDZhZGY4NjNjMmY2MWUxMmQzZWUyY2I0ZTY5OGMxMzVjYmRjZWQ5NTgx ZDhjZjhjYWFlMDBjMmYxYzBhMDBhOWUwOWYxYjY5YmUzN2QxZmVkNzY3OTg2ZWEyM2IyZWFjZTQz ZjNjMGZlDQo4N2Q0NzVjMWVmZWM3MjA1MGJmZjAwMGNlYTUwZmM1NmQzM2M0ZGE1YTQ3ZjY1OWFj ZTRiNGQ1MDMzZTA5NTE4MzE5MDNiOWNlM2YwNWY3YWU5MjYzYTM2ODRiMzVmNGRmNjBkM2M0YWM1 YTU5ZGY2NDViY2Y1MjU5YjhjOWZhZA0KNzMxNzNmMTNmNGE5YTY2YjZmMGVkOTZhMWUyMmI5MDc2 OTFhNzQyNGM0YTdmZGE5NWIwYTA3YjhjZDAwNzcxNTg5ZTIxZjE2ZTg3ZTE3ODU1ZjU2YmY4ZTE5 MWZmZDU0MGJmM2NiMjllODAyYTBlNGYzZWQ1Y2JkZDQ3ZTM5ZDYNCjZkZGVlMzU3ZDUyYzNjMjFh NTgxOTc0Yjc3NTlhZTAyZjdkZDJiNjExM2VhYjVjM2RkNzhmN2MwM2UwMzlkYzc4NjZjZTVmMTE2 YmYyN2NhZDdmM2I5OTE5OWJhNzMyYjBjOWVkYzIwYzFmNWEwMGVlOWY1NWYxYmY4YjExOTc0DQpj YjA1ZjBiZTk2ZGQ2ZmY1MGMzZGQzMjdhYTQyMzg0M2ZlZjFhZTJmNTBmMWNmODNmZTFlNGYzNWFm ODVlZGRmYzQ1ZTI3YjgzYjI2YmY5NjQzMmIzMzljNzBkMjc1NmVkZjJhNzFjNzUwNmE5MGYwZjdj NTBmOGFjYzFmNWRiOQ0KM2ExNjg4ZTdmZTNkY2ExOGMzMGY2OGIzYjliZmUwNjQwZjRhZjUyZjA2 N2MzNGYwZTc4MjIzMGY2MTZkZTdkZjkxODdiZGI4YzM0YTdkNDBlY2EzZDg2M2RmMzQwMWU2YmE2 N2MzMWYxNmZjNDRkNDYzZDZiZTIwZWExM2RhZGENCmU0YjQ1NjExOWMzYTgzZDgyZjQ4YzdlNmM3 MWNmYWQ3YjU2OGJhMWU5OWUxZWQzMjNkM2I0OWIzOGFkMmQ2M2U4OTE4ZWE3ZDQ5ZWE0ZmI5ZTZi NDI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwDQowMjhhMjhhMDAy OGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDBlMmZjNGZmMDAw YWJjMjNlMmIyZjJkZGU5OGI2Zjc2ZGM5YmFiM2ZkZDQ4NGZhOWM3MGM3ZGQ4MWFmM2QzZjBhYmM3 ZmUwYQ0KNzY5N2MxMWUyODMzZGI4MzlmYjI0Y2RiMzNmZjAwMDE2Y2M2N2VhNzE1ZWVkNDUwMDc4 MGNkZjE2ZmM0NWE0NDI3NGZmODg1ZTA3MTNkYjkyMTVhNDMwZWQ1N2ZjMTgzMjM3ZTA0MGE5NzRl ZDZmZTExZWFkMzdkYTM0Y2Q0NzUNCjFmMDlkZjM3MjRkYmNhZjZiZjllZGRkMWQ3YmJjOTFhNGIx YjQ3MjIyYmEzMGMxNTYxOTA3ZjBhZTNmNThmODUzZTA4ZDZkZGE0YjlkMDJkYTM5NGZmMDAxZGFl NjAzZjVjMjEwMGZlMjI4MDMyZWMyYzdjNTI2MjBmZTFhZjg4DQo1YTdlYjU2ZTA3MTFkZmMwOTJm MWVmMjQ0NDEzZjhkNWNmZWQ5Zjg5MTYxODE3NWUxM2QyYjU0ZTc5N2QzYjUxZjI3ZjQ5NDdmNWFl NDJmYmY2NzRkMjQ0YmU2ZThkYWZlYTM2MzIwZTQ3OWFhYjJlMGY2YzExYjRmYTdhZDU0Zg0KZjg1 NjdmMTU3NDYxOGQxZmM3M2Y2ODg4NzBhOTM1YzQ4MzAzZmRkNjBjMDc0MWRlODAzYmJmZjg1ODNh ODViNzFhOGY4MTNjNGIwZmFiNWJjMDk3MGEwN2Q1MWIzZDdkYThmZjAwODVhYmEyYzdjNWQ2OTdl MjBiNDdmZWU0ZmENCjU0YTBlM2Q3ODA3OGFlMTdlZDFmMWVmNGIzOTc4MmQ3NTE1MDczOWM1Yjlj ZTdiNjE0YTllMjk3ZmUxMzlmOGQxNmJmYmE5N2MxNzZiMzM4ZWFlMmQ1ZGIzZjhhYzk4YTAwZWU3 ZmUxNzBmODE3ZmU4MzEzN2ZlMGJlZTdmZjAwDQo4ZGQxZmYwMDBiODNjMTA3ODRkNTZlMjQ3M2Y3 NTE3NGZiOWNiMWY0MWZiYmViNWMyOGY4YWZmMTM0MDAxYmUxYzVkMTNkYzhiMWI5YzdmMmEwZmM1 NGY4YTEyZmM5MGZjM2FiODQ5MWI4NTY5MmM2ZTM2ODNlZmQzZjk4YTAwZQ0KZWJmZTE2OWU5MzI3 ZmM3YTY4ZGUyM2JiMjNlZjA4MzQ5OTQ5NWZhZTQwYTNmZTEzZGQ2NmViOGQzM2MwMWUyMDk0OWU4 NmVmY2FiNTA3ZDM5NjYzYzdmMmFlMWJmZTEzNmY4ZDU3OWYyNDNlMGViNTgxOTc5MmM2ZDk5NzNl ZGYNCjNjOThhNDBiZjFlYjU3MzgyZjZiYTY0NmY5ZmYwMDlmNzE4MDdmZWZhNjE4ZmNlODAzYjlm ZWQzZjg5N2E4ZTNlY2RlMWVkMTM0ODUyNzkzN2Y3YWQ3MGMwN2QyMjE4Y2ZlMzU5ZGE5NTk2YjUw YzY1ZmM1N2YxMzYwZDJlM2VhDQo2MGQzZTM4YWQ3MWRmODc3MjVjZDcyZGZmMGFhN2UyNTZiNWZm MjFjZjFlMzQ1MWI3ZGU4ZTE5YTU3MWZmN2M4ZDhiZDg1Njg2OWJmYjNhNzg3YTE5MDQ5YWFlYWRh OGRmYmU3MjQyOTU4OTRmYjFlMDlmYzg4YTAwYzViZGYxMw0KN2MxZmQwYTczM2JhNWVmOGE3NTAx ZDY1YmEyZjcyNDlmNzMyOTA5ZjkwMzRmOGJlMjdmOGYzYzUyODk2N2UwNmYwN2FkOGRhZTMwOTNi NDdiOTU0N2IzMzA1OGQ3ZTg3MzVlYTNhMzdjMzVmMDc2ODBjMWVjMzQwYjQxMjhlOTINCjRjYTY2 NzA3ZDQxNzI0OGZjMmJhOTAwMjgwMDAwMDBlMDAxNDAxZTFiNmZmMDAwNjdjNTNlMmFiODRiYmYx ZTc4YWE1OTE0MWM4YjZiNzdkZTQ3YjAyNDA0NGZjMTRkN2E1Zjg2M2UxZGY4NWZjMjIxNWI0YWQy YTIxNzIzZmU1DQplYTZmZGU0YTdmZTA0N2E3ZDA2MDU3NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0 NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1 MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MQ0KNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0 NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1 MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDA3ZmZm ZDl9fX17XHNwe1xzbiBmUHJlZmVyUmVsYXRpdmVSZXNpemV9e1xzdiAxfX17XHNwe1xzbiBmTGF5 b3V0SW5DZWxsfXtcc3YgMX19DQp7XHNwe1xzbiBmQmVoaW5kRG9jdW1lbnR9e1xzdiAxfX17XHNw e1xzbiBmTGF5b3V0SW5DZWxsfXtcc3YgMX19fXtcc2hwcnNsdFxwYXJccGFyZFxxbCBcbGkwXHJp MFx3aWRjdGxwYXJccHZwYXJhXHBvc3g0OTg0XHBvc3kzODdcZHhmcnRleHQxODBcZGZybXR4dHgx ODBcZGZybXR4dHkwXGFzcGFscGhhXGFzcG51bVxmYWF1dG9cYWRqdXN0cmlnaHRccmluMFxsaW4w XGl0YXAwIA0Ke1xwaWN0XHBpY3NjYWxleDQ0XHBpY3NjYWxleTQ0XHBpY2Nyb3BsMFxwaWNjcm9w cjBccGljY3JvcHQwXHBpY2Nyb3BiMFxwaWN3OTcxMFxwaWNoOTUyNVxwaWN3Z29hbDU1MDVccGlj aGdvYWw1NDAwXHdtZXRhZmlsZThcYmxpcHRhZzQyNTY1MDc3M1xibGlwdXBpLTk2e1wqXGJsaXB1 aWQgMTk1ZWVhNTUzZDVmNmM4ZGFkMWM2YzIyOGI3M2FhZTN9DQowMTAwMDkwMDAwMDMwNjA1MDEw MDAwMDBlMTA0MDEwMDAwMDAwNDAwMDAwMDAzMDEwODAwMDUwMDAwMDAwYjAyMDAwMDAwMDAwNTAw MDAwMDBjMDI2OTAxNzAwMTAzMDAwMDAwMWUwMDA0MDAwMDAwMDcwMTA0MDBlMTA0MDEwMA0KNDEw YjIwMDBjYzAwNjgwMTZmMDEwMDAwMDAwMDY4MDE2ZjAxMDAwMDAwMDAyODAwMDAwMDZmMDEwMDAw NjgwMTAwMDAwMTAwMDgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDANCjAwMDBmZmZmZmYwMGZlZmVmZTAwZmNmY2ZjMDBmYmZiZmIwMGZhZmFmYTAw ZjdmN2Y3MDBmOGY4ZjgwMGYyZjJmMjAwZmRmZGZkMDBmOWY5ZjkwMGY2ZjZmNjAwZWVlZWVlMDBl MGUwZTAwMGJiYmJiYjAwYjNiM2IzMDBiZWJlDQpiZTAwYTVhNWE1MDA4MTgxODEwMDY0NjQ2NDAw NTc1NzU3MDA1ODU4NTgwMDVkNWQ1ZDAwNjE2MTYxMDAwOTA5MDkwMDA2MDYwNjAwMDEwMTAxMDAw MjAyMDIwMDA0MDQwNDAwMjUyNTI1MDA0ZjRmNGYwMDVjNWM1YzAwNWI1Yg0KNWIwMDU5NTk1OTAw N2U3ZTdlMDBhM2EzYTMwMGJhYmFiYTAwYmZiZmJmMDBhY2FjYWMwMGU1ZTVlNTAwZjVmNWY1MDBm NGY0ZjQwMGYzZjNmMzAwZWNlY2VjMDBmMGYwZjAwMGM5YzljOTAwYmRiZGJkMDBhZWFlYWUwMDY1 NjUNCjY1MDA2ZjZmNmYwMDNmM2YzZjAwMTMxMzEzMDAxYzFjMWMwMDExMTExMTAwMDgwODA4MDAw MzAzMDMwMDA3MDcwNzAwMDUwNTA1MDAwYzBjMGMwMDFlMWUxZTAwNGI0YjRiMDA1NjU2NTYwMDcw NzA3MDAwYWZhZmFmMDBkMGQwDQpkMDAwZWZlZmVmMDBmMWYxZjEwMGRmZGZkZjAwOTE5MTkxMDA2 YTZhNmEwMDJlMmUyZTAwMWExYTFhMDAwYTBhMGEwMDBmMGYwZjAwMGIwYjBiMDAxOTE5MTkwMDY5 Njk2OTAwOGI4YjhiMDBjN2M3YzcwMGUyZTJlMjAwZWFlYQ0KZWEwMGI1YjViNTAwNzc3Nzc3MDAz ZDNkM2QwMDJjMmMyYzAwMTAxMDEwMDAwZDBkMGQwMDRkNGQ0ZDAwNjI2MjYyMDA2ODY4NjgwMDY2 NjY2NjAwNjM2MzYzMDA2YjZiNmIwMDcyNzI3MjAwMzMzMzMzMDAxNDE0MTQwMDQwNDANCjQwMDBh ZGFkYWQwMGUzZTNlMzAwY2RjZGNkMDA5ZTllOWUwMDUzNTM1MzAwMjcyNzI3MDA2ZDZkNmQwMGEx YTFhMTAwYjBiMGIwMDBhNmE2YTYwMGI5YjliOTAwYWJhYmFiMDA1MDUwNTAwMDRhNGE0YTAwMWIx YjFiMDA4ZDhkDQo4ZDAwZDlkOWQ5MDBjNGM0YzQwMDc4Nzg3ODAwMzAzMDMwMDAzYTNhM2EwMDc1 NzU3NTAwOGM4YzhjMDA5ZjlmOWYwMGU2ZTZlNjAwZThlOGU4MDBhNGE0YTQwMDljOWM5YzAwN2I3 YjdiMDAzYjNiM2IwMDIzMjMyMzAwMzIzMg0KMzIwMGQxZDFkMTAwYThhOGE4MDA0NzQ3NDcwMDIy MjIyMjAwNmU2ZTZlMDA5NTk1OTUwMGNiY2JjYjAwZWRlZGVkMDBjZmNmY2YwMDczNzM3MzAwMTcx NzE3MDBhMmEyYTIwMGUxZTFlMTAwZWJlYmViMDBjMGMwYzAwMDdhN2ENCjdhMDAzNDM0MzQwMDBl MGUwZTAwMzYzNjM2MDBjY2NjY2MwMDk5OTk5OTAwODQ4NDg0MDA4ZjhmOGYwMDM3MzczNzAwMmQy ZDJkMDAzMTMxMzEwMDQzNDM0MzAwNzk3OTc5MDA4YThhOGEwMDg1ODU4NTAwZTllOWU5MDBlN2U3 DQplNzAwODI4MjgyMDBiY2JjYmMwMDk4OTg5ODAwMmEyYTJhMDA0NDQ0NDQwMDlhOWE5YTAwYjFi MWIxMDBjNWM1YzUwMDE1MTUxNTAwN2Q3ZDdkMDA4MDgwODAwMGMyYzJjMjAwZGFkYWRhMDA5MDkw OTAwMDVlNWU1ZTAwMzgzOA0KMzgwMDUxNTE1MTAwNjA2MDYwMDBhMGEwYTAwMDQ1NDU0NTAwMjEy MTIxMDBjM2MzYzMwMDc0NzQ3NDAwMmYyZjJmMDBjMWMxYzEwMDIwMjAyMDAwNTU1NTU1MDAzNTM1 MzUwMDg3ODc4NzAwZDdkN2Q3MDBlNGU0ZTQwMDhlOGUNCjhlMDA3YzdjN2MwMDE2MTYxNjAwNmM2 YzZjMDA5YjliOWIwMGQyZDJkMjAwZGJkYmRiMDAxZjFmMWYwMGNhY2FjYTAwNDk0OTQ5MDAxZDFk MWQwMDEyMTIxMjAwZDZkNmQ2MDA3MTcxNzEwMDI2MjYyNjAwODg4ODg4MDA1NDU0DQo1NDAwM2Uz ZTNlMDA4Njg2ODYwMDkzOTM5MzAwZDRkNGQ0MDAxODE4MTgwMGI4YjhiODAwMjkyOTI5MDBiNGI0 YjQwMGI3YjdiNzAwYjZiNmI2MDA1MjUyNTIwMGQ1ZDVkNTAwZDhkOGQ4MDA5Nzk3OTcwMDRjNGM0 YzAwYjJiMg0KYjIwMDVhNWE1YTAwMjgyODI4MDA5Njk2OTYwMDg5ODk4OTAwOTI5MjkyMDAzYzNj M2MwMGRkZGRkZDAwZGNkY2RjMDA1ZjVmNWYwMGFhYWFhYTAwZGVkZWRlMDBjOGM4YzgwMDY3Njc2 NzAwNGU0ZTRlMDAyYjJiMmIwMDk0OTQNCjk0MDA0MTQxNDEwMDc2NzY3NjAwNDI0MjQyMDBhOWE5 YTkwMDQ4NDg0ODAwODM4MzgzMDAzOTM5MzkwMDQ2NDY0NjAwOWQ5ZDlkMDBhN2E3YTcwMDdmN2Y3 ZjAwY2VjZWNlMDBkM2QzZDMwMGM2YzZjNjAwMjQyNDI0MDAwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDJhNzAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyZmYw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMDAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIN CjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyZmYwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQow MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMmZmMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMmZmMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMTAxDQowMTAyMDMwNDAxMDEwMzAxMDIyODBiMDEwMTAyMDUwMTA0MDEwYTAyMmEwMTAx MDkwNTA1MDEwMTAxMDQwMTA3MDUwMTAyMDUwMjAxMDIwMzA0MDkwMTAxMDEwOTAzMDMwOTAxMDEw MTA5MDUwMTA2MDcwMTAxMDcwNjAxMDEwMw0KMDcwMzAxMDEwNDA1MDEwNzAzMDEwYjA1MDEwMzAy MDIwMTAxMDEwMjA5MDQwMTAzMDQwMTAxMDMwYTA5MDEwMTAxMDUwNjA1MDEwMTAxMDMwMzAxMDkw NzA0MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDJmZjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDkwOTAxMDEwMTAyMGEwNjA0MDkwMTAxMDEwMTAzMDkwMTAxDQoyYzA3MDEw MTA0MmEwNjAxMDEwMTAxMjgwMjAxMDIwMTAxMDcwYTBkMGUwZjEwMTExMjEzMTQxNTE2MTcxODE5 MWEwMDAwMDAwMDFiMDAxYzE4MWMwMDAwMWQxZTFmMjAyMTU4MjI4YzZiMTA2MTI3MDEwYTAzMDEw MTAxMDMwNQ0KMDEwNzAyMGEwMTAxMDMwMTA5MGEwYTAyMDEwMTAyMDcwNTAxMDEwMTBhMmEwMTAy MDIwMTAxMDQwNTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEwNDA0MDIwMTAxMDEwMTA2MGMwYTAxMDEwYTBhMDUwOTAx MGEyYTI4MDEwMTAxMDcwMTAzMDQ4MTI1NjEzMDMxDQozMjMzMzQzNTAwMDAzNjM3MDAwMDFiMWIw MDAwMzgxOTFjMDAwMDAwMWExOTAwMDAwMDAwMDAwMDFiMWIwMDM5MWIwMDAwM2ExOTAwMzkzNjM5 YmEzYzE0NTIwZWVjY2MwNzA5MDEwNDAxMDcwMzAxMDEwMjA3MDIwMTA0MDEwMQ0KMDEwMTBhNDIw NzAxMDEwOTA5MDEwMTAyMDQwMzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxMDkwYTA0MDEwMTAyMDIwMTAxMDEwMTBiMDQw MTAxMjgwMTAxMDEwMTAzZDRmZWFlNThiOGUyMzY0ODM5MzY0OTAwMDAxYTFjMDAzNjAwMDAwMDFh MWExYTAwMDAwMDAwDQoxYjFjMWEwMDAwMzcwMDE4NGExYTAwMDAxYzFjMDAzNzAwMDAwMDM3Mzgz NzAwMzcwMDAwMTgzYTM4NGEwMDM5NjY5MzQ1NGQ0ZTRmOGUwYjAyMDkwNTAzMDEwMTAxMDIwMzAx MDEwMTAxMDIwMzA1MGEwMzAxMDEwMjA5MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyZmYw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA3MDENCjAxMDEwMTAyMDUyYTAxMDIwNjJh MDUwMTAxMGEwMTI5OGVlYTY3YjA5YWMyMDAwMDFjMWM5MjAwMDAwMDAwMDAxYTM1MWIwMDAwMDAw MDFjM2E1NjQ4MTg1NjMzNTcxNDU4NTk1YTViNTg1YjVjMTMxNjEzNWQ1OTVlMDA0ODRhDQozNTVm NDgwMDAwMzkzOTAwMzk0ODAwMDAxODAwMTkzNzM2MDAwMDAwMDAxYmY4YzljMzYxN2EwMTAxMDEy OTAxMDEwNzA4MDUwMzI5MDEwMjAzMDUwMzAyMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMmZmMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwOTAxMDEwNTA5MDEwMTAxMDUw MjAyMDEwMTA1ZmNiMzZlN2YNCjM4MDAxYTFjMWEwMDM4MDAwMDAwMDAwMDFiMzkxODAwNGIzYzFl Njc2ODY5NmExMDQzMGIwOTA0MDcwNjA2MDQwMTAxMDEwMTAxMDEwNzAxMDEwNzQyMDYwMTAxMDYw YjAyMDFiZjZiN2I2YTY5NWJlZWY1MzMwMDM2MDAwMDAwDQowMDM3MWMzODM5MWMwMDAwMzk0YTAw M2E2ZGE2NzE0MjAxMDkwOTAxMDEwMjAxMDEwMTAyMDQwOTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTA1MGIwMzAx MDI0MTAxMDdiNjUyNzQzNjFhMzgwMDAwMDAzODM5MWIwMGNiMDAzNjM2ZWZmMTIyOTc2NDBiNzkN CjI4MDEwNzI5MDEwMTA3MDkwMTAxMDEwMTAxMDEwMTAxMDIwOTA5MDkwMjAxMDEwMTAyMDEwMTAx MDkyODAxMDEwMTAxMDIwNTAxMDEwMTBhMDEwMTQyMDlhMDhjYjMxMmYxZmYwMDFjMDAwMGNiMDAw MDAwMzYxOTAwMDAxYTRhDQo5YTUyYjYyOTAyMDYyYTA5MDEwMTA0MDMwMTAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyZmYwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjBhMDkw MTAxMDEwYTgxODJiNGI1MWEwMDFiMWIwMDAwMWM0ODAwMzczOTQ3OWFjMzk3MmQ2MjAxMmIwMTA3 MDIwMTAxMDIwOTAxMDEwMTAxMDEwMjA3MGIwNTA5MDkwNDA5MDkNCjA5MDIwMTAxMDMwNTAyMDMw NDAzMDQwNDAyMDEwOTAxMDEwMzA5MDEwMjA1MDEwOTAxMDEwMjAyMDEwOTI4MDEwYzAxNGZjY2Fl OGE1NGM3NTYwMDAwMDAwMDAwMWMwMDFhMWMxYWMyZTE2ODhkMDgwMTAyMDQwMzAxMDEwMjAyDQow MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIzOTAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAzMDEwMjA1MDMwMTAxMDEwNTAxMDEwYTAyMDEwMTJh MDcwMw0KOGUxMDdkNzQzNzAwMWExYjAwMDAwMDM5MzcwMDkyOTM0NTdjODkwNjAxMGEwOTA1MDkw MTAxMDEwMjAyMDEwYTAxMGEwOTAxNDE3YTYyN2E5NDk1OTY0NDk3OTA1ZTVlNWU1ZTVlNWU1ZTVl OTg5OTkxMzI5YTg0OWI5Y2M0NzcNCmQyNjQyZDlmNDFhMGEwMDQwMTAxMGEwOTAxMDkwMTBhMGEw MTAxMDEwMjAxMDEwMzg3Nzg1OTc0NDcwMDE5MDAwMDAwMWEwMDAwMWMxODgwNTIyNTBjMDIwOTA1 MDEwYTA1MDEwMTBhMDYwMzAzMDkwMTAxMDEwMTAxMDEwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMzBhMDMwMTAxMDUwNzA5MDEwNTA3MDEw OTQyMDcwMWUwMTczMzM3MzgwMDAwMzYxYTM3MDAwMDVmODNhMTgyMmIwNQ0KMDEwNTI5MDUwMTAx MDEwMTA5MDkwNDA3MGEwMmEyMjZhMzMxM2M5YTM1MzkxOTAwMDAzODE5MDAwMDFhMDAwMDAwMDAw MDAwMDAwMDAwMzcxYjAwMDAzNzAwMDAwMDAwMDAxYjFhMDAwMDAwYTQ5YmE1MTZhNmE3YTgwOTA5 MDENCjAxMDUyODA1MDMwYjA0MDEyODAxMDEwMjdhMjU5YzNjYTkwMDAwMzczNzAwMDAxYzM5MDAx ODE3ZWMwMTA2MDEwMTAxMDUwOTAxMDEwMTAxMDEwMTBhMDcwMTAxMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTA0MjkwNDAxMDEyODAx MDIwOTAxMDkyZDY3YjUwMDAwMDAwMDFjNDkzODAwMDA5YWFiYWM4ZTAxMDEwMTAxMDEwMTAxMDEw MTA1MmMwY2M2MjQ5NzIwYTQ0ODAwM2EzOA0KMDAwMDAwOTJiMGIxM2M4M2IyYWU2YWIzNmFhMjAy MDIwMjAyMDIwMjAyMDIwNTAxMDEyODAyMDEyOTJkMjMyNjZjODYzMWIxZjg4MzM0MWMxYjQ4MWEw MDM3MWEwMGI1MjA5NzI0NDMwNTAxMDkwMTA0MDMwNDA2MDIwYjI4MDENCjBhYThmMjc0MzYwMDE4 MzcxYTE5MzgzOTE4MzU5NjZiNDEwMTAxMDEwOTA2MDcwMTAxMGIwNTAxMDEyYzAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDI1MTAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNDAxDQowMTAxMDkw MTAxMDEwNTJhZmViN2Q3MTkwMDAwMzkxYzAwMDAzOTZmMTRmOTBiMGEwMzAxMDEwOTBiMmMwMTAx MDk4ZWI2YWU1OWJiNGI1NTM5MDAwMDRhN2ZmNzVhYmQ4Y2JlMmJiZjA2MjgwMzAzMDEwMTAxMDkw NjBiMDEwMQ0KMDEwMTAxMDEwMTAxMDkwMjAyMDEwMTAxMDY4ZTBiMDQwMTA5MGEwNzAzMDEwMTUw YTA2M2MwYzE1Y2I4ODBjMjM3MWIwMDAwNmY4M2MzYzRjNTA3MDEwOTAxMDEwMTAxMDYwNDAxMDFh ZDYxNjVjNzAwMDAwMDAwMDAzODAwMDANCmI1NjdlYzAxMDEwODAxMjkyOTAxMDEyYTBiMDEwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwNzA1 MDEwMjQxOGUyYWFiYTU1NjAwMDAwMDAwMzYwMDE5DQo2NmI3YzgwYjAxMDEwMTAxMDEwMTAxMDEw YTI5NmI3N2IxMWQ1NjFiMDAxYjRiYjBjMzdiOTQyNzA3MDEwMTAxMjkwMTAxNDIwMTAxMDQwMTAx MGEwNTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA0MDMwMTAxMDQwMTAxMDEwMQ0KMDkwNDA5MDEw MjAzMjkwMTAxMDcwMTAxMDEwMTAxMGRiNjZjOWM5ODMzY2IwMDAwMzgxZGJiNzc2YmNjMjgwMTAx MDUyYTBhMDEwMTJhMGJmZGZiYTQwMDAwMWM0YTQ4MzgwMDAwNzRhNjA1MDEwMTAxMDIwMTAxMDk0 MjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw OTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAxMDEwMTA0MDY2MzQ1NGExYzAwMDAzOTE4Mzg5MjM0Yjc3MjAyMDEwNjA3MDcwYTA0MDkwNTYy Njk2NzgwMzMwMDAwDQoxYmM3NjVhZTcyMGQwMTAxMDEwMTAxMDQwMzAxMDQwNTJhMDkwMTAyMDEw MTAxMDEwMjAyMDkwNDAzMDEwMTAxMDEwMTAxMDEwMTAxMDkwMjAzMDQwOTAxMDEwMTA1MDMwMjAx MDIwOTAyMDIwMTA0MDQwMTAyMjkyOTA5MDEwMQ0KMDEwMTAxMDQ0MWJmNGU0ZDNjY2IwMDM3MWMz NWU2NWQ2YjBjMDEwMTAxMDYwMTAxMDcwNTBiODc4YWNlMDAwMDAwNDgzYTAwMDAzNjY1ODIyODAx MDkwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDI0MTAxMDg5N2NlMDAwMDAwMDAxYTAwMDA3ZjhhOTQwMTAxMGEyYTAxMDEwMTA2MDE5 NGE2ZDA0NzAwMDA0YjVlYjJiMzI3MDEwNjJjMDYwMTAxMDIwMTAxMDEwOTA1MDMwMTAxDQowMTAx MDEwMTA2MmEwMTAzMDkwMTAxMDEwMjAxMDkwOTA5MDkwOTA5MDkwOTA5MDIwMzA1MDkwMTA5Mjgw MzAxMDEwMTAxMDMwOTAxMDE0MTAyMDEwMTAzMDEwNTA0MDEwMTBhMDMwMTAxMDQwNTBhMDEwMWFk MjMyMWQxMWMwMA0KMDA1NTYwOWU0MDAxMDMwNDAxMDEwMTA0MDMwMTgxOTY0NjFjMDAxYjM3MWMx OTAwNjZkMzRmMDgwNzAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMmQ0YWYNCjAwMDA0ODAwMDAzYTAwY2IyMTBlMDMwMTAxMDIwNzAxMDEwYjg4 MmViMmE5MzYwMDAwZDc4NWQ4OWYwMTA1MDEwOTBhMDEwMTAxNDIwMTA5MGEwNDA5MDkwMTAxMDMw NzAxMjgyODAxMDQwMTA1MDEwMTA1MDUwMTAxMDUwMjAyDQowMjAyMDIwMjAyMDIwMTA5MDIwMTAx MDUwMzAxMDEwOTBhMGEwMzAxMDEwMTI4MDEwNDUwMDEwMTA3MDEwMTA5MDMwMTAxMDMwNDAxMDEy OTAxMDMwMjAxMDcwMTQyZGE0Yzc0NDkxYTE5MzVlZDUxMDYwMjBiMDIwMTA1MjgwMQ0KMGE2YmUx Y2IwMDFjMDAxOTAwMDAzNTQ1MmQwOTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDcwNDA5MDMwMjAx MDEwNTAxMDYwNDAxMjgyOGM1M2MxODAwMDAxYzAwMzUxY2I1NjQ3YTA1MDEwMTA2MDEwOTAxMmIN CmRhNWEzYjAwMWMzNTY1NzBjYzAxMDEwMzAzMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAxNTAwMTAxMDUwMTAxMDEwNTBiMDEwNTA4MDEwNzAxMDkwMTA3MDEwOTI5MDEwNDAxMGIw NTAyMDcwOTAxMDgwNDAxDQowNzA2MDEwOTA2MDIwMjAyMDIwMjAyMDIwMjAyMDMwNjI5MDEwOTAx MDkwMTA0MDEwNTI5MDEwNDJiMDEwMTBhMGEwMWNjYWUxZjU1MzkxYzNiYjJhNzhlMDIwOTAyMDEw MTA1MGI4ZWM0ZDczYTM4MWMxOTAwMDAxOTNkNGUwOA0KMDEwOTA5MDMwYTAxMDEwYzI4MDEwNjA3 MDEwNTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEw MTAxMDEwYjA3MDEwMTAxMDU0MThjOTkwMDAwMDAzOTFjMDA1NjE3YTIwMTA0MDMwMTA0MGMwMTA1 NjllMTFkMDAwMDU0M2U4ZjA0MDYwOTAxMDEwMTA5MDMwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwNTAxMDQwMTBjMDE0MzQxMmY2YTgxZWIwMTQxMDFhMDAxMDk4ZmU0NDQwMzAx MDQwYjAxMDEwMTAxMDEwNzAxOGUwYzA2MDEwODAxMGIwMTAyMDIwMjAyMDIwMjAyMDIwNDAxDQow MTBhMDYyODBhMGEwMzBhMDEwMTBhMDkwMTBhMDYwMTAxMDEwNzA4MDEyYzRlNWNjYTNhM2E0YjIw MjYwNjBiMDEwMTAzMDQwMTAxZmU2ZTkyMTgwMDM4MWIxYzAwZTI2ODAxMDEwYjAxMDEwYTAxMDEw MzA0MDIwMTAxMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MGEwOQ0KMDMwNjA5MDEwMTA0MDMwOTdiN2YwMDAwMDA0ODAwMDA1ZjEyN2EwMTAxMDQwMTAyMDEw MTJkNTg0ODAwMDBkNTEzOGYwNDAxMDEwOTAxMDEwYTBiMDUwMTAxMDkwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjI5MDENCjAxMjc0ZjRkYjUzNzFjMDAwMDM2ZWU4ZjAzMDEwNDJiN2Mz OTNiMGQwMTAxMDEwMTAxNDEwMTI5NDI2YzAwMDBiOTBiMGIwODkzZDEwMjAyMDIwMjAyMDIwMjAy MDIwYjAxMDYwMTAxMDEwOTAxMGEwNDAxMDQwMTAxMGIwMTAxDQoyYTA1MDEwMTAxMDcwMTAxMDQ4 ZmFmMTgwMDM2NTY1YmI2MDUwMTA3MmMwYjA5MDEyYWNkOGIwMDAwMDAxYjFjMDAzNDY4MDYwNDA2 MDUyODBhMDEwMTAxMDUyYzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjI5MDEwMTAxMDQwMzBhMmE3YzQ3MDAxYjAwNGEzOTAwYzI3Nw0KMmMwMTAxNDEwMTA1 MGJkYzk3ZTIwMDM3ZDU1YjJlNDMwOTAxMDEwMTAxMDQyYTA3MDIwMTAxMDIwMzA1MDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA2MGEwZTM1MDBkNTNiZjUyMWVmMWEwMDQ4M2Y0MjAx MDENCjI5MzQwMDllMDEwMzBjMjkwMTA1MDEwOTAxOWEzOWI1MmEwMTAxODEwMGNiMDIwMjAyMDIw MjAyMDIwMjA2ZDg4OTAxMDJhMDA3MDE0MTAxMDMyOTAzMDEwYjAxMDcwYTA1MDEwMTA3MjgwMTA4 MDkwOTA0MDEwOWQ4YWY4YjM2DQowMDg0Nzc0MzAyMDEwMjA4MDYwNTI4YWE0YjAwMTkwMDU2NGEw MGJhODYwNTAxMDEwMTAzMmEwNjAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDINCjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMTAxMGEwNjAxMmJhZTQ2MDAxYjM2MDA0ODFhNGJkMzg4MDEwNzJiMDEw NDBiZGFiMmE5MDAzNzYwZDk0MjA1MDEwMQ0KMDEyODA4MDMwMTA0MDIwMTAxMDEwMTA5MDIwMTAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTUxOTIwMGNhM2YwMTI4MDIwYWU3NzQw MDM4ZDgyOTAxMDE2NzM2NmQwMTA1MDEwOTAxMDMwNjA3ODcxYTAwZjQNCjAzMDEyOGI3MDA0OTAy MDIwMjAyMDIwMjAyMDI4OTAwMDBkNDAyMDEwMTQxMDMwMjA4MDEwMjAxMGIwNDAxMDEwNDA2MDIw NDI4MDEwMTAxMDMwYjI4MDQwMTAxMDVlMDFlYTkzODU1NTc3YjA3MDEwMTI4MGEwMTg4OTY3ZjAw DQowMDE5MWEwMDQ4YTk0NDg4MDU4ODAxMDEyYjAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwYTAxMDE2YWNlMDAwMDM2MDAzNjNhOTNhNzAxMGIwMTBh MDEwMTg4MjJlMjAwMDAxZGQzMjcwMTAxMDkwMTBiMDgwNzAxMDEwMTAyMDIwMzA3MjgwYjAzMDEw MTA5MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMjdhNDAwOTk0ZjA5MDEwMTA5 MDEwNWNjNjYwMDQ3NjIwMTA5MjQwMDU2Y2MwMTAxMDcwNTAxMGEwMTE1M2EzNTA2MDQwMTlmNTI4 YjZkMDIwMjAyMDIwMjAyMDIwMmU4MDANCjE5MDkwNDAzMDEwMWVhMWQ5YjJjMDMwMjAxMDEwODA2 MDEwNTAzMDEwMTA5MDIwMzAxMDEwMTA2MDcwMTQyMDEwMWQ0YWExZDAwNGFiNTIyZTgwMTA5MDgw MTA1MmE3MmRmMDAwMDE5MDAxYzAwMWQyNjAxMDcyODAxMGEwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwOTAxDQo3MmRmMWEzNzNhMDAwMDAwZTY1MTAxMDEw MTAxMjgwMTRmN2QzNjAwNTUxZTJkMDEwYTlmMDEwMTA0MGIwMTAxMDEwMTA3MDgwYjAxMDEwMTAx MDEwMTAxMGEyOTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMjhhNw0KNDgwMDQwMDEw YTBiMDEwNjA5MGEwMTcyMzgwMDExNDEwMTBiMWQwMGY5MGIyYTBiMmEwMzQyYzY4YjFiNWQyYTAx MDIwOWU5MDAxZjAyMDIwMjAyMDIwMjAyMDJmYTAwYzIyOTA5MDYwYTAxZDMwMDY2MDEwMTA1MDUw NzAxMjgNCjAxMDEwYjBhMDcwMTA0MDIwNTI4MDUwMTAxMjkwMTAxMjkwYjAxMDEwZjY1MWIzNWE5 YzE5ZjAxMDQwMTAxNDI4OGI5M2MwMDAwMTkzNzAwMDA4M2M1MDIyYTAxMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMmI1ZDM4MDAzOTAwMDAzOTMyODkwNTA0 MDEyODA4MDE2MmYyDQo5MjAwYmFmMDJkMDEwOTA1MDUwMTAyOGUwMTAxMDYwMTAxMjkwNTAxMDEw NjA5MDEwMTAxMGEwYTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxZTkwMDlh MDE0MTAxMDEwNjAxMDQwNzAxMGJhZThkMDYwMQ0KMDMwNTdkMDAxODAwMDA0YTAwMDAzNzAwMDA1 NjlmMDEwMjA4MDEzODM4YTMwMjAyMDIwMjAyMDIwMjAyNWQ0OGY1MGEwMTBhMDMwMTY2MTgxMzAx MmIwMjAxMDEyYTVhMzJjMWM4MDIwMTAxMDEwMTAxMDEwMTAxMDEwMjA3MDYNCjAxMDEyOTA3MDEw YTYzOWUzMzAwNDk5MDBkMDMyOTAxMDEwMTAzMTBkZjAwMTkzNzE5MDAxYmMxMGMwYTAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwNzAxMDQyOTAxMDEwYTA5MDQwMzI5MDEwMTQxMDhmOTVmMDAwMDM1MDAzNzZkYjYw OTAxMDkwMjA3MDVjNjVkMTkxYjg0OTY4ZTAxMDUwMTAxMDMwMTAxMGIwMTAxMDEwMTJhDQowMTAx MDMwNjAxMDYyYTAxMjgwMTJhMDkwMTBjZjhiNzAxMDYwMTI4MDEwMTAyMDIwMjAyMDIwMjAyMDIw N2JhMDA1OTA5MDEwNDAyMDIwMTAxMDEwNzAxMDYwMTA1MDIwYjA2MDgwMDE5ODAzMjdlZDE4MGE1 MDAwMDgzMDEwMQ0KMDYwYTA2NDcxYmQ2MDEwNTAxMDcwMzAxMjkwMTc2MDBlMTBiMDEwMTA1Mjcz ODMzZjAwOTAyMDEwMjQyYjEzNzAwNzRlYjAxMjgwMTA0MDE0MTAxMDEwMjAxMDEwMjAyMDIwMjAy MDIwMjAyMDEwNjQxYmQxZDAwMzc4NWFkMGINCjAxMDUwNTAxNDJjNWIxNWYwMDM4MDAwMDQ3NGQw YTAxMDEwNjAxMGIwMTAxMDEwNzBiMDIwMTAyMDMwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjA5MjkNCjAzMDEwMTA2MDUwMTAxMDEwMTJiNDI5NGYxMDAwMDRiMDAwMDg0 YjYwMTAxMDEwYTBhMDFiZmNkMTgwMGQ3OTc1MDAxMDEwMTJhMDcwOTA2MGEwMTA0MDEwMjBiMDUw MTJhMGQwMTA0MDEwMTAxMDEyYTA1MDIwMThlMDFhNTM2DQowNjk2ZDUwYzAxMDYwMjAyMDIwMjAy MDIwMjAyMDFiNTNhYjMwMTAzMDcwMTAxMDQwNTAxMDEwMTJhMmIwNDAxMDEwMTA4OTgxODk2MDEw MTA0MDU4OTM3M2JhMjA0MDYwMTAxYzgwMDM4MTAwMTA0MDEwMTA3MDEwMTA4ZTIwMA0KOGEyYzAx MDMwNDhmMzgwMDAxMDYwMTAxMDgxNTNhNGE2ZjQzMjkwNjAxMDMwMTI5MDEwMTJiMDEwMTA1MDIw MjAyMDIwMjAyMDIwMjA0MDQwMTAxZThhNjQ2MzkzNTg1NDAwNTAxMDEwOTI4MDlhMjhiM2E0OTM3 MDAzYWYzZjQNCjAxMDkyODAxMDQwNjI4MDEwMTAxMDQwOTAyMDUwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwYTAxMDE0MTg4MDEwMTJhMGIwNTBiMmMxNTAwMzgxOTE5MDAN CjkyOGMyYTAxNDEyOTAxMDRhY2IwMDAwMDk5YzQwYzAxMDIwODQyMjkwMzAxMDEwMTA4MDEwNzAx MDEwMTAxMDQ1Y2U2MjYyODBhMDEyOTI4MDEwMTAxNDM0ZDBkNzJmZjg3MDA1MzhlMDgwMTAyMDIw MjAyMDIwMjAyMDIwMWE5DQoxYTZjMDkwMTAxMDIwNTAyMDEwMTBhMDYwMTAxMDkwMTAyMDcwMWY0 MDBmMTJhMDEwMTAxM2UwMDU0MDQwMTI4MDEwMTYxMWI4YmJkNTA3YTJiMDE4ODAxMDEwNDVmM2Ey ZjBhMDEwMzA3Y2QwMGNlOGQwMTA2MDdmMTM3MDA1Zg0KODgwNTAxMDEwMTAxMDkwYTAxMDllOTQ0 ZmQwMzAyMDIwMjAyMDIwMjAyMDIwMTA5MDYwNjAxMDFkNDk1ZmYwMDAwZjhkODA0MDEwMjBiMDEw MWFlMDA0ODAwMWMwMGE5MjAwYzA1MmIwMTAxMDEwNzg4MDUwMTAxMDEwMTAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDMwYjBhMDEwMTAzMDYwMTAxMGRmMDM0MDA2ZjAw MDAzNzMxNzEwMTA0MDQwMTAxZWFmNzAwMDBiMDExN2EwMjAxMGENCjJhMDIwMTAxMDkwNDAyMDEy YTAxMGIwMzAxMDEwYTQyZDEwMGU5MDEwNDBiMDEwNjAxMDIwODZhMzk1NjkwNTk4M2QzNGYwMTAx MDYwMjAyMDIwMjAyMDIwMjAyMDY0YjAwYWEwNDAzMDEwNjAxMDMwNTAxMDEwYTAxMmMyYTA1DQow MzAzMDFlYjAwNTU2MzAxNDE0MTMzNTY2ODAxMDEwNzAyMDE4YzQ4MDAxOTM3Mzk0NzliZWVjZmRl ZjQzNjFiYjk0MjAxMDEwMzc0M2E1ODAxMDEwY2UxMTgwMGUyMDQ3YTAxMDQwMTlmMDEwNTAxMjk3 MTAwMTliOTAyMDIwMg0KMDIwMjAyMDIwMjAyMmMwNDA0MDEwMTAxMDEyOTA5YWUxZDAwMDBlZmE2 MDEwOTAxNDEwMThkZWQxODFiMDAwMDAwNTZkMjAxMDcwMTlmMDEwMTAxMDMwMTAxMGEwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDQyODA0MDEwMTA1MDNmZWY3MTkw MDE4MDAwMDY1NDAwNDAxOGUwMTAxMGVlNjAwNGEzZGM4MDYwNDAxMDMwNjAxMDEwNDA2MDEwMTQy MDMwMzBhMDEwMzAxMDMwNzA0MDENCjhjMDBkNzI3MDEwYTAzMDQwMTAxMDEwNDBmYTY5MDg0YjFi MmFmNGMwMTQyMDIwMjAyMDIwMjAyMDIwMjA2OTgxY2Y1MDE0MTAxMDMwMTAxMDIwMTA3MDcwMTAx MDEwMTA0MDEwMTJiZjUxY2ExMDEwNmZhNTZjMjA1NDEwYjAxDQowMTA0NzMwMGMyYmI1NTFjMTgw MDAwMzMwMDE4NGExYWRkMDkwOTAxNTA0YTAwMGUwMmJlNTcwMDAwN2U0MWJmMDEwMTBjMDEwMTJh MDEwNTAxY2YxYTM4NDIwNzAyMDIwMjAyMDIwMjAyMDIwMTAxMGEwMTJhODgwMTA2MDIwMQ0KMDk5 NDE3MWMxYjkxNDAwODAxMDEwMTAxNjM1ZTAwNGEzODFjMWI4MGE4NDEwMTAxMDEwMjA5MDQwNDA5 MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDE4ZQ0KMDEwMTQzMDE1MDIx MzYwMDAwMzgwMGMyZDg1MDAxMmIwMjAxMGQxNzhiMTlkMDJkMDcwMTAxNDEwNDA1MDEwOTAxMDEw NDAxMDEwOTAxMGEwMTA5MDQwMTAyMDUwMTAzMDg5MjAwZmIwMTAxMGEwMTAxMDE0MTAxMGRkZWM3 MTINCmRiMTBjNzU2MmMwNTAyMDIwMjAyMDIwMjAyMDIwMWU5MDA0YjI5MDMwMTA5MDEwMTA0MDEw MzA5MmRhOGQ2MDEwMTA0MDEwMTgyMDBkNTBjMDFkMTAwOWUwNDAxMDEwMTA0MDU2ZDAwNWQwNTA1 YTBlNzYxZGVjMWIwNDcxODQ3DQowYTAxMDIwMzBmMDA0ODIxM2QxYjFhNGE4NTA4MDEwNTA1MDEw OTAxMDQwMTAxMGEwNmY3MDBiNzAxMDkwMjAyMDIwMjAyMDIwMjAyMDYwNTBiMDEwMTBiMDEyODA3 MDQwMTAxMDY4ZjE1MDA0YjRjYTAwYjAxMDE0MTAxNmIxOA0KMDA0YTAwMDA3ZmJiMjcwODAxMDEw MjA0MDkwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjhlMDEwYTA0MDFm OTQ3MWIzNjM5MWIzNzdkMmEwMzAxMGIwMQ0KMGI3ODQ3MDA5Mzk3MmIwMTAyMDUwMTAxMDUwMTAx MjkwMzAxMDUwYjA0MGIxMWRhMDEyODA0MDEwOTAxMDcwYjAxMjEzOWU2MDUwNjAxMDUwODAxMDEw M2NmMDBlMTY5MTlkNDc5MGIyYzAxMDIwMjAyMDIwMjAyMDIwMjAxZmENCjAwMDBlMzAxMDEwNDAx MDc5ZjAxMDEwM2YxMzc2MDJjMDEwMTA4MDEyOGI1MDBhMmZjMzkwMDI5NTAwMTAxMDMwMTAxODAw MGMwMGIwOTAyMDEwNDAxMDIwOGFhMDA5OTA2MDEwNTA0NjcxYzU2MDAzNjU1MzE2YjAyMDE0MjAx DQowOTAxMjgyOTAxMDMwNzAxZjQ1NjAwZDQwYjAxMDIwMjAyMDIwMjAyMDIwMjAxMDEwNTA0MDQy YTAyMDEwMTAxMDUyYTAxMDEyNzZjODQxYjU1MjZhMDA2MDEwYzA1NGZlOTFiMzgwMDAwMDA3Zjc4 MDEwMTBiMDEwMTQxMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTUw MDE0MjIxMDAzOTAwMDAwMGE0ODkwMTBiMDEwNzAxYjk3NDM3MDBlNWFkMDEwMTJiMDEwMTJhMDEw MzBhMDEwOQ0KMDEwMjAxMGE2ODY2MDA4MzA5MDUwMTA5NDIwMTA3MDEwMWY5MWE0OWU3MDEwOTAx MDEwMTA0MDFkOGI3MjkwZTQ4ODUwOTBhMDEwMzAyMDIwMjAyMDIwMjAyMDIwYTA1YmMxYWZmNjIw MTAxMDYwMTAxMDE3OTk0NTYwMDk3MDENCjJhMDEwMTBhMDExMzM5OWU1OTRhYzkwYjAxMGMwMTBh MDEyYzAwMDAwZTA1MDUwOTA5MDUwNDA2MDEzYzQ4NWEwMTA2MDEwMTVlMDA3ZGZkNmUwMDEzMGEw MjBhMDEwNTAxMmMwMTA5MDUwMzA1MDE1YTAwOTEwMTAxMDUwMjAyDQowMjAyMDIwMjAyMDIwNzAx MDkwNzAxMDEyOTAzMDcwMTAxMDIwNDAyMDEwMTJiZTQzODAwZDdiZTBhMDEwMTI4MDFmY2Q3MDAz ODE4MDAxODE3YzYwMTA1NDIwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMDAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMTAyMGIwNjAxMDEw OTAxMDMwOTcxYTkwMDM4MWMwMGE5OTUwMTBiMDYwMTA1Mjk5MDFjMDA1YmZkMGEwMjA5MDkwMzA2 MDEwMzA1MDE0MjAyMDUwMTAxYmRhNDAwMDBkNTdkMmEwOTA5MDEwMTA2MDMwMg0KMDEyYTRhMDBk ZTA5MDEwMzJhMDEwNDAxMDkwNjAxMjhjMDBmMDEyODAxMDMwMjAyMDIwMjAyMDIwMjAyMDkwYjBk MDAzYWI4MGMwOTAxMDQwMTAxMjQ5OTAwNmY0MjA5MDEwNDAxMDEwYzg3MDA5YmI1MWNjNTBhMDEw MTAxMDENCjAxMGEwMDAwZGMwMzAyMjkwMTAyMGEwNjAxZGIwMDhhMDQwYTA3MDczNTAwZDkyOTA4 ZDUxYTgxMDEwNjAyMDEwODI4MDMwMTAxMGIwNTI4NDkxOGMwMGIwMTAzMDQwMTAxMDEyYTBiMDEw YjAxMDEwNDA4MDEwNjI5MDEwMTBiDQowMTAxMDEwMTA5MjgwMTA5NGVlMTAwMDA1MjJjMDQwNTAx MjgwMWY5ZmYwMDNhMDAwMDdmODEwMzA3MDEwMTAxMDkwOTAxMDEwMjAxMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMGIwMTAx MDkwMTAxMDcwNjQ0DQowMDM4MDA0YTAwMTY4ZTA1OGUwMTI4MDk2OTAwMDA1M2E3MDQwMTBiMDQw MTA5MDEwYjA0MDEyNzA3MDEwMjJhYWU0NzAwMTk4NGExMDMwMTQxNDEwMTAxNTAwMTA5MDEwYjA1 YjIzNzc1MDEwYjAxMDEwMTAxMDIwYTAxMDQwMQ0KOGUwMTAxMjkwMTAxMDIwMjAyMDIwMjAyMDIw MjA2MDE3OTdiMzkwMDM2NTgyZWE4ZjBkZjkyMDA5YWM4MDcwMjAyMDcwMzAxMDk4ZTVlMzYwMGU2 MDkwMTI4MDYyODA2MmM2OTAwNGE3YTQxMDEwYjQyMDIwMTAxMDEzNzAwYzANCjAxMDEwMTk1MDBj YjRmMDcwNzkxMDBhMTAyMDEwNjAyMDEwMTAxMDcwNTAxMDEzZjFjMDBjNjAxMDkwMTAxNDIwNjAy MDEwMjAxMDEwNTAxMDEwMTA1MGEwMTA2MDEwMjQyMGIwNDA3MDEwMTI4MjkwMTAxMjY0NjAwM2E4 MjA0DQowOTAxNDEwMWFkMTQwMDU2MDA5MjAwZDMwMTA1MjkwMTAxMDMwMTA0MDcwMTAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw YTAxMDMwODA3MDkwYjJhNjUwMDU2MDAwMDMzNDQwNDAxMDEwMTA1ZmUzMjAwYTk5Njg5DQowMTAx MDEwMTAxMjgwMTAzMDkwYjAxMDEwMWJlYjdmZjAwMzkxZjY5NzEwMTA2MDcwMTAxMDEyOTAxMDMw NDAxMDgwMWZlMzczN2JlMjgwMTA1NDIwMjA1MDYwMTA2MDEwOTAxMDEyYTA3MDIwMjAyMDIwMjAy MDIwMjAyMDEyYg0KMDEwMWE4OTgwMDQ4MzkxYjM5Mzk0OTU3ZDgwMTAxMDEwMTA5MDIwMTAxMDE0 YzlhYjA4NjAxMDEwMTAzMDEwMTAxZTM1NTY2MDMwMTI4MDEwMTAxNDE4ODA1MDA0YTRlMDU3YTAx ZTEwMDdlMDEwMTAxNTIxYTNjMDEwNjAxMjkNCjQyMjkwMzAxMDcwMjAxNTcwMGY3MDEwMTA2MDEw MTA1MDNhODRmMDIwMTA3MDEwMTAzOWYwOTAxZmUzZmJmMDEwMTAxMDEyODA5MDIwMTAxMDY0MjAx MmNmYjFhMDA3ZTcyMDYwMTAxMDgwMWEzMzMwMDAwMWEwMGIxNjIwMTAxDQowMjAzMDcwMTAxMDkw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDEwODAxMDEyODAxMGUxZDAwMDAwMDU2Yzc0ZjA0MDEwOTBiNzkyMDMzMDBlZWM2MDEw MTAxODgwNTAxMDEwMTAxMDcwMTA5MmJlNzE3MDAwMDAwDQo5YjEwNzkwMTAxMjgwNjAxMDcwYzBh MDcwOTBhMGEwMjA0MDEwMjNiMzM1YzAxMDEwMTAxMDEwMTAxMDQwMTA1MDcyYTA2MDEwMTAzMDIw MjAyMDIwMjAyMDIwMjAzMDEwMTc5MDEwMTk0ODUxMzljNGNhYmRkMDEwYTAxMDEwMQ0KMDEwMTAx MDkwNDA0MDEwYTAyMDEwOTA3MDEyOTA0MDMwOTJlY2Q0YzI4MDEwMTAxMDYwNTA5MDFiZjAwMDBl ODAxMDIwMTk4MDA5YzA3MjgwMjZjNTZlNjAxMDEwMzAyMDEwMTAxMDEwMTAxYzY1NjFhYTcyODAx MDkwMzI4MDENCjlmYmM0YTMyNmEwMTA2MDQwMjAxMDEwMTFkMWM5ZTQxMDEwMTAxMDcwMTBiNDIw MTAxMDEwNDAxMGI0M2VlNGEwMGUxNzkyOTAxMDMwMWM2YTQwMDM5MDAwMGVmMmYwNTAxMjkwMTAy YTAwMTAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIN CjAyMDIwMjAyMDIwMjA2MDkwMTAxMmJhYmE5MDAwMDRiMDBkZjAxNDIyYTAxMDEwZmNiMWI0NjEx MDkwMTA4MDEwMTAxMDEwNzA4MDE0MjAyMDEwMTAxN2E0YjM5ZDdmZDI5MDEwMTAxMDIwNTAxMDEy ODAxNzkwMTAxMDMwMTJhDQowMTAxMDE4YTQ5YzIyODA5MDEwNTQyMjgwMjAxMDEwNDAxMDEwNzAx MDIwNTAyMDIwMjAyMDIwMjAyMDIwMTBhOGUwMTAxMDEwYjAxMDEyOTA5MDEyYTA5MDEyYzAyMGEw YTAxMDEwOTBhMGEwNTA0MjgwMTI4NDIwMTAxMDEwMQ0KMDEwMTBhMGMwMTAxMDQwNzAxMDQwMTA5 ZGUwMGE5OGQwMTA3YzgzNjAwYjkwMTAxMGI0ZTAwMWIwZDAxMDEwMzAzMDcwNzA0MDcwMzlkMWEz NDA5MmIwMTAxMDEwMTAxMjdiODAwMWEzM2ZmZTA3MTAxMGEwOGNmMWIwMDZhMDENCjAxMDYwNDBi MDEwMzAxMjkwODAxMDEwOTBhMDEwOTgyNTQzOTU1NjEwMTBhMmEwMTQxMjAwMDM4MDAwMDU2OWQw ODAxMjgwMTAxNDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDEwNDAyODdlZTAwMDA1NjM5MDANCmZlMDEwNzAxMDQ1MDVhMTgw MGY2NTAwMTA5NDIwMTAxMDMwNDAxMDMwYjA1MDEwMTBhNDIwYTBiZGYzYTM0ODgwMTJiMDgwMjA5 MDEwNTA4MDFkZDAzMDEwMTA3MDEyODAxMDIwYWRkMDAxYWI5MmEwNDAxMDEwMTQyMDEwYTA2DQow MTAxMGIwNDA0MDUwMjAyMDIwMjAyMDIwMjAyMmMwMzAxMDYwMTBiMDEyODI4MDEwMTAxMDEwMjI4 MDEwMTA5MDQwMjAxMDEwMTAxMDEwMTI4MDMwMTA0MDMwOTA2MGEyODAxMDIwMTAyMmMwOTAxMDE1 MDI4MDEwNzAxMDgwMw0KMGMwMTQwY2ExYjJiMDYwMTA5MGFiODFiN2IwMTAzMDMyODAxMDEwYjAy MDE5OTRhZGIwYjAxMDEwNTAxMDE1MDAxMDFiZTE0MzczNzQ5ZGMwMTA5MGEzYjAwMTYwMTAxMDEw MTAxMDcwMTAyMGEwMTAxMjkyOTAxMDEwNTAxMDUNCjBhZmIwMDU2MzA3OTAxMmEwMTA3YTcxYzky MWExODAwZWVlODAxMDkwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA2MDE3OGI1MzczNjAwMzc5YTUwMDEwOTAyMDFmZGQ3 NGE1Zjg3MDEwMTA2MDEwMTBhMDINCjAxMDEwNTAxMDEwMTA3MmEwMTAxMDMwMTYzMTgzOWQyMDEw MTAxMGIwMTBhMDE3YWU1MDA2MjAxOWYwMTAxMDkwMTA5MDcwMWQ3Mzk0YzA0MDEwMTJjNDBmOTI4 MDEwMTBiMDUwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMTAxDQoyYzAzMDkwMTAxMDEwMTQyMjgw OTI4MDIwMTQyMDEwMTAxMDMwNzBhMDMwOTI4MDEwMTA5MDEwMTAxMDYwMTAxMDEwMTA4MDEwYTAx MDcwYTAxMDIwMTAxMjgwMTg4MDEwMTQxMGEwMWEwMDEwYjAxMGIwNGYyMWEzNjUzNmFjYw0KY2My OTAxMDcwMTBkMDA0YmY0MmMwMTAzMDYwMTA3MDEwMTUwMDQwMTBkOWVkMDAxNzkwMTRjMWI5MmQ0 MDkyOTQxMDMwMTAyMDIwMTAxMDEwMTAxMDEwOTBhMDUwNzAxMDUwNTgxZDUzODkxNzEyYTA0MDEw MjQzYTUwMDAwNWYNCjFiMzQ3ODAyMDEwNzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAw MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDI0MjczMzkwMDNhMDA1NTkwNDEwMjBiMDMw NTIzYTkwMDE2NDIwMTA0MDEwMTQxMDEwMTA1MDkwMTA2MDkwMTA3MDkwMTAxMDUwMzQyMDEyMTAw YTQNCjdhODgwMTAyMDE3OTNlMzYwMDFiYTEwMjAxMDEwYjAxMDEwMTAxMDRmNjAwYzc4ODJkNzY2 NjAwMWMwZDA3MDEwNTAxMDEyYTBhMDkwMjAyMDIwMjAyMDIwMjAyMDcwMTAxMDUwMTAzMDEwYjA1 MDEwMTAxMDkwMTAxMDkwYjAxDQowMTI4YTA0ZjBkZWJiZmNjMGQwNzAxMDgwMTAxMDE0MjA0MDEw MTAxMDgwMTAxMDUwNzAxMGEwYTAxMDEwMTI4MDEwMTA3MDEwMTAxMDMwMTA3MDEyYTkwMzUwMGMz NGM0YWM3NGQ0ZjJiNGMwMGZmMDcwMTA0MDkwMTAxMDEwNQ0KMDUwMTA1MDYwMTA2MDkwYzAxNzFj YjAwZjYwMTAxMDEwMTAxMDcwMjA5MDI0MjA1MDkwNTBhMDEwMTAxMDEwYTA2MDEwMWJmYWYwMDRh MjMwYTA1MDMwMWU3ZjA0ODAwMzk0ODFhM2UyOTAxMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDAwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMg0KMDMwMTAxMDEyODBiODMwMDM3MDAzNTM1ZWEwMTAx MDEwYTA5MTQwMDNhYzQwNTBhMDkwMTBiMDcwMTA4MDUwMTA2MDE3MTE3MDEwMTAxMjgwMzAxMDky YzAxY2MwMDRhNDQwYTAzOTQ1MjU2MzYwMGQwNjMyODAyMDEwYTI4MDENCjA1MjkwMTAxZTg5MjFh YjU1NjAwMWM0NzU4ZDQwMTA2MDYwMTAxMDEwMjAxMDEwYTA0MDEwMTA5MDcwMjAxODgwMTA0MDEw MTdhMDdjNGM0Nzg4NjMxYTVmN2Y4ZjdmM2YxZWY0ODAwMDAzOTM3MDAzNjU0ZjNkMTdlOWJmMWU2 DQoxNjk3OTVjMGQ4MGIyYzAxMDIwMTAxMDUwMTA3MGIwNDAyMDIwMTAxMDEwMTAxMDEwMzAxMDEw MTcxZDg0M2FiMzkwMDFhMDA5M2Q3MDBjMDAxMDgwMTAxMDEwYTAxMGIwOTAxMDIwMTAxMDEwNDA3 MDE3NTFjOTEyNzAxMDEwNA0KMDkwYTA0MDEwMTQyOThmODZjMDEwMTAxMmEwMTAxMDMwYTAxMDEw MThlNmMzNjE5ZGYwMTA5MDEyYTAxYWM1NTAwNDgxYjAwZjEyODAxMDEwNDAyMDEwNTA5MDEwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDYwMTJhNDEwYjhlZjgwMDU1MDAwMDdlOGUw MTI5MDkwNA0KNzEzYjRhYTQ4NzAxMDEwMTAyMDQwMzAxMDEwMTAxMjkwMWI2MDA1ZmI3MDkyODAx MDEwYTAxMDEwMTA2ODUwMGNhMjNiYzAwMDAxOWIyNGYwMTI4MDEwMTBjMDEwMTUwMDEwMmQ0YzA3 NTAwMTkxOTM1YWZlYzUwMmIwMTAxMDENCjAxMDMwNzA3MGEwYTAzMDEwMTQyMjkwMTAxMDQ0MjI1 OGMzZWIxNzUxOTAwMWIwMDAwMDAwMDAwMDAwMDFiMDAwMDAwMzkzODM3MDAzODFjMDAwMDAwMDAx YTM3MWMwMDE5YzI1NTAwMDAwMDE4MzI5YjIyOGNkYTAxMDEwMTAxDQowMTA5MDYwYjA1MDEwNTAx MDEwNzI4MGEwMTAxMmMwMTJhNjliNDE5MzkwMDM2NDZhMzAxMDEwMzAxMGEwMTAxMDEwOTA3MDQw NDAxMDEwMTNmMTkxOTQ0MDEwMTAzMDEwMjAxMDE0MTAxNzAwMDAwMGYyNzAxMDEwMTAxMjgwNw0K MDEwNzQxMDEwMTA5ODdmNzQ5NDhlODA2MDEyYTA2Y2MxNzE5MDAzNjNhZjM4ZTJiMDEwMTAxMDEy OTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNTBhMDkwMTAxNmI2ZjAwMWEwMGE5 YWUwMTQyMDEwYTAxOWQxYTFhMzAyYjAxMmEyODAxMDEwYTAyMDM0MjAxMDE5Zg0KMDEwMTU4MDBm ZmQ0MDEwMTAxMDkwMTAxMDYwMTQzMzUwMDM5MzY4YmFmYzUwMTI4MjgwMTAzMDMwMTAxMDE1MGIz ODAwMDM2MDAzNmYzMGYwMTAxMGIwNDAxMDEwMTAxMDEyODA3MDEwMTAxMDEwMTA3YTg5NzViNWU0 ODVmMzgNCjAwMDAzNzE5MWMxYzAwMWMxYTAwYTlmN2I0NzVmMTc1MzIxZjk2Zjk2NDg2YTNhNmQy ZTliNGYxZDFiYzliNTQxODAwMDAzOTM2MDAwMDNhMDAxOTM3MDA1NTE5ZTZiMWY2NGUwNTAxMDIw ODA3MDEwMTAxMDEwMTAxMDEwMTI5DQowODJjMDEwMmY5ZjcwMDE5MDA0N2UxNjkwMTAxMDQwMTAx MDkwMTAxMDIwMTA0MmNhNDM5YjAwMTAxMDIwMTA5MDEwMTAxMjk0MmE0MDBiNzA2MDEwMTA1Nzkw MTAxMDE0MTAxMDE0MjAxMDEwMThlMjAxOTNhOTcwMzAxMDEyYQ0KMDI5ZTAwMzc1NjAwN2Y3MjAx MDkwMzA0MDEwNzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwNzAxMDI2MWNiMzYw MDAwMzVlYTJiMDEwNDI4MDdmMTFjY2E3YjAxMDEyOTAxMDIwOTAxMDUwMTAxMGEwMTA3MDEwMTAx MjdjZTFiNmQwOTAxMGIwMTBiMDUwMzAzMDFlOQ0KMDA0NzE0YmUwMTAxMGIwNDAxMDEwOTAyMDIw ODI5ZmRjNzAwNDczYzI2YmYwMTAxMDEwNTA0MDEwMTJhMGEwNTA5MDEwMTAzOGRlYzkwZjE0ODAw MWIzNzFhMDAwMDFjMDAzNWM3NWU1OTIyYTg3MTBkYWQ0ZjA1MDEwMzAxMDkNCjBhMDQwMTAxMDQy OTI5MDEwMTBiMDgwMTAxMDEwOTA5NDJiZjYyZTgwZjk2ZWRiYzU0MDAwMDM1MDAzNzAwMDAxYzM5 M2FiY2JkNDAyODA3MDUwYTA2MDYwNjA2MDQwMjAxMDEwNDA1MjgwMzUwYTE1NDFiOGIwMDRkMjgw MjAxDQoyOTAyMDEwMTA0MDMwMWFiMWE5MmM4MDEwMTJhMDEyOTAyMDkwNTAxYWIwMDAwNDAwNDAx MmEwMTAxMGMwNjI5MDEyODAxMDEwYzAxMDIwMTAxNjk1NjFjODNiZjA0MDEwYjAzZGEwMDAwNTUw MDQ5ZDkwMTA3MGIyODAxMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA1DQoyYWI2 M2E5MjAwNTZkNTI2MDkwMzAxMDliOTQ3MDBjOWI5MDgwMTI5MDEwMTAxMmEyYTA2MDQwMTAxMDQw NTAxMGIwYTQyNzgwMDE4YjMwOTA1MDEwOTA5MDEwMjI4ZThiYTAwYTIwMzAxN2EwMTAxMDEwOTAy MDhlMGIyMDEwMQ0KMTM3YjQyNzkwMTA5MDEwNTA1MDIwNTAxMDEwMTAxMDIwN2RkZDNmODRiNTUx OTAwMWM5MjFjMWE3NDY3ZmIyZmVjNDIwYTQxMDEwMjA4MDIwMTAxMDIwMTAxMDEwYTA0MDkwMzA0 MDMwMTAxMDEwMTAxMDEwMTAyMDMwYTAxMDkNCjBiMmEwMjAxMDEyODAxOWYwMWU3NjM3MmI3YzNj YWNiMTgzODM3MDAwMDM3Y2JkZmY5ZWIwOTAxMDEwMTAyMDU4ODA1MDEwOTAxMDEwMTA2MDFhMjU4 NzQ3MTAxMDEwMTA4MDEwMTQyMDQwMWViZmYxYTViMDE4ODAxMDEwMTBiDQowMTA0MDE3MTNhMDA3 NzI5MDEwMTQyMDE3OTMyOTA4ZTAxMDEwYTI5MDEwYTA5MDEwODAxMGRlZjFhZTJhNzAxMGEwMTI5 MjQ1NTAwNDgwMDhiZjQwMTA0MDEwMzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyN2Ew MTcwNDkzOTAwNDhiYzdhMGMwMTQyNDI1ZDFiNDkyMmEwDQowMTAxZGQwMTA3MDYwNjAxMDEwMTAx MmEwNTA1MDE3YTA3MDEwMTAyMTUwMGQ3ZWIwMTA3MDEwMTA1MDEwMTAxMTcwMDU0MDEwNTAxMDIw YjAxMDhkM2UyMDAxYzUxMDEwMTAxMDEyODAxMDEyYzA5MDEwMTA0MDEyYTYzZTNiYg0KZDUxOTE5 MDAwMDAwMDA0NzE0YjNhZDBiMDIwMTA3MDEyODAzMDkwYTAxMDEwMTAyMDMwMTAxMDIwNTA1MDEw MTAxMDkwOTAyMDIwMjAxMDcwYjA5MDEwMzA0MDEwMjAyMDEwMTAxMDEwMTAxMDEwMTAyMDEwMTA1 MDkwMTAxMjkNCjQwZGUxNDg0MWMwMDU1MzcwMDAwNmY2NWEzZWMwNTAxMDEwYTAxMDEwMTA4MDEw NDA3MDEwMTBjMDEwYzA1MDEwYTAxMDUwODAxMDE1ODAwODRlODA3MDE0MTAxMjkwMTAxMDIwMTVj MDA3ZmEwMDEwNTAxMDEwMWZiMDAwMDgzDQoyZDA3MDEwMTUwMDEwMTAyMDEwODAxMDljMzM4OTJm MjA2MDEwMWEwMjhlMjAwMDAxYjNhZDIwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIN CjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAxMjAwMDE5MDAwMDlhMjcyOTAxMDkwMTNlMDAzNDExMDUwNTA2MDQwMTAxMDEwNjA0MDE4 N2RkMDEwMzAxMDEwMTAxDQowOTJjMjgwNWJlMzkwMGI3MDgwYTAyMDEyODAzMGIwMTQzMDAxYjZj NzkwMTA3MGJmMGE0MTkwMDhiZTQwMzA0MGEyYzAxMDEwMzAzMDEwNTBiMDI0Zjk3NWUwMDE5MDAw MDAwMTllMjRjMTE5ZjA2MDIwYTA0MDEwMTAxMDEwMQ0KMDkwOTAxMDEwMTBiMDEwNDA2MDUwMTAx MDEwMjAxMDkwNTA0MDIwMTAyMDQwMTAxMDIwMTAxMDEwMTAxMDIwOTAxMDEwOTA3MDUwMjI4MDEw MzAxMDEwODAxMDIwMTAxMDIwMTAxMGFmZDI2ZjNhNDU1MWIwMDAwMWExOWNlNzcNCjlmMGIwNzAx MDUwMTQxMDEwNjAxMDEwMTA4MDEwYjAxMDkwMTA1MDEwMWFjMzgwMGY5MDMwMTAxMDEwNDBhMDEw MTAzMTE1NWMyYzAwNTAxMjkwMTBiZGUwMDNhMzkwMDg0YzQ4ZTA2MDEwMTAxMDEwMTAxMDEwMTAx Nzg2ZjE4DQoxZjAxMmEwMTJhMDdmNTAwMDBjMjE5ZTkyYTBiMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIyMDAwNDgwMDAwYjQ4ODAyMDEyYTAxMjEwMDkzNTAwMzAxMDEwMTBiMDkwYzAx MDEwNDQzNDY5YjdhMDEwOTA1MDMwMTJhMDEwMTQxMDE3NzFhMDBlYzAxOGUwMTAxMDMwMTAxDQow NWVlMDA4MDAxZmQ0ZGUyMDAxYWI4ZTM0MjAxMDQwYTAxMDIwMTI5MDEwMzAzMjc5NWU2NDgxYTAw MDAxYTZmMWVlNTQwMGIwMTAyMDQwMTAxMDEwOTAxMDEwYTJhMDMwMTA5MGEwMjAxMDEwNjAxMDEw MjA1MDMwMjAyMDUwMg0KMDEwMTAxMDIwMjAxMDcwNDA5MDMwMzA5MDMwNDA5MDEwMTAyMDkwOTAy MDEwMTJhMDEwNTAzMDEyODAxMDYwMTAxMDUwYTAxMDEwNzAxMGI4NzQ0MWU0NzM3MWEwMDAwY2E1 ZWRlMDQ0MjAxMDEwYjAxMDYwOTA5MDEwNzAyMDENCjBhMDEwNTAxMmNlOTFjMWQwYjAxMjgwNzAx MDkwMTA5MDEwYjc1MDBkZjA0MDEyOTAxMDEwODQ5MDBhNTk0NTcwMDM2NWRiZjAxMDYwMzAxMDMw MTI5MDEwYTAxYTBiODAwNGMwYTAxMDEwNjBkYjEwMDAwMWEwMDE2MDkwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAw MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwOTA5MDkwMjAyMDEwMTAx MjkwNjAxMmMyODAxMDgxNjAwNGENCjAwMDAzZTA4MDEyODAxYmU5OTAwOThiZjA0MDEwMTAxMjkw MTAxMDUwMTI5MDcwMTQ5MDA2NzA4MDEwMTAxMDUwMTAxMDcwMTAxNDJmMTAwNTQ5ZjJhMDEwMTA1 MGEwMjAxNGUwMDAwZWU0ODU1MDBmM2FjMjgwMTAxMDcwMjAxDQowMTJhMDEwMThkNmMxNWNhMDAx YjAwMDA5M2U0OGQ4ODA0MDEwMzA1MDkwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMzAxMDEwNDAyMGJjOGUz Yjg1NjAwMzYzNmNiMTU2MTJiMDEwMjA3MDEwMTA2MDIwOTAxMDMwOTA1MDFlMDAwOTIyMDJhMDE0 MTAxMGIwMTAxMDkNCjBiN2IwMDAwYTgwMTAxMDQwMTJjMzIwMGVmNjMwMTg4YjNhOTAwNzRlMDA3 MDEwMjA1MDkwMTAxMDkwMTA5Mjk4MDAwNzRiZTA1MDEwMTJhODUwMDAwMDAwMDVhMDYwMTAxMDEw MTBhMDEwOTAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDkwOTA5MDIw MjAxMDEwMTAxMDEwODAzMDFlYzVlMDAxYjE5MDBjNDRmMDEwMTAxZmNmZjAwY2ZkZDAxMDIwNTA0 MDkNCjAxMDEwMTA3MDEwMTJhMGIxMGE5MDA2NDI5MDEwMTBiMDcwNDAxMDk0MTAxYTIzNjU1N2Qw MTA5MDEwNzAxMDUwNTAxNzUxOTAwMDA4MDgxMDEwODAxMDEwYjAxMDEyYjA2MGEyZTRjNjYwMDAw MDAwMGQ1NGM0ZTA2MGEyYTA1DQowMTAxMDMwNTAzMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDEwMTBhMDgw NTAxMDk1MDBhZmU1Y2MyMDAxYzQ4MDAzNjc2ODk4ODAxMDEwMTA5MGEwMzAzMDEwOTJjMjY3ZjAw ZmYxNDJkMDEwMzAxMGIwODA2MGM0ODAwOWIwMTA2MDcwMTAxYmQwMDM2ZjkwMTA4MDkNCjAxZTA1 ZTAwMDA3NzAxMGIwMTAxMDcwNzA5MmEwOTQyMDVlNjZmNTZjNTAyMDE5ZjQyNDRjYjAwM2EwMDlh NDMwMTBiNDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA5 MDkwMjAyMDIwMjAxMDEyOTAxMDEwN2NjNDcwMDM4MzkwMGE2MDIwMTAxOGU0MDZmMzdhYjBhMDE4 ODAxMDEwMTI5MGIyYjAyMDYwMzAxMDEwNTAxNGQxOTQ4M2YwYTA0MDYNCjAxMDEwMTAxMjkwMTBi OTAwMDMzYzgwMTI5MDEyYTYzNjdiZmNjMzZjOTJkMDEwNDAzMDQwNjAxMDEwNzAxMDZmMDdmMWMz NjAwMDAzN2U5NzIyYTA0MDkwMTAxMDEwMTAxMDEwMzA0MDkwMTAyMDIwMjAyMDIwMjAyMDIwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNTA5 MDIwMzAyMDEwMTAxMDEyYw0KMDMwMTEwYTUxYzNhMzgwMDAwMWQ5ZDQzMDEwMTAzMDEwMTBhMmEw MTAxMDhlNDNhNDgxYjE2NDEyYzAxMDEwMWNkMDA1NjhkMDIwMjAyMDExMTAwOTJhYjAzMDEwNTAx NDIwMTUwNGMwMDAwZjFlYzAxMDQyODAxMDEwMTA1MDENCjAzMDE4NTU1Yzc3MTAyMDEwNDA3NzAw MDE4MWMwMDhiODkwMTAxMDEwMjA1MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMg0KMDIwMjAyMDIwMjAyMDEwNzA1NDBjMjAwMzUwMGNiOWQwMTA4MDEyYmFjNjYwMGNm MDEwNjAzMDQwMTQyMDMwMTA5MDEwMTAyMDcwNTAxN2EwYjAxNWIxOTVmMjcwMTAzMDEwMTBhMDEw MTQxMDJhMGM3MDAzZDBhMDE3MTk1MzkNCjFhZDIwNmRjMDEyOTAxMDkwMTAxMDMwNTAyMGFhZWJh MDAxYTAwMDA2ZDZjMDM0MTQxMDEwMTA1MDcwMTAxMDEwMzA0MDMwOTAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDUwMjAxMDEwMTA3MGIwYTAxMDEwMTJiMDQwMTI3N2JiYzNhMDAwMDkyNTQ5ZThlMDUwNg0K MjkwMTAxMDQ0MjQxMjkwY2JiMWEzOTNiNzdlODAyMTAzYTAwZDIwMTJhMDEwOTgxYzIwMDg0ZTgw MjBhMDcwMjI5MDEwMTQyZmQzNTAwZGZmYzAxMDIwOTAxMjgwNzAxMDEwYTAxZDIwMDVmZDgwNzAx MDIwMThjMzcwMDVmMDANCmMyZmQ0MjBiMDEwYTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMzA5ZGNhOTAwMzkwMDk5YjYwMQ0KMDEwMTBhYTE5 MjFjOTU4ZTAxMmEwMTAxMDgwOTBiMDE3OTAxMGIwYTAxMDEwMTAxMDEwMTI4NGIxYjdlNDIwMTQx MDkwMTA2MDEwYTAxODg3ODM1MzZjMDZjNTQwMDAwY2QyYzA2MDMwMTAxMDEwYjI5MDkwM2NjYjc1 NjAwMDANCjAwNzQ2NGU3ODgwMTA5MDEwMTAxMDMwMzAyMDIwMjAzMDQwMzAyMDEwOTA0MDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAxMDEwOTAyMDMwNjA1MDEwNTA3MDkwMTAxMDkwMTAxMDE3MWJkOWEwMDAwMzYz YWMxZWMwMTAxMDcwNDAxMDEwMTAyMDFjODFlMDAwMGZmZjk2NQ0KMWNjNzQyODgwMTAyMDM3ZTAw MDA0YTlhODcwMTAxMDkwMTYyMDEwMTAyOGQzMmFjMDEwYjQyMDYwNzAxMDEwNzAxMDMwNTAxYWIz ODM3YzAwNjAxMDEwNjZiYTQwMDE4MWJkNWM4MDEwMTA2MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMTAxMDIwMjAyMDIwOTA5MDk3YTgwMDAwMDFhZWZmZDAxOGQwMTA1 ZjYxOTNiZGQwYjAxMDEwMTAxMGIwYjAxMDE0Mw0KZWE2MjJiMDEwMTBiMDk0MjAzMDcwNzBjNDYw MGVkMDEwMTA0MDEyODAyMDEwOTAxMDEzYzAwMzgwMDAwN2UyNTBhMDQwMTAzMDEwNjAxMDMwNTYz NWEzNTAwNTYwMGY4ZDYyODBiMDEwMTg4MDcwNDA0MDQwMTAxMDEwYjAxMDENCjAxMDEwMTAxMDkw NTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMTAzMDUwMzAyMDIwMjAxMDMwMTAxMDkwNDA5MDUyOTAyMGIwMTAx ODI3ZTQ4NGExY2NiZTEyZTAxMDEwYzI5MmMwMTAzMDMyOGIzOTM0YTFiMWEwMGQ4MjkwMTA3MDE5 ZTAwMWE3N2M3MDA0NzdjMjgwMg0KMDEwMTQyMDUwMTAxMDEyYjI4MDEwMTAxMDEwMjAxZTcwMTAx MDMwMTAxMmVkNzAwYTYyNzAyMDEwMTcxYjgwMDNhMDBiMDAxNDEwMTAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDIwMjA5MDkwOTA0MWUwMDNiMDBjZTlmMGIw NDAxMjgyMjFiM2E4NzAxMDEwMTAxMmEwYTAxMDEwYjRlZWYwMDNhM2NhNmJlMDEwMTAxMDEwOTAx MDE3ODQ4MDA0NA0KMDEwMTA1MDIwNTAxMDQwNThkMTQwMDkyYzI3NzAxYzYwMTA4MDEyYzBhMDEy YWFkYWYwMDAwMDAwMDc1YWMyYTAxMDEwMTA0MDUwMTAxMDEwNTAyMDQwYjAxMDEwMTAxMDEwMTAx MDIwOTA5MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA1MDkwMTAxMDEwMTA0MjgwNTAxDQowMTA0MDEwMTAxMDIw YTAxMDEwYjAxMDE2YjgwMDAwMDNhNDg2NWZjMDEwMTAxMDE0MjAxMDEwMTAyZjQ1NTAwYjAwOTA2 MDEyYjUxMDAxY2ZiMDQ0MDdkMDAxYTZlNDMwMTAxMjkwMTAxNTAwYTAxMDE0MTA3MDkwYTAxMDQw MQ0KMDEwNTJhMDYwMTA1ZDQxZDAwOWQwNDQxMDkwM2JlOTEwMDAwMDBmMzI3MDEwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxDQowMTAyMDIwOTA5MDk5ODFiMTgwMDE5 YjYwMTAxMDE4ZGJiMDBjZThkMDEwMzA1MDEwMTA2MDEwNzBiMDE2MzQ4NDgwMDFhMDAzOTc1ZDNm YzAxMjgwMTQyMDE2ODE4MDAxMTAxMDYwMTA5MDEwMWMwNDYxODAwMTcyYjAzMGMwMQ0KNDIwMTAx MDEwMTRlYTUzODAwMDAxY2RiZmUwMzAxMDUwNTA5MDIwMTAxMGEwMzA5MDkwMjAxMDEwMzI5MDMw OTAyMDkwMzAzMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwYTA1MDEwMTAyMDEwMzA5MDEwOTA3 MDUwMTAxMDYwMTAxMDYwNzAxMDI4OWYxDQowMDAwMDAwMGY1OTQwOTAzMDMwMTAxMDcwMTI4ODg0 ZGU3MDIwOTAzYmU1ZjAwZjgwNjAxMDkwMWU1ZDUzNjM2YTcwMTAxMDcwNzAxMDIwYTAxMDEwMTA1 MDMwMjA3MDEyYjA5MDEwMjAzMDEwMWRkYzIwMGJiMGMwNjAxMDFlYw0KM2EwMDMzMDBkZjlmMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIN CjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDcwMTA5MDcwMTJjMGE1ZTAwNTYw MDRhZjQwMzQyMDE4OGVmDQowMDU3YmUwMWEwMDEwMTA3MDEwNjBhMDEwYTA2MDE2MTRiMDA5YTdm M2EwMDAwYTk5YWJkYzUwMTA3MDEzMDFhNmZlYjAxMGEwMTQwZGYwMDAwOWE2OTAyMDEwODAzMDE0 MjAxMDFlYjIxOTIwMDAwNDgzZDBlMDEwMTA2MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMThmYzkwMDFiNDgwMGUxYzYwMTAzMmEwMTBh MDEwMzBhDQowNzAxMDMwMjdlMzk4YmM1MDE4ODAxMDEwMTYyYTUzNzAwMzEyODA1MDIwMTAxMGEw MTJjMDEwYTAxMDljYzA5MDEwMTA5MDYwMTA0MDEwOGEwOTEwMGNlNzkwMzA5MjkxMTU1MDAzOTNh OWEyOTQyMDEwMTAxMDEwMTA3MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMGIwMjAzNzkwMTQ1 MzYxOTFiNDkyNjBhMDQwMTAzMTcwMDNlMjkwYjAzMDIwMTI4MDEwMzAxMDEyYTg4MDEwMTg4DQpl OWNiMzk2MzYzNzAxZDAwMDAwMDAwNzQ5ZWRjMmE5MzM4ZjcwYzAxMmJiNDQ4MWNmNjAxMDEwMjdh MDEwMjAxMDEyYTc3NDkwMDAwYmE0Y2E4MDMwMTA3MDYwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjBhMjkwMTAxYzhlMTMzMzYzNzU1OTYw YjAxMjkwMTA1MDYwMTAxMDEwOGVhMDAwMDNkMjkwMTAxMjgyODAyMGE4ZDQ0DQo0ODM0ZmQwMTA4 MDEwMTBhMDYwMTAxMDkwYjlkNWZhNjJhMmEwNDAxMDEwMTAxMDUwYTJhNDUxODViMDEwMTAxMGJl MDE4MDA1NjAwNDUwMTA2MDkwYTA1MDMwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTg4MDEw MTAxOTYwMDAwMDAwMGUwMDEwMzAxMDE1YjAwNTc3OTAxMDEwNTAxMDEwMTAzMDYwNjJkMDEwMjQy MDEwMTAxNjUwMGU2OGQ0MjAxNzI3N2I4NWYwMDAwMzY2NjQ1DQowMDAwNWQwMTAxMmVkZjYyNDIw MzAyMDEwMTAyMDE0MjI1Y2UwMDFhMzRmNTdhMjgwMTAxMDYyOTA0MDEwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwOTAxMDEyNzAxMDE4MTFm MWMxYTAwODRlMDAxMDEyYTAxMDg0MTBhMDE4ZGIyMzkwMGRiYmY0MjAxMDQwMjAxMDEwOWRhYjM1 MDAxMDEwMTA3MDEwMTBhMDE4OGEzMzgwMGRmDQowMzAxMjkwMTQyMDEwYTBjMDEyOTA5YmExOTEz MDcwNDAxMDEyZTAwMDA0OTM2ZmIwYTA3MDEwODAxMDkwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAx MDENCjA3NDJhMTAwMDAzODAwNDQwMTBiMDgwMTFlMDA5OGM2MDE5ZjA3MDEwMzAxMDYwMTAzN2Nk N2VjMDEwMThlMDEyYzI4Y2UwMGIxMDEwMjBhMDEyODQwOTZmMzAwMzUwMDFhMWMwMGMwNDIwMTAx MDgwMTAxMjgwYzAxMDljNjZkDQowMDE5NDhmZjJlMDIwMzAyMDEwMTAxMDEwMzA3MDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDMNCjAxMDEw MzI5MGEwMWVjOTkxYjE4MDAzMmM1MDEwNzAxMDEwOTQxMDEyOWMwNWYwMDQ3ZDkwMjAxMGEwNzA3 MDEwMTAxMDEwMTAxMDgwYjAxMDEwMTBiNjk1NjAwZjg4ODA0MGEwMTA2MDE4ODAxMDcwMTA3MGMy YWNhMDBiMjA0DQowNDJjMDlmMDM3MDAwMDAwOTYwNjAxMDEwNDBhMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwYTAxMDE4YTAwMDA1NjAwN2Q1MDA5MDIwMWRmMzU3NDgxMDENCjAxMDkwMzAxMDEwNzI4 MDFkOTM0MDA2ZjYzMDYwMTA0MDEwMTEwNDcwMDc2MDEwNTg4MDEwOTA4MDE4ZGExOTgzNjAwMDBk MDAxMDgwMTAxODgwMTAxMDEwMTU5MzgzNjkyYTk1ZDBhMDEwMTA0MDUwYTBhMDUwMjAxMDEwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwOTAy MDIwMTAxMDEwMTQyMGEwNTczNDkzOTE5OGIyMjhlMDENCjA4MDEwMzAyMjkwMmM2OWIzODU2M2Uw MTBiMDkwNzAxMGMwYTAxMDUwMzAyMDIwMTBiMDE0MGNhMDAxZTA2NTAwMTAxMGIwNjAxMDEwMTAx MjcwMTAxNDE0MTk4MDBjMzc5MDEwMThlM2UwMDFiMDAzOGFiMDYwOTAxMDcwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDJmZTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDUwMjEwMTgzNzAwMzg1OTJiMDEwMTAxYWE0OTg0NGYwMTBhMDkwMTAxMDYw MTAyMDEwYjAxMTAzYTFjMThjYzAzMGENCjAxMmEwMWUwMDA0YjhjMDEwNjA3MDIwMTAzMmEwMTAx ODFiZGZiMDgyODAxMDEwYTA3MDE1MGUwOWEzNzAwMWNmNTdhMDEwNjAxMmEwMTAxMDIwMTAxMDEw NzBjMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDQwNTA0MDMwOTAyMDEwMTAxMDQwNTRmZTk5MjAwMDA1NDNmMDIwMTc5MDMwMTAxMDE1MDc3 MDAwMDliNjMwNDAxMDkNCjAzMDEwOTA3MDEwMTAxNTAwMWRhM2ExOTQ5ODgyOTAxMDE5ZjAxMDEw OTAxMGIwMjA5MDUwMzA5MjlhZGE0MDA5NTA4MDkwMTBhNGMxOTAwMDAwMGQ4MjkwMTAzMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyZmUwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjA2NmJjYTAwMWMzN2IyMDEwMTAxN2EyNjkyNDgwMjA3MDMwMTAx MDUwMzA5MDcwMjAxMjkwMzAxYTgzNjQ4M2FjODAxMDEwMzAxMDE1ODAwOTIyNTAxMmMwNzAxMjkw MTAxMDYNCjBhMDEwNjA3MDEyOTBhMDEwMWJmMjEwMDAwMzk4MzYxMDIwNTBhMDEwODAxMDYwMjAx MDQwODJhMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjA0MDEwMTA0MDYwMzAxMDQwOTAxMGIwYTAxZTBlNmNiMTkwMGJiZTcwMTAxMDIw MTA1MDEyOWUwNTQwMDE5MmYyOTI5MDgwMTQyMDEwMTA4MGEwMTI1YzIzNjAwZTcwMTAxYmYNCjAx MDEwMjAxMmIwMTI5MDEwMTQyMDEwMTUwMDE4ZjZmMDBlYTg4MDEwYjAxNTkwMDM3MDBlMmRhODgw MTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMmZlMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyYjYxYw0KMzkwMDFjZDcwMTBiMDE4ZTBlNGEwMDBlMGMw MTAyMDYwMTAxMDEwMTQxNDEyYTAxMjgwMjBiNDA5MjM3NDljODAyMDEwYzAxMDE1YjM4YjVlNzAx MGEwMTAxODgwOTJhMDEwNTAxMGEwYTAxMDUwMWQ5MzQ0ODAwYTlmNjA2MDENCjAxMjgwMTJhMDEw MTAxMDEwOTAyMDEwMTA5MDcwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDEwYQ0KMDQwMTAxMDQwNDAxMDEwYjAxMjgwOTAxMmNkMjRhMDAxOTY2 ZDgwOTAxMDIwYjAxMDEwNjYyZGIwMDM3ZDMwMTAxMDUwMTAxODgwMTA1NTBjYjAwY2JhZDA4MDkw YjAxMDgwYTAxMDQwMTI4MDE0ZjAxMDEwMTA0MDEyYTAxNjENCjQ5Mzg2MTA3MDEwYTAxOWEzODAw MDA1NTI1MDQwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyZmUwMjAyDQowMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMTAxMDEyYTAxMGE1MGI4MDAzNzAwOTg3YTA0MGEwMTQ0MDAzYmUw MDIwMTA1MDUwOQ0KMDQwMzI4MDEyMjM5OWU3YTA3MDEyOTA0MGI1NzAwNGJkODAxMDEwNzAxZTdj NzAwZDEwMTAxMDkwOTA5MGIwOTAxMDEwYzAxMDEwMTAyM2UzMzFhMDA2ZTYzMDEwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyODk4 Mw0KMTkwMDNhZmIwYTAxMDIwMTQyMDE3YTA1ZmE4MzAzZTU3YTBiMDEwYzAxMDM4OGY1MDA1NmFk MDEwMjA0MDEwNTAxMmEwMTAxMGIwOTQyMDEwYjBhMDEwNDAxMDUwMTAyMGU1ZjFjMjMwNjAxMDEy OGI4MDAzNzAwODAwYzAyMGENCjAxMGEwMTAxMDEwYjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMmZlMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxOGUwMTAxMDEwNDBiM2QxODAwNGFiMDUwMDIwMTAxYWMz NDRiM2YwMTA5MDcwMjAxMmEwMTA3MDE3YTM3NTYwMDM2NWJlYTAxMDEyODJjOWIwMA0KNDcyNDAx MDcwMTAxNDBkNTAwYzMwNzA3MDEwMTAxMDkwNjA3MDEwMTI4Y2NmNTU2MDA1ZmFlMDMwMTAzMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDE5ZTRhMDAwMGYzYWQwMTI4MDEwYjAxMDEwMzAxOTAwMA0KNTZhODAxMDEwOWEwNzQx YTU1YWQyOTI5MDkwOTA3MDEwNTAxMDIwMTAxMDFiZWIxNDEwMTAxMDEwNzAxMmEwMTA2ZWE1NmNi ODkwMTA1MGI4OGY3MzczNTAwYjQwYTAxMDYwMTc5MDEwODAxMDIwMjAyMDIwMjAyMDIwMjAyMDIN CjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDJmZTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMTBiMDEwMTYyMDE5ZDAwMTkwMDAwZmM3YTAx MDU4OWQ3MDBkMjAxMDEwMjBhMDEwMzAxOWYwMzI4MGE5NjAwZWVmODM2MzY3NDI0MDEwMTI4YjEz OTU2ZGEwYTA0MDUwMTY5NGIxYjYxMDEyODAzMGMwMQ0KMDEyYTAxMDQ2MWNlMDAwMDk5OGYwMTBi MDEwOTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwNDA3MDE3Mjk5MDBjMjg0NzgwMTI4MDIwMTAxMmIwYmRkMWQwMGM3MjUwYzdh ZDEzOTAwYTMwMTA4MDEwMTI4MjgwMQ0KMDIwMzhlMDEwMTg2NWYwMGI4MDgwMjJiMDEwMTAxMDcw MTAyZmIwMGVmZWMwMTAxMjdkNDM0MDAzYTM2YTEwOTAxMDgwMTQyMGEwMTAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyZmUwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjJiMDEwMTAxMDExMDNhMDAwMDAwDQo4 MjAxMDEwNmM2ODQwMGFhMDYwMzQxMDEwMTAyMDE5ZjAxMDEwMTI5MjgzYTFiYjkzZjE1MzkzOTgw YTIwMTQxYTUzNzU0NmIwMTAxMDc3YTljMTg2ZDA4MDEwMzA5MDEyYTAzMDUxNjAwMzc4YmFmYTAw MTI4MDM0MjAxMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDEwMzBiMDE0ZjE3MDAwMDAwNjUwMTA2MjgwNjAxMDE0MTdhZGYw MDM1NjM1NzAwNDhmYThlMDEwMTBhMGMwMTAxMDUwOTAxMDE0MjExNDgwMDg0Mzc5YzAxMDEwNDA0 MDEwMQ0KOWYwMTAxNWMwMDk5ODEwMTAxMDc4NjkyMWIwMDE5NmIwMzAxMDQwMTI4MDEwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDJmZTAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA0MDEyYTAxNGEzNjRh Mzk5YzA5OGUwNjAxZjcwMDEyMjgwMTI4MDEwMTAzMDkwNDAxDQowZDAxNDIwMTAxY2QwMDU5MDEy NzYzMTMwMDE4Zjc2YzAxZDAwMDU2ZTUwNDAxMDE0MThjMDEwMTQyMDEwMzAzMDFiNmI1MDA1ZjE4 ZjYwMTAxODgwMTAxMDEyODAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwODAxDQowMTAyMDEwMWEzNTY0YTRhNGI0MDAxMDE0MjAz MDEwMTAxZjUwMDAwMTkzOWRlMDgwMTAxMDEwMzBhMDEwMjA0MDEwNzAxZmIwMDAwODA3YjAwMzgz MTBhMDEwMTAxMmIwMTA3MDkwMTRjMDBlZThlMDEyODAxYjcwMDFhMTkzYg0KNGYwMTBjMDEwMTI5 MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyZmUwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTJiMDM1 ZTM5MDAwMGE0MDEwYzAxMDFiMTFiZjEyOTAxMjkwMTAxMmEwMjAyMDFjZDNhOTQwMTAyOGUwMTM0 MDA1MTAxMDIwNDQxOTAzMzAwDQoxODc3ZWUwMDU1ZTkwNjQxMDEwNDA0MGEwMTAzMDYwMWFiNTYw MDRhOWFiNjAxMDEwMTI5MDEwMWEwMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDE4ZTBjMDM0MjAyMDk0MDc0MzcwMDFiOWQw YTAxMDEwNzA5DQo3OTAxOWIzNzAwZjMwMThlMDEwODlmMDEwMTA2MDkwNTAxMDM1NDM2MDAyMTg4 MGMyNTAwMDBhYTA4MDEwYTAxMDYwMTI4MDEwMTFmMDAxZjJhMDEwMTI5ZWY0YTM3MDBkMTAxNDIw MTAzMGEwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMmZlMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjA2 NTAwMTkwMDA0ODAwOGJlYjI4MDEwYzRkNDg4MDJjMDkwNTA3MDEwNDA2MDEwMTcxMzkwMGZmYWMw MTAzMGI4NTMzYTUwMTAxMmIwMTAyMmM5Njk5MDAwMDM4MDAwMDEyMmEwMTAxNDEwMTA1MDEwMTE0 DQowMDFjMzljMzhlMDEwMTA0MGEwMTBhMDgwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA0MGEwMTAxMDcwOTAxMGMwNzVi MWI0ODM2NWM0MjA5MDMwMTAxNDIwMWYyMzYwMDEzMDEwYTAxMDMwMTg4MDkwNjAxDQo4ODU0MWQw MGFhMGMwNDAxOWY5NThiMzZkOTI5MDEwNTBiMDMwMjAxMDEwZDdmMzQxMTBiMDE0MjYyMWMwMDM3 MDA5MDAxODgwMTA1MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDJmZTAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDEwMWRhMWMwMDAwMzgwZTAxMmENCjA0YzZjNzM2MmUwOTA0MDEwMTQxMDkwMTI5MDEwN2Zl Y2EwMDkyMmQwMTAyMDczNzQ5MTAwMzAxMDEwNjA2MDFkZDg2NjYwMDAwYjhiZTAxMDEwMTAxMGEw OTI5NWIzMzAwZDcyNDA0MDEyOTA5MDEwMjAzMDEwMTQxMDEwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNTAxMDc4ODAxMDEw NDAxMDMwMTBlNTUwMDAwM2UyYTAxMmIwMTAxMjgwMWFlMzUxOTEzMDEyYTAxMmEwMTBhMDE2OWE0 MTkwMGExMDEwMTAyMDYwMTAxNGQwMDM0ODIwMzA0DQowMTA5MDkwMTA2MDEyZDAwNDdjNjAxMDUw MWQ2MTgwMDVmMDBkOTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMmZlMDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwNTAx MDcwMTAxMjkwMTA5Y2NhOTE5MDAwMDVjMDEwMTA3MDkxZDAwZDMwYTAxMDIwMTAxMDQwNzA3MDkw MTBhMDENCjQyNmUwMDQ3MGUwMTAxMTIxYWYxMGEwMTA4MDEwMjAxMDkwODA1ZTQzMjlmMDIwMTAx MDYwMjAxOWY3ZjFjMDA5Mzk0MDEwNTAxMjgwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAyMDEwMTk0Y2EwMDM4ZDVlODAxMDMwOTAxMDEwMWZhMDAzNzVlZTcwMTAxMDMw OTJlMTgzOTE5MDA2NDAxMGIwMzAyMmMwMTJhZDAzNjM3YTcwMTAyMjgwMTAxNDEwMTAxOTYxOWM3 MDcwMjA5MDE2NzAwDQo1NjAwMzM3MTAxMDEwMTBjMDEyODAyMDEwMTAxMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDJmYTAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAzMDEwNjAxMDYyODAxMDkwZGVlMDAwMDM4ODMwNjAxNDIwMTZkMWFiMjAxMDEwOTAxMGEwNDBh MDEwMTAxMDYwMTAxMGMyYWYxMWMzNDEwMDIyYjVmM2E2OTA3MDEyYTA0MDINCjAxMDkwOTAzMjkw MTQyMDEwODAxMDNmYzhiMTkzOWM5NjMwNjAyMDE0MjAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMGIwMTA1MDU3OTUzMDAxOGI1YmUNCjI4MDE3YTAxMGEwMWQ2MzY0OTMx OGUwMTQyMjU0YTRhMzg1ZDM4Mzg3YjAxMDcwOTAxMDEwMzAxMWYxOGE0ZWIwOTAxMjgwOTAzMDEw MTAxZTEzOGUxMDEwYjA3MDFiMDFhMTkwMDYwNDIwYzI4MDEyODAxMDEwYjJjMDEwMjAyDQowMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyZjcw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDcwMQ0KMDEwNzAyMDEwMzAzN2QwMDM2MDA4NDQyNDIwNTAxYjMwMDlhYTAwMTAyMmEy YzAxMDkwMTBjMDEwNzAxMDU0MjA1MDEwNDdlNDgzYTBlMDkyZjAwODQwNjAxMDQwMzAxMDkwOTAx MDEwMTAxMDEwMTAxMDE0M2E0MDAwMDEzN2ENCjAxMDEwMTJhMDEwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA1MDEwMTAxMDQwYmFmMDAzYTdmODEyYzAxMDMwMTA5MDFj NjViN2EwMTA3NWMxYzAwODQNCjA3MmM4YTFjMzlmOTAxMDcwNjAzMDkyODA0ZWYwMGJiMDEwNTAx MmIwMTBhMDIyOTlmOWEwMDIzMDEwMTAxN2E5MjQ4MDAwMGZiMDEwNjAxMDkwMzAxMDIwNTAzMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMmZmMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAxMjkwMTJjMDEwMTAxMTEwMDQ4MDA1NjI1MDIwMTAxYjYzYQ0KYTlmYzA3 MDkyYTAxMDEwNDBjMDEwMTAxMDMwMTAxMDEwMTAxMDQyY2I0MDA0OTQwMDc1NzAwZTUwOTAxMDEw MTI5MDEwMTQxMDgwMTAxMmEwNzExZDcwMDFiYzMyYjAxMDE4ODA5MDE0MjAxMDIwMjAyMDIwMjAy MDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTBiMDYyODAxMDEwMWIyMDAwMDdmYjMwMTA1 MDkwMTA2MDEwMTAxNDI1ZDAwMzdhZmM2MDcwMWEwNWMwMDhiNzIwMTAxMDUwMTAxMDI3OTIwNDEN CjBhMjgwMTAxMDE4ODAyMDkwYjcxYTkxYmM4MDM0MTAxNzIwMDE5M2EwMDgyMDEwYjAxMmEwYjAx MDEwNzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyZmYwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA3MGEwMTI5MDU0ZjRiMDAzODM4M2UwMTI4MDEyNzVlMDBm MDAxMjkwMTAxMDkwMTQyMDEyYTBjYTZhM2U1YWViZQ0KMDFiZjAxMDEyYjIwMDAxOTUxMjQwMGQ3 MDMyYzAxMGMwMTAxMDcwMTAxMDcwMzAxYjMwMDAwOGJkMDBhMDEwNzAyMDUwOTAxMDcwMTAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDE1MDAxMDgwMTAxMGEwNzFmY2Iw MDM5OTUwNzAxMDkwMTJiMDEwOWQzMDAwMDE2MDEwMjBhMjgwMTAxYzMwMDgwZmMwOTAxMDUyOTJh MDEwMTA3MDIwMTJiMDc1MDAxMDEwMzAxMDFhMzNhYzc4ZDAxMDUNCjAxYzEzOTAwMzUxODcxMDkw YTAxMDEwNzA3MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMmZlMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQow MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDUwMTAxMDEwNDAxMWUwMDM2MWExZTAxMDgwMTAx ZWUwMDUyMDEwNzAxN2EwMTA4MmIwMTI3MjJhOTM3MDAwMDAwMTkxZDBlNDIwYTAxOWZlOTE5MDA1 OGY1MDA3NzAxMDEwOQ0KMDEwYTBhMDEwYTAxMDE5ZTFhNDgzNmYwMDEwMzA1MDEwODAxMDIyYzAx MGIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDI1MDAxMGIwMTA0MDkwMTAx MDgxMQ0KNGEwMDAwOWUwMTA0MDEwNzAxMDkyYmZmYjUzNjcyMGEwMTBiMDEyYzBjZTIzOTQ3ZGMw MTAxMDMwMTI4NzkwMTI5MmMwMTA5MDEyODJjMDE4ODI5MDFjMzE5MTQwMThlMDkwYTgzMzYzOTAw ZDAwMTJjMDEwMzA5MGEwMTAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDJmZTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIyODAxDQowMTBiMDFkOTAwNTYwMDM4NTAw MTA3MDE5ZDFhNTM3YTA0MDEwMTA1MDcwMTAxODE3ZTAwMDAzMmQxOThlMjAwMWEwMGIwMjk4ODAx ODgxNDM1MDAxZDNhNTU0MTQxMDEwMzAxMDEwMTBiMGE5ZTRhMDA5MmFjMDcwMTA5MDE0Mg0KMDEw NzJhMDEwNzAzMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDE3OTAxMDcw MTA3MDQwNDAxODgyNTM0MWIzOGYyMDEwODAxMDEwMTA5MGNkZjAwY2UwNg0KMDIwNDAyMDEwMWM2 MWQzYWY3MjkwMTI4MDEwMTAxMGIwMTAxYTc4ZDAyMDcwMTAxMDEwMTQyMmM2MDAwZTQwMTAxMDFh MGMyMDAxYTAwYTcwNTAxMjkwMTAxMDYwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyZmUwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMjUwMDE3YWQ1M2EwMDM3 ZGE0MjAxMDFmNDFiNDllYjAxDQowNDA0MDMwMTAxMDg3MTVlMDA1MzcxODgwMTAxMDg0ZWIxMDAz OWNiN2IwMTAxMmM1YjAwMDAwMDFiNGQwMTAxMDgwMTI5MDcwMTlkMDAxOWNiZDYwMTAxMDcwMjA1 MDEwNzAxMDEwNTAxMDkwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjI4 MDEwOTAxNTAwMTAxMDMyODAxMDEyNDkyMDA0OGYyMDEwMzAyNDIwMTAxNTA5MzM3NTM0MjAxMDMw NTAxMDU4OGI4YmQyYjAxMDE0MTAxMDIwYg0KMDQyMjE4NTMwNzBhMDE4ODAxMGEwMTJhZTc1NTFh ZDgwOTAxMDFmYTM3MWIxYjZmMDMwMTAyMDUwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDJmZTAyMDINCjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA3MDEwMTBjZTQw MDE5MDA5ODA1MGIwMTQyYjUzNzI1MDIwMzAyMDkwNTAyMGEwNzIwMWE5YTAxMGIwNjAxMDcwMTA2 DQowNzdiMTg0ODAwZmMwMTA5MDlkMDM4MzkzODg3MDUwMTAxMDMwMjA0YTEwMDFiOGJlMDAxMDYw MTAxMmEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTQyMDEwZWJhMDAzNmMxMDcwMTAxMDMwYTA5ZmUxODFi M2MwOTA4MDEwOTAxMDEyYTg4MDEwMjA2MDEwNDBiZmM0NjM4MDA0NjdhMDcwNDAxMDEwNTAyMDE1 MDRlMzdlZg0KMmIwOTI5MDE1ZTAwMDAzNzk2MGEwMTA5MDgwMTAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyODAwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNTAx Mjk0ZTVmMzcwMDFjN2EwNzAxMGI1NzAwZWQwYTA0MDQwMTA5MDQwMTAxZmUwMDE5OWYwMTA0MDFh MDAxMGMwMTAxMDNlOGUyMzljZTAxMGIwMTAxMTQ0YmM4MGIwYTAxDQowNDA0MGE3MzQ4MWI1ZmI5 MDEwNzAxMDUwYzAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA5DQowMTI3MDFmYzFjMDBjYmMxMDEwNzAzMDEw YjA5ZGQ0NzAwNmQwMTA4MDEwNDI5MDEwMTA5MDEwMTAxMDFjNDM5MDAzMzc2MGI0MjAxMDUwMTAx MGEwOTAxMDEyOTVjMDAyMTAxMGIwMzQzMWMzNjE5MDBkYzA3MDEwMjA1MDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjgwMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAxMDYNCjJhMzIwMDAwMzkzMTAxNDEwMjg5MWNiODA3MDcwOTA5MDEwMzBhMDIwMTVhMzc3MzAx OGUwMTAxMDEwNzAxMDEyODAxMDFhNmNiMDA3YzAxMGIwMTQyZmMwMTAyMDEwYjA4MDFlYzNhMDBk NWRhMDEwMjJjMDEwMTAxMGEwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwNjA2MDEwOTI5ZGMzNDAwM2EzZjAx NDEwNzAxMDM0MmZjDQpiYTAwZDIwNDA0MDEwNTAxMDEwMTA5MDQ4Zjc1MDAxYjg0ZDYwODAxMDEw YjA5MDEwMTA1MGEwMjAxMDEwY2UyOTJkNjA1MDIwMWYyMDAwMDAwZTIwMzAyMDEwOTAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDI4 MDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwNTAxZTUwMDAwMDA5MzA2MDkwNjJhOTgxY2E3MDkwYTAxMDkNCjAxMDMwMzAxMDFj MjM2MGUwMTJhMDkwMTBhMDEwMTA2MDMwNTBjMDFjOTRhODQwYzAxMmIwMTAxMDcwYjI4MDEwMWZl MTkwMDkyMmQwMTA2MjgwMTJhNDIwMTA0MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMGEwMTAxNDEwMTAxYjk0 ODAwNWZkYTAxMDE0MTAxMDkwMWMwMDAxYWNmMDgwMjAxMDEyYzAxMDE5NjNiNTY1NTU4DQowNDA1 MDEyODBjMDEwMjAyMDEwMTAzMDYwNzA5MDNlMDAwN2UwNzJhMDEyYTY2NTYxYzAwOTUwMzAxMGIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjgwMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMGJjYzZmMDAzMzE4YTcwMTBhMDFkZTAwNWEyYzI4MDEwMjA1MDMwMTAx MDEwMTFhMDA4NzAzMDEwMzAyMGIwMTQyMDENCjAxMDkwMTAxZDgwMDFiMjgwMTAzMDY4ODA5MDEw YTAxNjExYjM2MWNkZTAyMDUyYTAxMDEwYjAxMDQwNTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwOTAxMDFhMDAx MDE4ZDAxZDI5MjAwOGJhODA4MDEwYTAyNDEwMTQ0NGFmMTAxMDEwMTlmMDEyN2FmMDAxODAwZjEy YTAxMDEwNjI4MDEwYTAxMDQwOTAxMDEwMTAyMDEwOTg4DQoyMDAwNDQwMTAxMDIyZDFhMDA0OGE5 MGQwNDA1MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDI4MDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxYmIwMDAwMDA1YjAxMDcwMzQzMWNhOTJiMmEwMTA0MDEw OTA2MDEwMzAyMDczYjE5M2YwODAxMDIwNjAxMDQwMTAxMDMwNzAxMjk2MjM3MDAwMTBjMGMwMTA5 MjgwMTAzMmQNCjZmMDBhOTEyNTAwMTAxMjkwMTA2MDEwMTBiMGEwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA1MDEN CjI4MDEwMjA4MDEwYjAxZTUzOTM2MDBhMjAxMjkwMTAxMDYwMTExOGQwMTJhMDYwMWZhOTIwMDRi NWUwMDkyZDkwMzAxMmIwMTA0MDEwMTAxMDQwOTAxMDEwMTAxMDEwM2JmNDg1NWViMDYwNDAxZGIx OTAwMDAxMzA3MDEwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyYTIzNg0KMDAxODNhMGMwMTAyMDExNTAwZmIwMzAx MDcwMzAxMDEwYjAxMGIwNjBhNGMwMDliMDEwMTBiMDE3YTAxMDIwYjA1MDEwNDAxNGUzNzAwOGUw MTAxMDcwMTAxMDcyODFkMDAzNTc2MDEwMTA5MDEwNjAxMDEwNjI5MDEwMTAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwYjAxMDEwNzAyMDUwNzAxMDEwYjcwMWI0YTU0ZTcwMTAyMDENCjA4MDEwMTJhMGEwMTAyODA1 NTM1OGJlNTAxNWIwMDdmMmI0MjAxMjkwYjAxMDEwMTA5MGEwNTAzMDMwNTJiMDEyOWExMzhiYjA1 MDE1MDA0NGIzOTFiMDBkNjAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQow MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMmE0MDAxYzAwYjMwMTA3MDM2NDFjNDYw OTA0MDMwMTA5MDcwMg0KMjgwMTA0MDEwMWEyMDA0OTdiMDEwNzA1MDEwNDA3MDEwMTI5MDEwNGE4 MDBkNTAxMjgwMTAxMDQwNzBjZTIwMDM2N2MwMTJhMDEwYjBiMDEyYTA3MDEwMjAxMGEwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDEwNjA0MDEwMTAyMDUwMTA1MDEwMmYwM2EwMDlhOGQwOTBhMDEwYTAyMDEwMTJm NGIzNjAwN2UyOTAxMDcwODYwMWINCmIxMGIwNjAxMDEwMTI5MDkwMTAyMDIwMTAxMDkwMTA2MDEw NWVmMDA2OTI4MDEyOWE2MzkwMDU2Y2EyYTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTI4MDEwYjAxOTYxYTAwM2E1ZTAxMDEwNTQx NWUwMDg5MDIwMzA1MDEwODAxMDUwNDAxMmEwMTAxMjhiYzAwZDdlNzAxMDEwMTBhMDQwNA0KMDEw YTA0MDE5MTE4MWYwMTA0MDEwNTA5MDY2NjM2MDAxNDQyMDEyOTAxMDEwMjAyMDIwMjAyMDIwMjAy MDEwMTBhMDIwMTBhMDIwNzAzMDEwNzAxMDkwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxNDIwMQ0KMDkwNjAxMDUwYTA5 MDEwMzAyMDEwMzAxMDEyOTAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTU3MDA0OTFkMmEwNzAyMDIw MTA1NzIwMDFiMTgxMTJiMDEwMTJiMDE4OWMyMDAxMTA3MDEwMjBiMDEwMTg4MDEwMTAzNDEwMTAx MGENCjA2MDE2MzAwZjc0MTA2MDEyOTkzMTgwMDkyOWUwMTAxMmEwMTAxMjgwMTAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMTI3MDEwMTBjMDFmYzhiMDAzODAwMmQw NzA0MGI5YzAwNWMwNjAxMDEwOTA5MDEwMTA0NjMwMTAyMDEwNTAxYzU2ZjM4NDkzZjA4MDMwMTAx MDQwMTBhMDE2ODNhMTk3MTAyMDcwMTA3MDExMzM3MDAyMQ0KMmIwMTA3MDE0MjAxMDIwMjAyMDIw MjAyMDIwMjA5MDEwMjAzMDcwMTA3MmM1MDc5NGZhMDBkN2E1MDlmOGU4ZThlOGU4ZThlOGU4ZThl OGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGUNCjhlOGU4 ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThl OGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4 ZThlOGU4ZThlDQo4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThl OGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZThlOGU4ZTJjNDE4ZDRmNDIw ODBjMGNlOGEwMDEwMzAyMDE0MTAxMDIwMg0KMDIwMjAyMDIwMjAyMDMwMTA0MDcwN2QwMDAzODNl MDEwNjA3MDUwMTA2YmIwMDgzMDgwMTAxMDQwMjAxMDE1YzhiYzcyOTAxMDMwMTJhMDEwMTBiNDEw MTAxMDEwMTA1MDIwMTlmMzEwMDNlMDMwMTAxOTQzMzAwMDAzM2I5MDENCjAxODgwMzAxNTAwMTAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjI4MDEwOTA2MDEwMTkxMDAzODAw DQo4NTAxMGEwMTJlMDAxZGU3MDEwMTAyMDEwYTAxMGE4NzdlMDMwMTQxMDE4ODAxMmYwMGE5MWM1 OWU4MDYwNzA5MGIyYThjMDAwMGE2MGEwMTQxMDEwNjgyNmYwMDMyN2EwMTAxMGEwNjAxMjkwMjAy MDIwMjAyMDIwMjAyMDEwNQ0KMGEwMTAxMGI1YjAwMWEwMDNhM2EzODE5MzcwMDFhMWExYTFhMWEx YTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFh MWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWENCjFhMWExYTFhMWExYTFhMWExYTFhMWEx YTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFh MWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhDQoxYTFhMWEx YTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWExYTFhMWEwMDAw MzczODM3MDAwMDAwNDkwMGNmMDYwMTAxMDgwMTAyMDIwMjAyMDIwMjAyMDIwMThlMDEwYTAxMDk2 NjAwMTljNA0KMDEwMTA0MGIwMWViN2YwMDVhNDIwMjA0MDE0MTAxMDFjYjFhMjMyYzA5MjgwMTQz MGEwMTA1MDEwMjdhMDEwNDAxMDEwNDYyYzczNmFjMDcwMTA3NWMwMDQ4MWE5YjAzMDEwNzA2MDEw ODAxMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNDAxMGEwMTAxNjQw MDM5MzdhNDQxMmMwMTQxMjAwMDJmMDEwNTAxMGIwMTAxMGEyYWZmDQowMGM0MDkwMTAzMDE0MjAz N2EzYjFiMDAzNTNjNmFkODY3N2UwMDRhYzEwNjBhMDEwMTA2ODEwMDE4ZDVkNDA5MDE4ODA5MDEy YTAxMDIwMjAyMDIwMjAyMDIwMjAxMDMwMzAxMGEwMTEzMDAwMDAwMDAwMDAwMDAxYTM3MDAwMA0K MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDM5MDAwMDAwMzgzMzM3MzhjMDAzMDEwYTA1MDEwMjAyMDIwMjAyMDIwMjAyMDEwYjAx MjkwNTA0ZTdjNzAwZDUyZTAxMDEwMTAyMDFiNjFjMDBkYTA0MDQwMTAxMjkwMQ0KYjIwMDEzMmEw MTAxMmEwMTAxNDEwMTA1MDkwMTAxMDQwMTA2MDEwMTBmMDBmNTQxMDE0MjJhOTkwMDAwMDBmNDBh MDEwMTAzMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MDAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDE0MjAx MGEwMWNhMWIxODAwZTAwMzA1MDE5NjQ4YjEwMTAxMmEwMjBhMDEwMTA0MDE2NjFjOWFlYjAzMjgw MTAxMDE0MTAyZjA3ZjAwMDAxOTAwDQowMDAwYjVmYTA0MDIwMTAxOGUwNmVmMDAwMDc4MDEwODAz MDEwMTA0NDEwMTAyMDIwMjAyMDIwMjAyMDIwMTA5MDMwMTA3MDE1YzE4MDA0ODAwMzkzNjAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDA0ODAwDQozNzAwMWMzYTAwMDBkMGFkMDEwNzAxMDcwNDAxMDIwMjAyMDIwMjAyMDIw MjA0MDEwNDAxMDE4ODAxYzQzOTAwYjA3MTAxMDIwMTA5MDNmYjFhYTk0ZjBhMjg0MjAxMGE1YTFj MjAwMzAxMDEwMTA4MDUwMTAyYmUwNzJhMDMwMw0KMDEwMzAxMDIwOTFlMDA3YzAyMDEwMTc4MDAx YTAwN2YwMTI4MDEyOTAxMDkwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDEwMjAxZWEwMDAwMDA3NDBhMGIwMWU3YzIzNmJlMDYwMTAxMDYwMTAyMjkwMTAxYjYwMDM5 ZTQwNzA0MjgyYTAxMDMwMzAxOGRjNGNmYjA0YjUyZWFkYzJiMDEwMTAxMDgwMTE2MDAwMGQyMDkw MzAxDQoyODAxMDEyYzAxMjkwMjAyMDIwMjAyMDIwMjAyMDEwNDBhMDEwMTBhY2RjYjVmNTQwMDAw NDgzOTM5MWMwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDM5MDAzNzFjMDBiOGZiMDEwMTBhMDEwNTAxMDUwMjAyDQowMjAy MDIwMjAyMDIwMTA4MDEwMTJjMDEyYjA0NTkxODAwNWEwMTA0MmEwMTJhMjk1ZTM4NmUwMTAxMDEw YWFjNTYxYTlkMDQwOTJhMDEwODAxMGI3MzZmZmIwYTAzMDEwYTAyMDEwOTI5ZGM0NzkyYzUwMTlm MDU1MzAwMzYwMA0KZmEwMTAzMDQwMTA5MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDEwYjA2MDNjYTFjNTYwMGY0MjkNCjAxMGI4NTAwOTAwMTJiMDEwMTAxMDEwMzI4MDEy ODBjZGYwMDM0OGUwODAxMDEyYzAxMjgwMjAxMDEwNTAxMDgwMTA3MDEwMzAxNTAwOTAxZDgzNzAw ZWU1MDAxMDE0MjAxMjg0MjAxMDkwMzAyMDIwMjAyMDIwMjAyMDIwNDAxDQowMTAyMDYwMTAxMDEw MTBiNjYxODFhMDAwMDAwMzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3 MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3Mzcz Nw0KMzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3 MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3Mzcz NzM3MzczNzM3MzczNzM3MzcNCjM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3MzczNzM3 MzczNzM3MzczNzM3MzczNzM3MzczNzAwMDAzOTAwMDAzNmY1MmIyODAyMDcwMTAzMjgwMTBiMDIw MjAyMDIwMjAyMDIwMjAxMDMwMTJhMDU4ODAxMDQwOGRiDQowMDAwZGEwMTBiMDQwMTBhZmM2NjAw NzVkNjJlYzE0NzkyYjU3OTAxMDkwMTAzMDdhNmUyMzUwMDM1NzEwOTAxMGIwMzA0MDEwNjAxNzcw MGMxMDEwMTAxYjMwMDAwMDAxZDg4MGIwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjJhMDEwMWE2MTgzNzAwZDEwMTAxMGIwYzAwNGIwMTA4MDEwMTJiMDEwNzA0 MDEwNzAxMDENCmNjNDgwMGQwMDEyODBiMDEwOTA0MDUwMTAxMGEwMTAxMDYwNzAxMDQwOTAxMDVl ODE4MDA2ZmViMDgwMTAzMDEwNzAxMDEwYjA5MDkwMjAyMDIwMjAyMDIwMjAyMDUwMTAxMDEwMTA3 MDEwMTAxMDUzNzAwMzcwMDAwMWIwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAN CjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxOTAwMWMwMDM4MDA5ODAxMDEwMTAyMDUwMTAx MGEwMTAyMDIwMjAyMDIwMjAyMDIwNjAxMjgwMTAzMDE3OTAxMGFlODQ3M2ExYTg5MDEwNjI4MDEw MWQ2NDk0YTFiMDAwMDAwDQo0OWE4MDEwYjAxMDVlYWZmMWMwMDAwY2EwMDczMjkwMTAyMDEwYTBh MDEyYzJhZWYwMDk0MDEyYTA0NzUzODAwNDhmOTAxMDMwYjA0MDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjA4MDIwMTAxMDEwMTAxMDEwNTAxMGIzMzE5MTkwMDJmMDIwMjA5MTUwMGZhMmMwMTAxMmEw MTA0MDEwNDA3MDMwMTAzMDE1YzM4MzljYzBiMDUwMTBhMjgwMTA5MDQwMTA5MDENCjA5MDEwODJh MDEwODA2MWQzODFiYTcwMTAxMDUwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMTJhMDgwNDQyMjEwMDRhMzcwMDFhMzkwMDAwNWYwMDFiMDAxYzAwMDAwMDFj MDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMWENCjFjMDAwMDM2YjgwMTAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjBhMDEzZjM2MTg3NDdh MDkwMTA3MDUwMTZiYjQ0ODAwNGIxNzQyMDEwMzQyZmM5MTM3MDA0ODE1ODk4ZDU2MzkyZTAxDQow YTI4MDEwNzI4MDEwNzZhMDBiMjAxMDEwMTZhMDAwMDNhZDUyODAxMDUwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDEwMQ0KMDEwNDBhMDUwNDA0MDUwMWFlM2EwMDAwM2NiZjBhMDFjNTQ3MzYwODAx MjgwMTA5MDIyODAxMDcwMTAxMDUwNTAxNjIzYTM4NDUwMTA3MDMwNDAxMmEwMTAxOWViOTQxMGIw NDAxMDE0MTBhMjA0NzAwOWUwMTBiMDEwMTAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEyYTdkNjZiYWNlODQ3NTFiNDgzNzAwMDAxYTFiMzYw MDFjMDAzNjM2MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzNjE4MDAzYTAwZWZlZDA1 MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA5MDE1 MjAwMWMzMDAxMDEwMTA0MDEwMTAxMjc5ZmFkMDEwMTBjYmY2NTAwMzgwMGRmY2MwMzAxMmFjZDAw ZTYwMTAxMDEwMzAxMDEwYTAxMDg4YjkyMGQwMTBiMDViNDAwDQowMDNhYmQwMTBiMDEwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAxMDkwNDA5MDEwMjAyMDEwMTBkZWYzNzAwMDBkYTAxMDkwMQ0KYjcw MDVjMDEwMTA3NDIwMTAyMDFkY2IwMTQyODA3MDE4ZTA4OGEzOGUxMDk4ODdhNGYwMTA1MGE3MWMy NTU4NzAxNDIwMTQyMDEyNjM5MDA2ZDI5MDEwNTA5MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjA5MDkwMjA1MDEwOTAzMDEwMTA1Y2MwMDAwMTkwMDQ4 MDAwMDFiMDAzOTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDFhMDA2 ZjAzMmEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA1 MDENCjAxMDMxZTAwMzZhMzAxNDIwNTI4MDYwMTAxMmMwMTA4YWQyMDVmNGEwMDM3OTdhMDAxMDEy ODAxYTA1NDAwZGEwNDAxMDkwMTAxMDIwNTAxN2QwMDlkMDEwYTAxMjYzOTAwMWExZDQxMDkwMTAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwOTA0MDIwMTAxMDIwOTAxMDE0NDE5MDAxOGQ3MjgwMTAx YmY0YjhiMmIyYTA1MDEwMzAyMDEyOTQ0MDAzNmMyZDk0Mg0KMDMwMjBkMDAzYmYzMDAxODFiNWU2 NWE1NDYwMDgzN2EwMTAzMDEwMTI3YmEwMDg0YzYwMTg4MDEwNjAxMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMjkwODBhMDEwNDAxMDkNCjcxMTkw MDNhMDAwMDFjMDAxYzAwY2IwMDFiMWEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDM3 MDA0ODAwY2EwMTA0MDQwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwOTBiMjkwMTlmYzIxODQ3MGMwMTAzMDEwMjAzMDMwMWEwZjINCjFiNGE0OTM4ODQ0ODE3 MDE4ODAxMDEwMTAxY2YwMGI0MGIwNzAxMDUyYzAxMDEwMTcxNTVjYjJiMDEwNTJjNzUwMDAwMThl MzAxMjgwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEwMjBhMGEwMzA3ZTYxYTAwMTk0 ZDAxMDUwMmU0MDBjZDAxMjkwMTAzMjkwMTAzMDE4ZDMwYTQwMDAwZDVhODAxYmUzNjM4MzcwMDM4 MzcwMDFjMDAzODE2NDIwMw0KMDEwMTJiMDExNzAwMDA2OTAxMDkwMTAxMDQwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA3MGEwMTAxMDEwMTAxMGIwNzBh MDEwYzAyMDMwMzAxMWIwMDFhMDAzYTM5MTkwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMTgwMA0KMzdjMDlmMDUwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDEyODAzMDEwMmY0MWIxYTE1MDEyNzAxMDkwMWE4OTUzNDAwNGE0NzY3MDFk NDAwNDhkYzA2MGIwMjBhMDcwMTQ5MWINCmZjMDIwMTAxMDkwMjA2MDEwMTVkMDA5NzBhMDEwMTcw MDAwMDE5OWEwNTAzMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxDQowMTAzMDMwMTAxMDFkYTRh MDAwMGI1N2EwNTAxOWY1NTM0ZTgwNTAxMGEwMTAxMjgwMTAxMGEwMTg4M2MzYTAwYzJmOGUzMWNl NmQ2MGEyNzc5MjVhNmRlNjEyOTAxMjgwMTA3MDFjNDM2MDBlZTBhMDIwMTJhMDEwMTA0MDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAyMGEwMTI4MDIw MTAxMDEwMTA3MDEwMTI4MDEwYTAwMzc0ODFiMDAwMDM4MWEwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDA0YWU0MDEwOTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjA1MDEwNDAxODgwMTgwMzkzODdiMDEwMTAxMDdmYzAwNDg0ODNl MDQwMTA2MDJjZDAwNjUwMTAzMDEwMTQyMDFkZjAwMzEwMTBhMDEwMTBhMmEwMTAyNDIzYjQ3NzEw MTAxZWINCjFkMDAwMDAwYTIwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDQwMTAyMGEwMTAxMDE0 MjU3MDAwMDE4OTYwMTBiMDFlNDAwDQpmNjAxMDgwMTBiMDEwNDBiMDEwMTAxODgwOTAxYTI3NTAw MDBhOTAwYjkwMTAxMDUwMTA3MmMwMTAxMDEwMTAxMDQ0MjA5NTMxYTE4ZmMwYjAxMDFiZjAxMDEw MzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMGEwMTA1 MDEwMzAxMjkwNjJjMDEwNjAxMDcwMTAxMDY3MTBkYzg3N2NiMWIwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAxOGIxZGQ3MTAxMDEwNzI4MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMGEwNQ0KMDEyYzAxMDUyNTNiMzZkNzc5MDUwOTBhMDFi MTAwM2MwMjAxMDEwMTJiOWYzNDAwNTEyYzA4MDkwMTA4NmQzNzE2MDEwNTA5MDUwMjAxMmMwYjAx YzMwMGJkMDEwMTAxOWQxODAwMDBkYjg4MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA0MDEwMTA3 MDEwMTlmYjYwMDAwNDg1NTQxMDEwYjBjOTJjYTJhMDcwMjAxMDEwNjAxMDkwMTBjMDMwMTAxMDUw MTBhDQo3ODk5MTkwMDRiNzgwODAxMDQwMzAxMDIwMTI4MDIwOTA0MDE1MjM3MDBmYjAxMDEwMzBi MDEwYjAxMDMwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw YTAxMGEwMTA2MDEwNTAxMDUwMQ0KMDcwMjAxMDQwYTAxMGIwMTA3NjkxODFhNTY0ODAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMWM0NTA2MDEwMTQyMDEwMTAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEyOTAxOWYwMTAxMzEwMDFhYWUwNjAx MDE5ZmU4M2IwMA0KYTgwMTBhMDEwMTAzYWEwMGI4N2EwMTAyMDFkMzAwMWEzZjAxMDYwMTJhMDEw MTI4MDEwNjUwZTI1NjJiMDQwMjJiNTUxOTM3MDBkYTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MTA1MDMwMTlmMDEwMWJiMWIzODAwZDMwNzA5MDM3MzAwZjYwNjAzMDMwNzAxMDcwMjA1MDEwMTAy MDMwMTA5MDUwOTAxOGU1MmM3MDAzNmUyZGEwMTBiMDE0MjA5MDEwMTBhDQowMmZkYzIwMDY2MmMw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNzAxMDQwNTAxMDEwMTY1MWIw MA0KMDAwMDE4MDA1ZjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMWEwMDM1MDAwMDAwZjcwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMjAyMDkwOTA5ODQw MGNiNjMwMzAxMDQwMWJkMDA5OTA2MDUwYTA5MDIwMjY2MDBjZWEzMjM2NzAwMDBmMQ0KOWYwMTAx MjkwYjAxMDUwMTAxMDMwMWFiMzk0NTA3MDEwNmU1NDgxYjAwZTkwMTAxMGMwMTA2MDQwMTA0MDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjA2MDENCjA0MDEwMzBhODljYTAwMzg3ZjA4MDEwNTRmYzI4YjlmMDEwMjAxNDEyODA2MDEw YTJhMDcwNzBhMDEwMTAxMDEwNzAxMDE3OTU5MDAwMDM5N2VhYzAxMDEwMThlMDIwMTUwMWU1NjFj ZmEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDMwMTAxMDEwOTQy ODhjMzAwMWEzODE5MWMwMDAwMzYwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAN CjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAxODAwMDAwMDFhMWMxYWE0MDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDIwMjA5 MDkwOTUxMDAzYTNkOGUwMTAxMmE0MjVlMDBkMjAxMDEwMTAyMGIyYWI1MDAwMDAwMDA5MmE5ZTAw MTc5MjkwMTAxMGIwNzJhMDEwNDAxZTczNDVmNzkwYQ0KMDcyYjM0MWE0YWNiZmMwMTAxMGIwMTAx MGEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwNDAxMDEwMTAxMDFjZDAwMWEzN2QzMDEyYTAxNjcwMDk2MDENCjA3MDIwMTAx MDEwMTJjMDEwMTAxMDUwMTAxMDUwOTAxMmE0MjAzMDEyY2Q0NTkwMGNiNTY2MTJiMDEwMTJhMDFm OTM3MDAxNTAyMDkwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDUw MjAxMDEwMTAxNDM2MmQ3MDAwMDAwMTgzOTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxYjAwMTgwMDE4YzYwYzAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxDQow MjAyMDIwMjA5MDkwMTY1MDAzNzdjMDEwMTAxMDk5ZDFjNmY5ZjI4MDEwMTAxMDM0MjgwY2U0OTMz ODU0MTA4MjgwMTAxMDQwMTBhMDEwMTAxMmMwNzAxYTExYmYyMDIwMTAxOTUwMDU2MDBjZDAxMDEy OTAxMDEwNjAxMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDEwYTAxMDIwNjA0NGIwMDAwNGEwNTAxN2EyODE4NGFlNzA4MDEw MTA3MDE0MjI4MDEwMTAzMGIwMjAxMDEwYTUwMDENCjAxMDEwMTA1MDQwMTI3ZjQ3NTM1NGYwMTA2 MDIwYjA1M2I4YjAwNjIwNTA3MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAy MDIwMTAzMDEwNTA2MGEwMTAxMDQzMmUyMDAwMDFjMzYwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDFiMzMwMDAwY2FjYTAxMDcwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjA4NDEwMDM4ZmYyODI4MDEwNzBjDQo5OTM2MzEwMTAxMGEyYzAxMDEw MThlMjUwMTA3ODgwMTAxMGEwYzAyMDMwMTI4MDUwMTBiMDEwMmRkMWI1NTA1MDEwYzAxNDkxYjAw MzQyODA4MDEwOTA3MDEwNzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDYwNDAzMGEzZjAwMTkxY2FmMDIwMTAxZDMzYTZk MDcwMjAxNDIwMjAxMGEwMTAxMDQwNjAxMDEyOTJiMDEwMTAxMDQyOTA1MDcwMTBhOTQ4MDhmMjUw MTBhMDEwMzAxNWMNCjAwMDBhMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjA0MDMwMTAxMDUwOTQxMGEwMTQyDQowYzMzMzkwMDAwMWEwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDBjNjAxMDEwMjAy MDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIyODAxMjIwMDU2YzMwMTQxMDEwMTY5MDAxOThmMDEwNDAx MDcwNjAxMDkwMTg4MDQwNDAxDQowNTAxMDE2ODU0ZDMwMTA1MGIwOTAxMjkwMTY1MDA2ODI4Mjkw NzhhMDAxYTAwZmEwMTAxMDYwNjAxMGEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDMwMQ0KMDMwMTA5YTUxODAwNGE4MTBhMDcw MWI1OTJkNDAyMDEwMTA2MDkwMjAxNjEwNzAxMDU4ZTA5MDEwMTAxMjkwNDAyMDEwMTA4MDEwNGY1 MzZhZjAxMDEwMTI5MDFhZDAwMTg5YTBhMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwYjA5MDEwMTA5MDEwMTAxMDEwMTAxMDAwMDFjMWMxYzAwMDAwMDAwMDAw MDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDkyMDAzNjE4YzUw MTJhMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwOTA5MDIwMjAyMDIwMTAxMDE4ODAxNzUxYjAwZWIwMTA2MjkwMTc1MTg1 ZDA2MDEwOTBiMDEyNzAxMGEwMTAxMDIwMTQyMDgwMTg5YmE1ZjI4MGEwMTAxMmIwMTAxNDMxYzFk DQowMTAxMDlmZTAwMWEwMDYwMDEyODAyMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxNjMzYTE5MDA3NDA5 MDEwOTk0MDBmNzAxMDU0Mg0KMDEwMTAxMjg2OTAwODQ2YTAxMDEwNDA2MmEwNDAxMDM0MjAyMDEy YTAxNmIwMDU1ZWMwMTI4MDkwMzAxYjIxYTM5ODkyODAxNGYwMzAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTBiMDI4ODAyMDEwNTA0MGMwOTQ5MDAwMDM2MDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDQ5 OGM3OTAxMDcwMjI5MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjA5MDkNCjA5MDIwMjAxMDEwMTBhMDEwMmM2MDAzOGUxMDEwMTA0 MjhjODkwNDMyYTAxMmEwMTAxMDEwMTBjMDEyYTAxMDMwMTAxMDYyOTIyMDA4NjJiMDEwMTI5MDEy YTAxZjEwMGM4MDIwMTUwMzIxOTM3MTg4MTQyMDEwMTA2MDEwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA4MDEwNjllNDgw MDM4YjMwMzA3MDFiYjAwYWMyODAxMDEwMTJhMDEwMWMzOTIwMDM4NmY2NzQzMDEwMzAxNDIwMQ0K MDEyODAyMDEwOTIwMDAzMDAxMDUwMTAzMDFkYzQ4MDA5ODI5MDE0MjAxMDEwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjA5MDIyOTAxMGEwMTAxMDcwYTAxMDQzOTAwMTkw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAw MDAwMzkwMGEyMGIwNTAxMmIwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwOTA5MDkwMjAyMDEwMTAxMDcwMTA3MDYzMjAwMTk0 MDAxMmENCjAxMDQwMzAxMDEwOTAxMDEwMzJhMDEwMTI5MDEwMjAxMDUwNDAxMDJjNDAwOWUwMTAz ODgwMTAxMDEwN2Q2MTg2ZTAxMjgwMWRlMDAwMDM2YWIwMTAxMDEyODAxMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDAwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwYzAx MGIzNTM3MDBjNzI4MjkwMTUwNDkzNDJhMDQwMTAyMGEwYTAxMDEwODQzZGIxYzAwMDAzNWMzODcw MTA5MjkwMTI5MDEwMWZkNTYzYWM2MGEwMTA1MDQwMTZkMWIwMA0KYjYwNDAyMDQwMzAxMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDENCjI5 Yzg4MjAwMzgxYjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDM2MDA0YTAw MDA5MjAwMDBlZGE4MGEwYTAxMDEwNTAxMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAzMDMwMzAx ZDgwMDAwZTEwMTAxMDEwNzAxMDFjNDc4YTYwODQyMDgwNjAxMjkwMTJjMDENCjAxMGMwMThlN2Y1 NTQzMDgwMTAxMGEwYTAyMDEwYjVmYTk0MjA2MmMwMWNiMDAxY2NiNDEwMzQxMDEwNDAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowNjJmNDkwMDFjMzAwNjAxMDE1MjE4YzEwNjAxMDIwMTA5MDMwMTAxMDkyOTA2ZWJjZjhi MDAzYTFkYTUyNDAxMDUwMTI5MDE1ZDM5N2UwMTA2MDEwNjAxODE1NjAwNTdiZjAxMDEwMzAxMDEw MjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw NTAxMDEwNmRjMzkxYjAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwNDg0OTAwMDAwMDAwN2IyNzAxMDQwMTAxMGEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw NDAxMDUwMTA1OTMxYzNhODEwYTA4MDEwNTAxOWQwMDAwMTkwMDU1ZDE2NTE1YTU1MWVhN2JmZDI4 ZDEwMDczMjkwOTAxMDEwMzA5MDEwMjA2ZDINCjAwYWEwMTA1MDJlZDAwMDAxOGE3MGEwMTA2MDQw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDkwMTAzYjExODAwNDhkNjA1MDEwY2MyNGJlODAxMDEwMzAxDQowMTA5MDMwMTAxMDEw MTJhMDIwMWU1OTIwMDFjMDA1M2ZhMDEwMTg3NDkwMDI2MDEwMTAxMDMwMTY1MDAxY2E3MDIwMTAx MGEwMTAzMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDEwNTAxMDE0ZjFiMDAzOTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwNTUwMDAwMDAxYzFhNDkwNzc5MDEwMTA1MDEwMTA1MDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDEwNTBhMDEwNWQ2MzcwMGU5NDIwMTAxMmEwMWZkYTVmNTk4NjYzNzAwMDBhOTAwMDAx YTAwNDcxYTAwNWI0MTAxMDEwMTAzMDkwMTAxMDMwMzg4MWE2ZjA3MDMwNTcyMzkwMDAwMjAwOTAx MDIwMTAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAzMDEyYzM1MWMwMDQ2MDgwOTA1MjQxYWQwMDEwMTAxMDkwMTAxMDkwYTA1 MDIwMTAxMDEwYjAxMDEwN2M4NmQwMDFiDQowMDU2OWNiZDAwZGYwMTJhMDEwNDAxNDAzNzM3YTU4 ODAxMDIwMjAzMDkwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAxMDcwNTA1YmUwMDAwMTgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAN CjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDM4DQoxYzAwMWIwMDAwMDMwMTAxMDMwNjAxMDEwMzAxMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMTI5MDEwMThlMDFmMzFjMDBhOA0KMDEwMjI5MDMwMTBhMDEwMTA1NTAyYjRm ODE3MGQzYTE3NjAwMzcxZjc5MDEwMTAyMDUwYTA5MDEwMTA5MDEwMWRmMzkyNDA1MDMwOGJjMDAw MGNhNDE3YTAxMGEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwNzAxZWEwMDFjMDA5ZDAxMDEwMTU4MzdmYTAxMDMwMTAxMDIw OTA5MDkwNDA1MDQwNTAxNDEyOTAxMjkyYTA5ODczMjE5ZDUwMDM3MDAwZjAxMDEwMzA1MDE4NTM4 MTkzZjAxDQowMTAxMDQwMTA0MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDMwNA0KMDEwMWU3MWMwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMTgwMDAwNGQ4MTg5YzYwMTAxMDEwNzBhMDEwMTA5MDEwMjAyDQow MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDQwMTAxMDEwMTA2ZDkzNzAwYzEwMTA3MDEwMTI5MDE0MjAxMDUw NzJhMDQwMjAxMDE0Zg0KNjAwMGQxMmMwODAyMDQwNTA0MDkwOTA5MDIwMTAyMDQ2YzM5YjIwMTAx MDQ0NDFiMDAzOTNmMmMwMTI5MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDENCjU3MWIxYjAwNGYwNTAxMDM1ZjM1N2EwMTA3 MDEwMTA0MDUwMTAxMDEwOTAzNzkwMTAxMDkwMTAxMDEwMTAxMDVlYmMxN2YwMGE0MDMwOTI4MDEw MWU3N2YwMGI0MDQwMTAzMDEwNTAxMDYwMTAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA0MDEwMTA5YWQzNjFjMDAwMDAwMDAwMDAwMDAwMDAw MDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA0ODY5MDEwMTJhMjgwMzA1MDMwMjAyMDkwMTAx MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDUwMTA0MDEwMTJjZGYwMDY2MGQwMTAzMDEwYTBi MDEwMTlmMDEwMTAxMjgwYTBhZmIwMDU0NzIwMTAxMDcwMzA5MDEwMTAxMDUwNDAxMDUwMQ0KNzk0 OTQ3MGIwMTAyZTgxODAwMDAzZDAxMjkwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAw MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTQzY2IxYTAwOTgwMTI5MDE1MTAwMTUw MTAyMDEwMTAyMDUNCjA1MDEwMTAxMDIwMTAxMDMwMTAyMDgwMTAxMDkwMTBiMDEwMWRjMjIyMzBi MDE5ZjAxMDM5MDFiMzg2YjAxMDEwYjAyMDkwMjA3MDkwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAyMDEwYmZkMWIxYjM3MDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDllMGEwYjA2MDEwYzAxMDkwMzAxMDEw NDA5MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMTI5MDkwNDlmMDEyYTcyMWIwMDc2MDE4 ODA2MDEwMTA0MDEwMTAxMjkwNjAxMDEzMTAwYmFlODAxMDMyOTAyMDEwMjAxMDEwMTA1MDUwMjA1 MDEwNWQwMDBhNzA1MDEwNTdlMDAwMGE5OGUwNjAxMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDU3ODAwMDAxYWY2MDEwMTA1 ZTEzOWUwMDIyODAxMGIwMTA0MDQwMTA5MGEwNDAxMGEwNDAxMDQwNGZlY2YyNmQ0MDENCjdhMDEw MTAxMjkwMTI4MDEyOTc5NmYwMDU3MDEyYTAxMDYwNDAxMDMwMTAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDkwNzAxMDFlNzFhMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDM5NGQNCjA3MDEwNzAxMDE0MjAy MDkwMTAxMDcwMjAxMDkwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA2MDEwMTAxMDE4ZTAxMDlmODRh DQoxODlmMDEwMTA5MDQwMTBhMDEwNzAzMDEyY2I3MDBjZTRmMDMwNjAxMDIwMTAxMDQwYTA5MDEw NDA0MDEwOTA0MDk2MTAwMTMwODAxMDFmYmE5MDAwMDk1MDEwNjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAyMDIwMTJjMDEwNTA0MDMwMTAyOWEzNjFjMWNj YzAxMDMyOTkyNmYyYzA4MDEwMTBiMDMwMTAxMDEwYzAxMjgwMTAxMDcwMThmYTQzODAwMDAzYTFl NGUwMTAxMjgwMTAzMDgwMTAxMzEwMDAwZGMwNjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA3DQowMTAxZTgz NzAwMzkwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDFiMDAwMDNhMDAxYjFiMDAxYWNmMDQwMTBiMDQw MTA0MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyODEwMDM4M2UwMTAxMDUwMTAxMmEwMTAxMmMwOTVkMDBjYmVjDQowOTAxMDEyYjAxMDYwMTA5 MDEwOTA5MDMwODAxMDE4ODA5N2EzNDQ5MjkwMTAyNzE0ODAwNDg1ZTA1MDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwNTAxMDYwMTA0MDEwYTAyNDMzMw0K MDAwMGI0MGEwMTAxMmYxYzc2MDEwMjAzMDkwMTAzMDUyYzAxMDEwMTA0MDIwNTAxOTQ1ZjAwMDAz YjRhMWIxYTU2ZTgwMTAxMmEwMzAxMDkyYzFkMDAxZDBhMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwNzAx MjhjNTE5MDAxYzAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxYjFhMDAzNjAwMWIxOTQ5MWNmYjQx MDEwYjA1MDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjJhOTkwMGNlMDYyODAxMDcwMTAxMmMwNDAxNWQwMDVmZmEwOTA1MDQwMTQyMDEw OTI4MDEwMTA4MDEwMTAxMDcwMTA5DQowMTA3NzYxY2UwMDUwYTA0NmUwMDAwNDlkNDAxMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDcwMTAxMDIwMzAxMDYw MWIzMDAwMDAwZTMwMTAzMDExNTFjYzUwMTAxMDMyOTAxMGIwMQ0KMDEwNTA4MDkwOTA5MGEyYzE1 MDA1YTg5NDIwNDc4NDkxY2I1MGEwYTA1MDEwNDA2MjQzYTM3YzAwMTBhMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDQwMTAxNDM1NjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAzOTAwMWMwMDFhMzY5 MzdiZGQwMTAxMDIwMTAxMjkwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMWU1MDAwMGRhMDIwMTBhMmIwMTAxMDE2YTAwNTU2MTA1MDEwOTAx MDEwNDAxMDQwMTBhMDcwMTI5MDUwNDJhMDcwMTAxMDFiZTFjMTQwYjA0MDE5ZDAwMDAxYmE2MDkw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAzMDMwMTA5 MDIwMTA3MDFkMDAwMzcxOTQwMDEwYTc5MzRjZTBhMDYwMTAxMjgwMTAxMDY4ZTAxMDEwNTBhMDEw MTJlMzc0ODJlMDEwMjAxMDEyZQ0KMTgwMGJmMjgwMTQxMDEwMTNjMDAxOTg4MjgwMTAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMTAzMDgwYmRjMDAwMDM4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDE5MDAxYTFh MDAxOTY1MDEwMQ0KMDkwYjA1MDEwMTBhMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA1NzkNCjU1MzlhNTAxMDUwMTAxMDEwMTExMzU4YjhjMDkw MTAxMDEwNzA2MDkwMjAxMDNkNGUzMTRiODBiMDQwMTBhMDEwNDA1MDExZDQ5N2EwNzAxYTgxOTFi MzcxNTA0MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyDQowMjAyMDIwMjAyMDIw MTBiMDEwMTAxMDIwMzA2OGIzODAwOTkyYTBiMDFlMDAwNWMwMzBhMDMwMTA0MDIwMjAxMDEwOTQy NDEwMTAxMjg1OTM5ZjUwMTAxMDEwYTAzMDkwMDQ4YmUwMTAzMDEwMTJiMDAwMDU3MDE4ZTAxMDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjA5MDINCjA2MDE4ODAwMzcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz OTAwMWExYjAwMDBhZjI4MDUwMTAxMDQwYTA5MDEwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIyOTA5YmIzOTAwNzkwNDA5MGI0MjI5N2YzODEz MDMwMTA5MDcNCjAxMDEwMTA0YTdmMjFkOTIwMDAwMzMwNjI5MGIwMTI4MDEwYTAyNWMwMGQ2MDUw YTAzNzQwMDAwY2EwYjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAy MDIwMjAxMGIwMzAxMDIwNDAxMjUwMDM4DQowMGMzMDEwMjAxYzMwMDI0MDMwMTAzMDMwMjAyMDFi ZjAxMDEwNTAxMDEyODJjYTQxYzNmMDEwNTA2MDEwMTgxMzkwMDYyMDIwNTAxMDQ5NTAwMDA3MjAy MDcwNTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwNjAxMDEwY2ZjM2ExOTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAN CjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMWIxYTFhMDAwMDAwMTYwMTAxMDEwMTAxMDMwYTAzMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwYmUwMDAwMGFlMDEwNDAxMDEy YzdjMTcwNjA5MDEwMTAxYzY5N2RmNmYwMDFjMDAwMGM3NGM2NDBkMDEwMTAxMmENCjAxMDEwNmQ2 MDA0NTAxMDUwMTQ1MDAwMDAwYTIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIw MjAyMDIwMjAyMDIwMTAzMDUwMTAzMDIwMjQ1MDAwMDM5ZDkwMTAxMmM2NjhiMGIwYTAxMDEwMzAy MDEwNDZlDQo0Yzg3MDEwMjJhMDEyNDAwMzUwNTAxMDE4ODAxMGJlMDAwZGIwNDA1MDE4ZTA1NjAx YjM0MmEyYTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMzI5MjBlNjAwMWEzOTAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQow MDAwMDAwMDAwMDAxYTAwMzcwMDAwMzcwMDE1MDEwNjQyMGIwMjAxMDEwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEyYmQ3M2FiYzBi MDEwMWJmMDFlNzAxMDEwMmI5NTg1MzM4MWEzYTAwMTllNmYwYzgyYzA3MDEwNzAxMDgwMjAyMDEw MjA5NDE4NDdmMDcwOTA0M2Y1NjM4MDA1YjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDAwMjAyMDIwMjAyMDIwMjAyMDQwMTA1MDkwNTAxMDRhNDM3MDA0NzBjMDYwN2ZjMDA3ZTAxMDgw YTAxMDEwOTAxZWMxYTAwMDA0YjU5MTAwMTMwMDAxMzAxMmEwMTAxMDcwMTNjDQoxYmI3MDkwMTA3 MDE2MzAwMWM1YTAxMDEwNjA3MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMGIwMTM1MDA0ODAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDFjMDAzNzAwMDAxOTFjYmIwNTAxDQowMTAxMDMwYjAzMDEwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyNDIwMQ0KMjg1 YjFjMDBlYzAxMmEwMTA2MDY2NGQwMWIwMDFhMWMwMDQ3YzcxYTE2MDcwNTA3MDEwOTAxMDEwODAx MDcwMTA1MjgwMTAxZjEwMDcyMDIwOThlNWYwMDM3YjgwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMDAyMDINCjAyMDIwMjAyMDIwMjAxMDgwNDAxMDEwMWQ0MzgwMDE5ZjgyOTA5MDFmYjM2 NmE4ZTAxMDQwMTAxMDYwMWNjNzNjZTE4MDAwMDM5YzIzOGMyYTcwMTA5MDEwNzAxOGQ0NzAwODcw NTAxMDMwNGMzMDAzNTBlMDQwMTAzMDkwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNDAxMDEwYTAyMDEwMzA2MDgwMQ0KMDQwMDAwNDkxYzAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxYzAwMDAxOTAwMzkwMDFlMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA1 MDEwMWZlMDAxYTU4MDEwMTBhMjgwMTM1MDA5MjNhNzU3ZA0KYmUwOWEyMDBkNzA0MDMwMzAyMDEw MTAyMDIwMTAyMDUwMjAzMDMwMWM0MDBlNTAxMjkwMTMyMWIzNjAwODEwMTAxMDkwMTAxMDIwMTAy MDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDEwNjAyMDEwNDAzOGMwMDM4MDANCmIzMDEw MTAxOWEzOWZjMDMwMTBiMDIwMTA1MDEwMTAxMDRmYzUyZWYzNjAwMDAwMGZmY2QzZjQyMDEwNjc4 MzkxZDA0MDIwMTAxMDVhNDFjZjcwODA1MjgwMTA5MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMjgwNzA1MDMwMTAxMDEwMTAxMDEwMTNhMzkw MDAwNDgwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMWEwMDAwMDAwMDRhMDBjMzAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMTJhMDEyYjc1MzY4NDAxMmEwMTAxMDExNTQ4MWZiZjA1MjkyYTAyMjc4YjU1ZmMwMTAx MDEwMTAyMDkwMjAxMDIwOQ0KMDQwMTA0MDE4MTE5OTEwMTA2MDljNDAwMDAzODdjMDEwOTA1MDEw OTAxMDEwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAxMDkwMTAxMDUwNTE3MDAwMDAw MjcwMTAxMjgwMGI4MjkwMTAxMjgwMjAyMGEwMTAxMDUNCjAzMDEwMTA5YjZjMTdlNmYwMDAwMDA2 ZjlkNzFkYjAwYzEwMTBhMjkwMTJlMDAwMDlkMDEwMTA4MDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEwMjA5MjkyOTAyMDEwYTAy MDUwMDAwM2EwMDRhMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDM5MDAzYTAwM2EzOTAwMjEwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDEwNzAxMDFhNjAwMDA3MjBhMDEwNTI4N2MwMGUyMDEwMTAxMDEwMjA5YTUw MDIzMDEwMTAxMDEwMzAzMDEwMTAxMDEwNTAxMDUwYTAxYmExYjBiMDEwNDA4MWEwMDM5MjEwMQ0K MGEwNDAxMDUwMTAzMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwOTAxMDkwMjAxMGI0 NjAwMDBjNzI4MDMwMjNmMDAyMjAyMDEwMTA0MDEwMjA2MDkwMzAxMDEyOThlMDkwMTAzODhjNTk2 NTM1NjAwMDAxYTFjMDANCmM1MDIwOTJjMDE2ZDAwMDA0MzA2MDEwMTAxMDEwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwNjI5MDEwMTAxMDEw MTA3MDEwNzAxNmYwMDM4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDQ4MDAxYTAwNTVk YjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwNzAxDQowMTA0NzkwMDFiZGIwMTAxMDEwMzI5Y2IzYTRmMDgwYTAx MDcwMTY5MDA1MzA1MDEwMTAxMDMwOTAxMDEwMTAxMDIwMTA5MDgwMWQwMDBhNzAxMjgwNDMzMTkw MGQ3MDEwMTAxMDEwNjAxMDUwMjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjBh MDMwMWFkNTUzNzAwZTEwMTAxMDllZDFjMmUwMzAxMDIwMTAxMDEwNDAxMDUwNDAxMDEwMTAxMDEw NDAxMDEwMTA2ZWI4NjVlNGExYTY2MGIwNTAxMDE4ZTM4Mzg3ZTAxNDIwMTAxMDEwMzAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDIwMzA3 MGIwMzAxMDUwMTNlDQo0YzAwMDAwMDAwMzkwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDA4YjhjZDgwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDUwMTAxMDYwMTUzNTUwMGU4MGEwOTQyMDE5MTFiMjMw MTA3DQowMTBiMGI0MTAwMzc0MTBhMDEwMTA5MDEwMTAzMDIwOTAxMDYwMTI4MDE3ODAwMTMwMTA5 MGJkYjRhMDA5MjYyMDEwMTAxMDcwMjA0MDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIw MTAyMGEwNTAxNjgwMDAwMWJiZA0KMDEwMTA4OTgzODQzMDIwOTA5MDkwOTAxMDEwMTAxMDUwNTI4 ZGRjODBkMDQwMTA2MDUwYTAxMDE3YWEwY2ZmOTAzMDEwNzAxODIwMDFhNjgwMzAxMGEwNjAxMDUw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MTAxMDUwNDAxMDEwOTAxMDJiYzFiMDAzNjM3MWIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAx YzE5MDAxYTFhNWUwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMmEwMjAxMDVlYTE5MDAzZjAxMDEwNDAx OTAxYmYzMDEwNTAxMDE4ZTUwMDA0ODdhMGIwMTAxMDkwMTAxMDUwMzA1DQowMTI5MDEwOTI4OGQx Y2JjMDIwMTA5YzQwMDQ4MDA2YTAxMDQwMTAzMDQwMTAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAy MDIwMjAyMDEwOTA5MDQwMTE3MDAwMDE5YWMwMTAxNDMzM2E0MjgwMTA5MDIwMzA0MDEwMTJhMDc2 MQ0KNThiODM4MDBjYTMyYjJmZTAxMDE0MjAxMDE0MjAxMDIwMzAxNDIwYTU4MWMzODdhMDcwMTA5 MDcwMjA5MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMjgwMjBhMDEwNmE2N2VlMjc0MWIxYjM4MWEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAw MDAwMDAwMDAwMDAwMDAxYWQ3MDEwNzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA3MDIwMTA1NDExOTM3YjIy ODA5MGIwMTYzOTIwMDlmMDEwYTAxMDE4MTFjMDA5ZjBhMDEwMTA0MDEwMTA0MDEwMzAxMDcwMTAx MDUwOTY2NDg0ZjBhMjg4OTAwMDAwMDEzDQowOTA2MDEwMTBiMDEwMjAyMDIwMjAyMDIwMjAwMDIw MjAyMDIwMjAyMDIwMjAzMDkwMTA5MDNmNzM4MDA0YjAxMjkwOWZkMDAyMTAxMDkwMzAxMDIwOTAx MGFlYmI0NWYwMDAwMWIwMDAwMDAxODAwY2JmNDAxMDYwMTA0MDkwMQ0KMDcwMTAxMmM2MDAwNmYw YTAxMGMwMTAxMjgwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIN CjAyMDIwMjAyMDIwMjAxMDEyOTAxMDRhYTE5MDAwMDkyMDAwMDAwMDAwMDFhMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAxYjFiMzYwMDRhNTQ0MjAxMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjJjMDENCjAyMjgwMTA1 YzIxYjkxMDEwMTA2MDEwMWNlMzhhYTAxMDIwMzA3YmQzNzhiODgwOTAxMDIwYTAyMDEwMzAxMDEw NTAyMGEwOTAxMDllZDAwNDAwOTA3MDFjZTFhMWJlNjA5MDYwMTAxMDgwMTAyMDIwMjAyMDIwMjAy MDAwMjAyDQowMjAyMDIwMjAyMDIwNTAxMGEwMTRmOTIxYTM3OTkwMTA1MDY3MDAwYjMwMTAxMDQw MTI5MDEwMWU3YzIxYzAwYjEyM2EzNjgyZjIyOTM1ZjAwMzdkZjJhMDEwMjA5MDEwMjA5MDEyODAw NTYyMjA3MDEyODAxMDkwMTA1MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDMwMTAyZmMzZGQ3MDAxYjAwMDANCjAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQow MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDQ4MzkxYTAwMDAwMDM3MWExYzAwMDA3YmIzMDEwNTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA1MDEw NTA5MDE4YTM3MDAyYTAyMGEwMzBhZDkwMDAwYWYNCmRhNDRjOTE5MzdhMTA5MDIwMTAxMDEwMTAx MDEwOTA0MDEwMTAzMDEwMjA3NjgwMDllMDEwNzJhNmQwMDM5MzNiZjAzMDIwMTAyMDUwMjAyMDIw MjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjBhMDkwNzAxOGYzNjAwMDA5NjA5DQowMTA3ZjEzOWVi MDEwNTAxMDYwMTAxNDJhZjAwOGIxMDAxMDcwMTAxMGMwMTBjNjNhYjAwMWIxZTA3MDEwOTAxMDEw MzAxMmYwMDAwNjkwMTAzMDUwMTA2MDEwNTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDgwODExNDkzYTAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMWEwMDAwMWEzNzAwMDAwMDFhMDAzOTU2MDEwMTBhMDEwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDkwNDAzMDEwNDAxNmMxYzFiNzgwYTAxMGIwMjI5NTgxYTNhM2EwMDM5MWJmMzQxMDEwOTI5MDEw OTAxMGIyYzAzMDENCjBiMGEwNjAyMDUwMmM1MDBhNTBiMDEwMTIyMzkwMDE5MTAwMzA0MDIwMTAy MDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMTAxMmEwNzdkMDAxYTM4YzgyODAxN2Ez NzM0MDEwYTAxMDEwNjAxMDFkYTFjODRkNjAxDQowMWEwMDMwMTJhMDIwMTAxOGU5MDNhMTk2YTAy MDkwMTAxMDkwMWQwNDk0YWEwMDEwNjAxMDEyOTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxMDFkYTAwMDAwMDM3MDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAxYzAwDQowMDFiMWEzNzM3MDA5MjFjNmIxMDAxMDEwYzAxMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjA3MDIwNTAxMGEwMWEwMzMwMGU5MjkwMTAxMDEwMWJmZDNhNDU1MWQ5MWMwMDYwMTAx MDEwMTAxMDYwMTAxMDEwNTAxMDUwOTAxMDEwNzA1MGE0NzM1MGQwMjAxZDY0ODAwMDANCmU0MDEw NDBhMDEwMTAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMGIwODAxMDE1YjQ4MDAwMGVi MGEwMTk0MzczYzA5MDQwMTA0MDEwODAxM2QwMGMwMDE0MjA5MDEwNDAxMDEwMjA5MDYwMTI5MjAx YTk5MDEwNDAxDQowMzAxMjhkNTNhYjQwMTAxMDYwMTAxMDYwMTAxMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDMwMTUwZjQzOTFhMWMxYzAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDM4MzcwMDFjMTkxYjAwMWE0ZjAxODgwYjAxMGEwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDcwMQ0KMDkwMjBhMDEwMzliMDBiODQxMDMwMTA1MmEwMTAxMDEwMzAyMDQw MTAxYTAyOTA1MDEwMTAxMjgwNjA2MDQ3YTAxMGEwNzAxMDEwMTA5NmQ0YTg5MDcwMThkMWEzNzAw MjEwMTAxMGIwMTA0MDIwMjAyMDIwMjAyMDIwMDAyMDINCjAyMDIwMjAyMDIwMjAxMDQwMTJhMWQx YjFhYTQ0MTA0MDE2YzU2YWEwNjAxMDUyOTAxMGEwMTE4MWNjODJhMmEwMTAxMDQwMTAxMDYwMTJj MDEwMTg5MTkxYjI3MDMwMTA3MDE0MDAwMDBlNTAyMDkwOTAxMDQwMzAxMDMwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwYTdhNmQ2MDFhMDAx OTAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA0YTAwMDAzODAwMDBmMTI2MmMwMTA1MDEw MTQyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjA1MDEwMTI4MDEwMTBiNDQzOTAwZGMwMTJjMDUwMTA1MmEwMQ0K MDIwMTAxMDUwMjAxMDEyODAxMmMwNDI1YWUxNTE1YjEwMTA0MDQwMjAxMDcwNWFiMzY2OTA5MGEy OWNiMWMwMDc0MDkwMTBiMDEwNjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDUyODAx OWZhOTM4MDBiNDAxMDgNCjAxOWMwMDdiMDEwMTAxMDEwNzAxMDMwMDhiYTAwMTAxMDEwNzA1MDkw NDBhMDgwMTBiMDMwMTNiMTg4MjAyMDEwNzAzYzAwMDAwODkwNTAzMDEwMTBhMDkwMTA3MDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDQ4ZDAw MWEwMDAwMWExYzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzNzAwMzkwMDFiMzYwMGNiYjEwMTI5 MDEwNTBiMDIwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMzAxMDEyODAxMDEwODcxMDAwMGU1MDMwNTAxMDEw NzAxMjgwMTAxMDgwNjUwYjkzZjljODMxYzM5MDAzOTAwMDAzYQ0KMDcwMTAxMDQwMTA2MDEyMzAw NzMwMTI5MDNmNTAwMDAzNTYyMDEwYTAxMGEwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIw MjAxMDIwNTI1MDAwMDFiYTEwMTI4MDlkMTAwODkwMTA1MDEwMTJhMDkwMjFjOGI5ZjA4NDINCjAx MDEwMTA4MDkwMTA1MDE0MTA5MGI4NDFhNjgwMzAxMDMwNmY1MDBiYTJjMDIwNDAyMDkwOTAyMDUw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAzYTAwMDM2MzcwMDAwMzYwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDFjMDANCjM3MDAxYjFhMzNm YjZhMDEwNDAxMDEwNDAxMDcwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTAzMDEwOTAxMGEwYWE5MTliNDBj MDEwMTBhMDEwZGU3ZDgzMDZlODAxYTU1MDAwMDAwMDAwMGMyOTM2NWQzYzQwMTAxMjkyODAxMDEw MWZjMzlmNzAxMGIwMTIyMDAzNw0KMWE3MjAxMDMwNDAxMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAy MDIwMjAyMDIwMzA5MDIyZTAwMTkwMGQzMDYwMTAxOGI0NzBhMDEwNTQxMDEwMTQyMDEwMDAwZWMw MTAxMDcyYzAxMDEwNTA1MDE0MTAxMDEwNzFkMDA0MDBhMDENCjAxMjgzNDAwNmUwMjAxMGEwNjA1 MDEwMjA2MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAy MDIwMjAyMDIwNGNjMDAzNzAwM2EwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMzgwMDAw MDA3NTBiMGEwMTAxMDgwMTAxMGEwMTAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxDQoyODAxMmEwMzAxMGE4 MzM5NmYwMTA3MDgwMTAyMTMwMDFhMzYwMDFiMDA0YTNiNTc1ZGQ2MmU4ZTg4MDEwYTAyMDMwNDAx MDEwOTA1MDMyODg0MzUwOTA3MDFhMzFhNGEwMDY5MDEwMjBhMDEwMjAyMDIwMjAyMDIwMjAwMDIw Mg0KMDIwMjAyMDIwMjAyMGIwMTAxZTExOTM2MDBlODA0MDE2MjM2NTMwMTBhMDQwMTA3MDcwMzAx MTcwMDU3MDEwYTAyMDEwNTAxMGEwMjAxMmEwMTAxNDAxYzFjMDEwMTA1MDFkYTAwMDA5NTA0MDIw MjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjZlNzQ0OTAwMDAxYTFhMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDE5MDAwMDM2MDAwMDM4MDAx YzAwNDkwMGQ5YjYwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMmU1MTkwMGUwMDEwMTJhMDFmNjM5DQowMGQxNWE2NGQ4YmYwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAxNDFlNjQ5YmYwMTA2NzEwMDM3MDA1ODAxMDQwMTAxMDIwMjAyMDIwMjAy MDIwMDAyMDIwMjAyMDIwMjAyMDIwYTA0MDE5MTAwMWEzNjJjMDMwNw0KMGUxOWIyMDIwMzAxMDEy YTAxMDIwOGVjZDUzNzk1MDEwMzAxMGMwMTA5MDIyODAxMDEwMWE1OTIxNzAxMDEwNDA2YzAxYzFj YWMwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIN CjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDI5MjE5MDAwMDAwMWIxYjFhMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAzODAwMDAxYjFi MTgwMDAwMTkwMDAwY2E0MTA3MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDJiNjM5MDA4NjA1MDkwMzAzMGU0OGQxMjgwMTAxMDIwMTAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMTA5ZWQxYTUxMDMwMTQyMDAwMDFhM2QwMTA5MDcyYzAyMDIw MjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDEwOTAzY2IwMDAwZDcwMTAxMjhkMjM3ZTUwNTAy MDEwNjAxMDEwMTA2MDQ3NzAwMzhiMg0KNGYwNDAxMDQ1MDAxMDQwMTI4ZTFhOTU2ODcwMTA0MDEw YmUxMzkzYThlMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMDAwMWIxYTAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQow MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxYTM4MDAw MDAwMDA1NjAwMWJjMw0KNzA0ZGU0MDEwOTQyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDcxODAwMzAwNjA2MDEwYmRkMDAzYTJjMDMwNTBhMDMwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA5MDE3YzAwZjYwYTAxMDk5MTM4DQowMGMyMGEwODAx MDEwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAxMDEwNjFhMTgwMGY1MDEwMTAxZTEz OTEwMGIwMTA5MDQwMTA3MDEwMTBiMGI1YzAwOTI5MjkwOTZhZDBhOTQ0ZmQ4OTExOTAwNmMwMTBi MDUwMQ0KMDE0NjAwM2IwNTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjFhMWMxOTFjMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MzcwMDFiMDAwMDAwMDA1NTAwN2IwMjAxODgwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAxM2IwMDVlMDIwNTAxMDMwNmQ3MDA0ZTAzMDEyODAx MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxNzIwMDVhMDEwMTBiZjgwMDAwMWMw MTA5MDIwMTAyMDIwMjAyMDIwMjAyMDAwMjAyDQowMjAyMDIwMjAyMDIwMzA5ZTgwMDRhMDA1YzBh MDkwMTc1NTZlODA3MDEwNTAxMjkwMTA2MDEwMTAxMmM3ODM2MDAwMDNhMzYxYjM4MDAxYjAwNDk2 YzAxMDkwMjAxMGIwNzFiNGE1YjAzMmMwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMWMxYjAwMDAwMDAwMWEzNzAw MDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDFiMDAzNjAwMTkwMDAwZGIzZjQyMDEwMTAxMGEyODJjMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDFkZjAwNTUwMTAxMDMwMTA5YjENCjAwOGMw NzAxMDYwNDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwNzhkNDhmNTAxMDkwNzVi MDAxYzM3MGIwMTA5MjkwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDFkODAwMzkw MGRlMDEwYjAxDQpjYTQ3MGMwMTAxMDIwNTAxMjkwMTAzMDIwMjAxMmEwYmFhMWUxYjAwMDAwMDFj NDg5NmNjOGUwMTAxMDUwYzBiMDExODAwYjcyODAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjFhMDAwMDAwMDAx YjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw DQowMDAwMDAwMDAwMDAzOTAwMTgwMDAwMWM2ZmU0MDEwMTQxMGEwMTAxMDEwMTAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA1OWUzNzFhN2EwMTI4MDEwMTQ1 MDBmNjQyMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAxMGEwNmNhYjUw YTBhMDEyMzFjMWEwMGQ5MDMwMTAxMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMTAx NzAxYzAwMWI2YjAxMDcwMTFjZDcwYTAxMDIwMTI5MDE5ZjAxMDEyOTAxMDUwMTAxDQowMjQyMDFi ZmE3YTgwMzhlMGMwMTAxMDEwNzA5MDEwODUxMDA1NmI5MDEyYzAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIzNzFi MWExYTFhMWEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDFiMDAxYzAwMDBhNDlkNzIwMzA2DQowMTAxMDcwNzA3MDEwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMzBmMWEwMDBlMDEw OTA5MDY4NjFiMWUwYTAxMDkyOTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy YTQxYzA3MDQwMWQ5MDANCjM5MWI0NDAzMDEwNDAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIw MjAyMDQwMTVkM2EwMDAwYjYwYjAxMDQwMDkxMDIwMTI5MDEwMTQyMDEyODAxMDEwNzAxMDEwMTA4 MDEwNTAxMDEyODBiMDEwMzAxMDEyODAxMDcwNzAyDQo4MjAwMWEyNTAxMDEwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIw MjAyMDAwMDAwMDAwMDAwMWExYzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDM3MDAzODAwZTkwMTAxMDEwNjAxMDEwODAxMDEw NzAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDEyZDAw MzdkZTAxMDEwNTAxZTczNzAwNDEwMTA4MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDEwNGI4MDAwMTAyMGEyNTAwMzc0YTc2MDMwMTA1MDIwMjAyMDIwMjAyMDIwMDAyMDINCjAy MDIwMjAyMDIwMjAxMmJiYjM3MDA1NjAxMDMwMTdiMTg3ZDAzMGEwMTI4MDEyOTAxMDEwYjAxMGIw OTAxMDQwMjAxMGIwMTBiMDEwMjAyMDIwMjAyMDIwMjAyMDEwOWJiMDBjYjYyMDQwMTAyMDIwMjAy MDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIxYTAwMDAwMDAwMDAwMDFhMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDFiMWE2NTY5MmEwMTAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjI3NTUxY2JiMDkwMTAyMDUyYg0KNDk1NjRmMDEwNzA5MDEwYzAxMDQwNDAxMGIwMTA0MDYwMTAx MDIwODAxMDQwMTBiMDFmMjE4Njk0MjAxMDExYTE4MDA2ZTA2MDUwMTAyMDIwMjAyMDIwMjAyMDAw MjAyMDIwMjAyMDIwMjAyMDEwMTUzMWIwMDRhMDEwYTAxZjQNCjAwN2QwMTAxMDYwOTAxMDEwOTA5 MDEwNzJiZWQ3ODAxODdlYTAxNGYwMTA5MDIwMjAyMDIwMjAyMDIwMjA3MDE5YjM4M2IwNjAzMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMWEwMDAwMDAwMDAwMDAxYTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDM2MWExYTRhMGUwMzAxMjkw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDQwYjdmOTI3ZTBhMDMwMTA5MDY1OWUxODk0MTA2MDEwNjAxMDEwMTA5MDk0ZTNmMDEw MQ0KMjgwMzAxMDUwMTBiMDEwMjA5N2QwMDJmMDEwMzAxMWI0ODAwZTYwMTA3MDEwMjAyMDIwMjAy MDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAxMDZjNzAwMDA4MDAyMDQwMTRkMDA2ODAxMDEwODAxMmEy OTJhMDkwNzAxMjkwMDEzMmENCjNiNDhhMDAxNDIwMTAyMDIwMjAyMDIwMjAyMDIwYjAxY2UzNmJj MDEwOTA5MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjFhMDAwMDAwMDAwMDAwMWEwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDFiMDBiZTA0 MDIwMTAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAxMDFhNDE5ZTIwMTAxNDIwNTAxMjgwYjAxMDEwMTA5MDE3YTk3Mzk2NDAx OGI3NTI4MDEwNTAzMDEyOTAxMDEwOTAxMDUyMzAwYzAwMTA0MDVlZg0KMzgwMGJhMjkwMjAyMDIw MjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMzBkMTgwMDM5NDUwNjAxMDU2NTM3ZWIwYjA1 MDEwMTAxMDEwMTAxMjkyYTBiZmEwMGE3NmZhNjAxMDEwNDAxMDIwMjAyMDIwMjAyMDIwMjAxMjkN CjRhMDBlOTAxMDMwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIxYTAwMDAwMDAwMDAwMDFhMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDE4MDAw MDAwZmQwNTA2MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDI0MTAxNWM0ODE5NDMwMTAxMDcwNzAxMDEwYjA0MDQyYTAxMDE4 ZGNiYTRjNjkyZTQwMTg4MDEwNzAxMDEwMTBiMDQwMTAzZTgwMDIxMmEwMTA5NWExYzM3MzlkYzAx MGEwMjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAyMDQ1MDAwMDAxYmNkMDQwMTAyZjcz NzA4MmEwMTAxMDEwYjAxMGEyOWM1ODA3ZTZhMzBhZmVhYmZlNzhlMDEwMzAyMDIwMjAyMDIwMjAy MDIwMWVjMDAwMGM0MDQwNDAxMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjFhMDAwMDAwMDAwMDAwMWEwMDAwDQow MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAxYzFiNTc5MDUwMDEwNTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDE5ZDAwMTg4OTAxMjkwMTAxDQowMTBiMjgwMTAx MDEwYTI3MGMwYzUzZTk3Njk0OWRmYjAxMDQwYTI4MDEwMTAyMDEwNDJhMDBlNjJhMDEwMThhMzkw MDAwNGYwMTA1MDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwOTA5MDA1NjAwMTYwMTAy MDE2MA0KMDA0MzAxMDEyYzAxMDEwNTAxMDEwYzc1ZWQ1YzgwYTQ4MDFjMDAxNzBhMDkwMjAyMDIw MjAyMDIwMjAyMGE5NTAwMzdmYzA5MDQwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIxYTAwMDAwMDAwMDAwMDFh MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAw MDAwMDAwMDAwMDAzYTExMjkwYTAyMGEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIyOTAxODkwMDAwZjAwMjAxMDgwYTAxMDIw MTAxMmEwYTI5MTczOGJjNGNjZTdlZDUwMGMyDQo1MDAxMDEwMTA1MGEwMTAxMDc3OTAwZDEwMTAx MDFiMjM4MDAxYzAyMDMwMTAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDNkZDAwNDgw MGZiMDEwMTA5YjA5MjYyMDEwMTQxMDEwMTQyMGEwMTAxNDIwMWJkOTE3Nw0KMmRkZGVhZTcwZDAx MDIwMjAyMDIwMjAyMDIwMjA5MTIwMDM5NDMwMTA0MDkwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMWEwMDAwMDAw MDAwMDAxYTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAxYzAwNzgwMTAxMDEwNTA2MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwNWRkMDAxYWQzMDMwNzAx MDEwOTAxMDEwMzAxMDEwNzc2NTg3MzBlZTk2ZTBiMDEwNTAxMmEwNzAxMDkwMTAxMDEwM2EwNDg3 NTAzMDMwMTVkDQoxYTAwMWFjNjA0MDEwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjBh ZGUxYzAwMzdiOTJhMDE4OGM3ZDcwMTA4MDIwMTA0MDgwMTA1MDUwYjAxMTMxYzhmNmQ1ZjQzMDEw MTAxMDEwMjAyMDIwMjAyMDIwMjAyMDFhYg0KMTkxYmRkMDEwNDA5MDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjFh MDAwMDAwMDAwMDAwMWEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw DQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMGZhMDIwMzAzMDQwMTAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAxMDdhMDE4MDBi ZDA3MDEwMTA1MjgwMTA5MDUwMTI5MDEwYTBhYzgzNWFjYjg4NDcxMDEwYjAxMDEwMzBjMDEwOTI4 MDEwNWNhZTI5ZjAxMDk2ODAwM2EwMDg2MDEwNDAyMDIwMjAyMDIwMjAyMDAwMjAyDQowMjAyMDIw MjAyMDIwMTlkMzkwMDAwZDQyODAzYzYzNzgzMDEyODAxMDEwNDAxMDMwMTA3MGIwMTIxZTEwMmRh NDg5ZDA1MDkwMzA1MDEwMTAxMDEwMTAxMDYwNTAxN2QzNjAwMGQwMTI4MDEwMjAyMDIwMjAyMDIw MjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMzkwMDM5MzYwMDFiMWMwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMzkxYTAwMWExYzAwMDAzNjAwDQoxYzAwMzkwMDFjMDAzNjAw MDAxOTAwMzkzNjAwMDAwMDAwOTIxYTAwMDAzYTM4MDBiMzAxMDYwNzAxMDEwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwNjRm MDAzNjljMDEwNDAxMDYNCjAxMDQwMTA2MDYwMTAxMDEwMjMwMDAwZDQ0MzZhNjJjMDEwMTJjMDEw MTAxMDMwMTI5MDNmNTM3Y2MwMTA5ZWMwMDAwMTllNDAxMDEwMjAyMDIwMjAyMDIwMjAwMDIwMjAy MDIwMjAyMDIwMjA0OWUzNzAwMDBmZDA0MDFiZjAwDQpmMTAxMDEwMTAxMDcyYTAxMDEwMTAxMDEw NzA0MDcwMTEwOWYwMTAxMDQwMTA0MDUwNTBhMjkwNzAxMDEwNWIxMWJjNzQxMDEwMTAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjkyMDAxOTAwMDAxYzM5MzcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMWExYzM3MDAwMDAwMDAwMDAwMDAwMDAwMTk0 ODAwMDAxODM3MzkwMDAwMTkwMDU2DQowMDAwMWIzYTAwMDAwMDAwYTMwMTAxMDEwNDA3MDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjA5MDkwNmNhMWFlZTBhMDEwODAxMDEwNjAzMDEwMTg4MDMwNTAxNmJmNjAxNDJlYzg4MDENCjAz MDEwOTAxMDcwYTA1MDEwOTAxODMxOWFkMDMwOTk0MzgwMDAwZDIwNzAxMDIwMjAyMDIwMjAyMDIw MDAyMDIwMjAyMDIwMjAyMDIwMTllMWExYTAwYzgwMjAxOGUwMGYxMDIwMTAxMDQwMzAxMDEyODAx MDYyNzAxMDEwNTAxDQowMTAxMDQwMTBiMDEwNDAyMDEwMTAxMDkwMTI5MGFhNDAwZjMwNDA5MDEw OTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIxYjAwNDgwMDM3MTkwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMWMwMDAwMzgwMDAwMDAxYTAwNDgwMDE5 MzYxYjE5MDAxYjFjYjQ4MzQ1MTQwMDE5MDAxYzAwMDAxYzAwYjUzMDU5NTlhODAxMDIwMTA0MDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwOTAxMDFkMTAwYTQyODAxMDEwMTA0MDUyODAxMDEwMTA5MDkwNTA3MDQwYTAxMDEw MTAyMmEwMTAxMDEyOTAxMDMwMzAxMDFmMzM4NGYwOTAyMmQNCjM5MDAwMDc3MDYwMTAyMDIwMjAy MDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDExMjAwMDAwMGFjMDkwMWFkMDBkMDA1MDMwMzAzMDEw MTA5MjgwMTAxMDEwMjAxMDE0MjAxNDIwMjAxMDkwMzAxMDYwNTBiMGEwNTAxMDQwMWNlDQowMGY1 MDkwNzAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDA1NjAwMTkxYzM4MDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDM2MDAwMDFiMDAwMDM5MWIw MDM1MDAxYTFhMWE5MjFhMDAzM2I2MDEwMTc5MzYwMDAwMDAwMDFiMTkwMDFlMGIwYjdhMDMwMjA1 MDEwNDAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMDEwOTI4ODMzNzFkMDEwNTAxMDQwNzAxMDkwNzA5MDYwMTAxMDcwMTAx MDcwNzA3MDEwNTA0MDEwMjA0MjgwMTAxMDYwMTA1MzIxYzYyMDEwOWI2MDAwMDFiYWUwMzAxMDIw MjAyMDIwMjAyMDIwMDAyMDINCjAyMDIwMjAyMDIwMjAxNTkwMDAwMzg2MzA5MDIyZjFjNzMwMTA3 MDMwMjAxMGEwMTAyMGMwMTk0ZWM4NzYzOGZkNDQwYmViNmM1ZmU5NGM1MDEwMTAxMDQwMTI5MDFi YzAwNTMwMTA1MDQwMTAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDI5ZWFiMDAxODAwMDAwMDFiMDAwMA0KMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMWIwMDAwMDAwMDFi MzcwMDAwMTkNCjAwMWEwMDAwYjQ0NDlkYmQ0ZjA5ODU2NzAwNGEwMDAwMTkxYjAwMDAzZDAxMDEw MTAxMDUwMjAxMDcwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAyNDJhNTAwYTQwMTBiMDMwMQ0KMDEwMzBhMDQwMTA1MGEw MTAxMDkyODA0MDEwMTAxMDUwMTA0MDQwMTBhMDUwMTBiMDEwNzZkMDA4NzAxMDQ4OTRhMDAwMDhh MDUwMTAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMjlmMzAwMTkzNDlmMDEwMjllMWMN CmEzMDEwOTAxMDkwMzAxMDEwMzA1MDEwMDAwMzkwMDM5NGExYTFhMDA1NjAwMDA5MzBkMDEwMTAx MDEwMTI5NTMwMGY3MDEwMTA3MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDE3MTQ4M2EwMDAwMDAxYTAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMWMx YjAwMzcwMDAwMWIxYzAwM2ExYzM4MDAzMTAxMDEwMTBiMDE1NTAwMDAwMDAwMDANCjFhMWMwMDQ4 YjEyOTBiMDMwNTBhMDEwMTA1MDMwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDQwMTAzOWIwMGUyMDEwNDA2MDkwNTAxMDFkZDRm NzllOGEwNTBkZDk1NzdhYjc3ZmIyNg0KMDEwMjBhMDEwOTBhMDEwYTAxMDFmMjAwMjMyODA5OWZl MjFhMDBmMTI4MDkwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjA3ZWYwMDE5ZTIwMTA5 MDE5YzFjMjMwMTAyMDEwNDAzMDEwNjBhMDEwNDNhNDgzNTNhMzUNCjE4MDAzNjM2OGI0YTFjOTMw MjAxMDUwMjBiMDEyODk4MDBkMTAxMDEwOTA5MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQow MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyYWQxZmIyMTNiMDAw MzgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDM4MDAwMDQ4MDAwMDgwNTkxZmVkNDkxYzAwYzMwMTI4MDE1MDAxM2EwMDRhMDAxYjAwMDAx OTE5MTNlMzAxMDEwMTA5MDkwMTAyMDIwMTAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA0MDEwMWE1MDBlMjAxMDEwMTAxMDkw MTQxNWUwMDAwMDAxYTAwMzgxYjAwMDAxOTAwMWYwNjAxMDcwNDAxMDEwMTA5MDkwMWM0MDBmNjBh MDEwNQ0KODAxYTAwZmYwMTA1MDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMWUyMWMw MGNlMDEwNjAxZjYzOWIzMDIwNDAxMDMwMTAzMDEwMTAzMjkwYTAxMDYwMTA1MDkwMjAxMDEyOTAx MDA3ZjA5MDEwNDAxMmMwMTAxYjgNCjAwYTUwNDA0MDEwOTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMTAxMDkw MTAyZDIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAw MDAwMDAwMDAwMWEzNjAwMDA0YTAwMzZlZDAzMDEwMTc1MDAzNzczMDEwMTAxMDEwNTQ4MTgwMDE5 MDA1NTAwMDA5YTA4MDkwOTBhMDIwNTAxMDEwNzA5MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMTA0MDM5YjM4YjgwNzAx MDYwMTAyMGEwMTVhNTczZDIxYzkxYmNiNjVkMDNkMWU1NjE3MDUwMTA1MDkwMjAyMDEwMjI5MDQ2 MTAwNzYwMTAxMDRkNzAwM2FmZjAxMDYwMjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAy MDJiODAwMTljZTA5MDEwMjk2MDBmYTAyMDMwMTAxMDIwMTBhMDEwMTA1MDEwOTI4MDEwMTAxMDEw MTAxMDEwMTFjNTQwMzA0MDQwYTAxMDFlYmNiMzcyMjAxMDUwMTAxMDIwMjAyMDIwMjAyMDIwMjAy MDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAx MDIwMTAxMDhlYzdiZjA2YWE5DQowMDM5MDAxYjAwMWIwMDM4MDAzNjAwMDAwMDE4MWExYTFhMWEx YTFhMWExYTM4MDAwMDAwMzkwMGNiMDAwMDAwMDAwMDAwMDAwMDAwMTkwMDM5MDAwMDM5MDAwMDAw MWMxYmMxNjQ3Y2QzYjNjNGY5ZTVhMzZhODZkZTcyMjkwMQ0KNDJkNjMxMDBjMTBiMDEyODAzMDEx YjAwNTYwMDE5MDAwMDFiYjUwNTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEwOTUyMWIz NTlmMDYwMTAxDQowMTAxMDEyYzAxMjgwNDJhMDBkMTAxMDUwMjAxODRhNDI5MDEwMTBhMDMwMTA5 MDIwMTAzZjQwMDllMDIwMjAxNjYwMDFiZWYwMTAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIw MjAyMDIwMmI4MDAxOWNlMDkwMTAyOTYwMA0KZmEwMjAzMDEwMTAyMDQwNDAzMDMwMTI5MDEwMTA5 MDkwOTA5MDkwOTA5MDkwMDk5MDEwMTA5MDkwMjA1YzUxOTFhYWUwMTAxMDEwOTAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMTBhMGEwMTAxMDMwMzAxNTA3NTAwMDAzNzQ4MDAxYjU2MDAxYjAwMzYxOTE4MDAwMDAw DQowMDAwMDAwMDAwMDAzNzFhMWMwMDAwMDAwMDAwMzczNzM3MzczNzM3MzczNzAwMDAwMDAwMDAw MDM4MDAwMDAwNTZhMDAyMDQwMjA3MDMwMTA0MDQwMTA1MDcwMTAyMDIyYTA0ZTAzOTg1MDE0MjAx MDEwMTM1MzcwMDQ4MDAzOA0KMDAzN2M3MGEwMTI5MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA0 MDFlMzM2MDBjNTAxMDcwMTAyMGIwMTAxMjkwMTAxYzYxYzdlMGMwMTAxNDI5MzU1DQowYjA1MDcw MTAxMGEwOTAyMDEwM2Y0MDA5ZTAyMDIwMTY2MDAxYmVmMDEwMjAyMDIwMjAyMDIwMjAyMDAwMjAy MDIwMjAyMDIwMjAyMDJiODAwMTljZTA5MDEwMjk2MDBmYTAyMDMwMTAxMDIwOTA5MDIwNTA0MDQw OTA0MDEwMQ0KMDEwMTAxMDEwMTAxMDBlZjAyMDEwMzAyMDEwYWZjMDAwMDY4MDEwMTAxMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDEwOTA1MDIwMjBhMDUwMTAxOTc0NTMxOGE4YTEzNWQzMWMzOGE2ZDFiMDAx YzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzNzFhMWIwMDAwMTUzMTMxDQozMTMxMzEzMTMxMzE4YTUy M2VmMjg1OGFiNzlhMTkxOTAwMjgwYjA1MDEyYTAzMDEwMTAzMDkwMTAzMDYwNTAxMDIwMTJlMDBi YzQ0MGQwNzA4MmI0ODM2MDAzNzAwMDAwMGNkY2YwOTAxMDQwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDMwOTAxN2IzOTAwZWMwMTBiMDEyYTAxMDI1MDAxMjkwMTEwMTliYzAxMDEwNzAxNTQwMDAx MDEwODAxMDQwMjA5MDIwMTAzZjQwMDllMDIwMjAxDQo2NjAwMWJlZjAxMDIwMjAyMDIwMjAyMDIw MjAwMDIwMjAyMDIwMjAyMDIwMjAyYjgwMDE5Y2UwOTAxMDI5NjAwZmEwMjAzMDEwMTAyMDEwYTAx MDEwNzAxMGMwMTAzMDMwMzAzMDMwMzAzMDMzOWZmMDcyOTAxMGIwMTAzZGMwMA0KMDA4MjA2MDIw MjAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDINCjAyMDIwMjAyMDIwMjAzMDQwMTAxMDEwOTA3MGEwMTBiMDEwMTA5MDEwNzAxMGEwMTAx YzU5MjAwMDAxYzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxOTM5MDA0ODJmMDIwMjAyMDIwMjAyMDIw MjBhMDEwNTAxMDcwMTQyYjcxYjAwDQowMDBkMDcwMTAxMDEwMTAyMDEwMTAyMDEwMTA3MDcwMTAy NDIyNjAwMWEzNmE2MDUwMTAxNWYwMDFhMDAzNjAwMzk4ZTAzMDE0MjAxMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAzMDEwMzk1MDA0ODgxMDMwYTAxMDEyYzAxMDEyODA0NTE4MDAwODA1MDI4MDE1 MDg0MWMwMzAxMDQwYTBhMDEwOTAyMDEwM2Y0MDA5ZTAyMDIwMTY2MDAxYmVmMDEwMjAyMDIwMjAy MDIwMjAyMDAwMjAyDQowMjAyMDIwMjAyMDIwMmI4MDAxOWNlMDkwMTAyOTYwMGZhMDIwMzAxMDEw MjAxMDYwNDAxMDkwZjdiMmU2YjZiNmI2YjZiNmI2YjZiMzdmZjAxMDEwMTJhMDEwM2RjMDAwMDgy MDYwMjAyMDEwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMzA0MDIwMTAxMDEwMTA0MDINCjAxMDMwMTAxMDIw OTI4MDQyY2ViYzk2ZGRmYTU4MzgzODM4MzgzODM4MzgzYzljOWI0YTVmOGE1NjBlYzAxMDEwMTAx MDEwMTAxMDEwYTAxMjgwMTA5MDEwMmEzZjg1NmNiOGNhOGQ4ZDkwMjAxMDYwNzAzMDUwNDAxMDkw MTA5DQoyYTA0YTIzOTAwMDA4NjAxNzIzZjNhMDAxODAwMDAwMDM3MDMwMTAxMDcwMTAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDMwMTAzOTUwMDQ4ODEwMzAxMDkNCjQxMDEwNTBhMDFiZDM5M2E0NzAw NjMwMTAxMmQzYWY4MjkwNjAxMDEwMTAyMDkwMjAxMDNmNDAwOWUwMjAyMDE2NjAwMWJlZjAxMDIw MjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyYjgwMDE5Y2UwOTAxMDI5NjAwDQpmYTAy MDMwMTAxMDIwMjAxMGEwMTJjMzc1NjFiMDAwMDAwMDAwMDAwMDAwMDAwZTIwNjA1MGIwYTAxMDFm YzAwMDA2ODAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEwOTA1MDcwNjA2MDcwMTAzMDQwMTAx MDUwNTAxMDEwNTAxMDEwYzA5MDEyOTAyMDINCjAyMDIwMjAyMDIwMjA1MDEwMTA4MDEwMTg4MDEw MzAzMDMwMzAzMDMwMzAzMDEwMzBiMDEwMTI4MDEyOTAxZGYwMDAwMWMxYTgzMDIwMTAyMDIwMTAx MDMwMjAxMDkwMjA5MDFkNjFhMzczODZjMmNiMDM2MDAxYTFiMDAwMDE5DQowMDI5MGEwMjA1MDkw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAzMDkwMTdiMzkwMGVjMDEwMTA1MDEwYjAxZGE3ZTAwMDA1 YjZjMDBjZWFhMGYzMjAwOTYNCjAxMDMwOTAxMDEwYjA5MDIwMTAzZjQwMDllMDIwMjAxNjYwMDFi ZWYwMTAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMmI4MDAxOWNlMDkwMTAyOTYw MGZhMDIwMzAxMDEwMjA5MDEwNDAxNDE2NmI1NWZiNWI1DQpiNWI1YjViNWI1YjUxYThiZTQ5ZDEy MmEwMjAxYzUxOTFhYWUwMTAxMDEwOTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNzAzMDEwMTAxMDEwMTA5MDcy OTA5MDEwMTA2MDEwMTAzMGIwMzA2MDEwNDAxMDMwOTA5MDkwOTA5MDkwOTA5MGEwMTAxMjgwMTAx MDM1MDAyMDINCjAyMDIwMjAyMDIwMjAxMDYwYTAxMDc0MjAxMDEwN2IwMzkwMDM5MDA1ZmJkOGQw MzAxMDQwMTAyMDUwMTA1MDEwMTA5ZjQwMDAwMDA2ZGFiNmYwMDFjMWEwMDM4MDAzOTAwMDEwMTAx MjgwMTAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA0MDFlMzM2MDBjNTAxMDEwMTAyMDEwMzc1 MDAxYWZiNDIwMWYxMDAwMDM3MDA1NGFjMDEwMTBhMDIwMTA0MDkwMjAxMDNmNDAwOWUwMjAyMDEN CjY2MDAxYmVmMDEwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDJiODAwMTljZTA5 MDEwMjk2MDBmYTAyMDMwMTAxMDIwMjA5MDUwNTAxMDE1MDAxMDEwMTAxMDEwMTAxMDEwMTM4MDAz NzAwMDA0MzA2MDJlYmNiDQozNzIyMDEwNTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAzMGEwNTA5 MDEwMTAxMDIwMTAyMGIwMTAxNDIwMjAxMGEwMTA5MDEwODAxMDIwMjAyMDIwMjAyMDIwMjAxMjgw MTAyMDEyYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDYwNTAxMDQwMjAxMDkyOTAxNjANCjE5MDAwMDQ4 MDAzOGE4MDUwMTA2MDEwMTAzMDEwMTA1MDcwMWQ5MWIzNzAwMzkwMDFiNGEwMDM3MzgwMDAwM2Ex YjI4MmEwMTA0MDUwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDEwMTA5NTIxYjM1OWYwNjA3MDEw MTJjMDE2NmM3NDMwMTAyMDE4ZWUzZjFiOGI3YWQwMTBiMDEwNjAxMDMwMTA5MDIwMTAzZjQwMDll MDIwMjAxNjYwMDFiZWYwMTAyMDIwMjAyMDIwMjAyMDIwMDAyMDINCjAyMDIwMjAyMDIwMjAxZmYw MDAwYTQwMTJjMDFmNjM5YjMwMjA0MDEwMzAxMDIwMWEwMDEwMTA2MDEwMTAzMmEwMTAxMDYwMTAx MDZlMDhjYWM2MTIzMDkyODA0MDFiODAwYTUwNDA0MDEwOTAyMDIwMjAyMDIwMjAyMDIwMjAyDQow MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxNDEwMTAxMDEwMTA3MDMwNDgzMDAx YTAwMDAxYjM4MmUwMzAxMjgwMzAxMDUwOTAxMDINCjJhMDEyNDAwMDAzOTAwMDAwMDAwMDAwMDAw MDAxYjRhMWIwOTAxMDQwNDAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA0MDM5YjM4YjgwNzAx MDUwMQ0KMjgwMTAxZmEwMjAzMDEwODA5MGIwMTAxMjkwMTBiMDEwNTAzMDEwMjA1MDEwMTAyMDEw YjgyMDBmNjAxMDEwNGQ3MDAzYWZmMDEwNjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAy MDc1NDAwMzdiODAxMGEwMTljMWMNCjIzMDEwMjAxMDQwMzI4MDEwMTQxMDEwMTJjMjgwMTAxNDEw NjAxMjk0MTAxMDEwMzBhMDMwYzAxMGIwMTI4OTgwMGQxMDEwMTA5MDkwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA0MDEwNTBiMDEwNjAx MGIxZTM2MDAwMDRhMDAwMGM4MDkwMTBiMDIwMTBhMDEwMTAxMDEwMzBmNGExYzFhMDAwMDAwMDAw MDAwMDAwMDAwMDANCjAwMjkwMTAyMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDQwMTAxYTUw MGUyMDEwMTBhMDEwMTA5MDc4ZTAxMDEwNDBiMDEwMTg4MDMwMTQxMDEwMw0KMDMwNjAxMDkwNTAx MDcwMTAxMDlhNzFhYWEwNDAxMDU4MDFhMDBmZjAxMDUwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIw MjAyMDIwMjBiYjQwMDM3ZTIwNzAxMDQ5ZTFjYTMwMTA5MDEwOTAzMDIwNTAxMGIwMTBiMDEwMTBj YzgNCmQyYmRkMjc2Nzc2MjJhMDEyODAxMDEwMTAyMDEyOTUzMDBmNzAxMDEwNzAxMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMGEwMTAxMDYw MzAxMDkwMTAxZTYwMDAwMDA0YWUyYmQ0MzAxMDEwYTAxMDEwYTAxMDMyOTAxMDFkOTM5MDAwMDAw MDAwMDAwMDAwMDAwMDA1NjFhMzcwNjAxMDEwNDA5MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA0 MDEwMzliMDBlMjAxMDQwMTA3MDUwMTAzZjlhYWQyN2Q0MDgxOTRhZDcxMGIwMTAxMGMwMTA2MDIw NzA5MDEwNjAxMDEwOTExMWFjZjAzMDk5Zg0KZTIxYTAwZjEyODA5MDIwMjAyMDIwMjAyMDIwMDAy MDIwMjAyMDIwMjAyMDIwMWMzMDAwMGNiMGQwMTAzMmYxYzczMDEwNzAzMDIwMTAxMDYwYTAxMDY4 ODAxZGFmZjFjMzgxYTAwMzcwMGNiOWU0MTAxMGEwMjA5MDQwYTAxYmMNCjAwNTMwMTA1MDQwMTAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNTAx MDkwYTAxMDEwNTA0MDE5OA0KMzkxODAwMDA3ZTAyMmEwMTAxMDMwMTAyMDUwMTAxMDEwNDAxMjQw MDAwMTkwMDAwMDAwMDAwMDAwMDAwMDAwMDQ4OWYwMTAyMDMwMTAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIw MjAyMDIwMTAyNDJhNTAwYTQwMTBiMDEwMjBiMDE1MDU2MDAwMDAwMDAwMDFjNGE0N2IwOWE5ODVh MjkwMTAxMDEwMjBiMDEwMjAxMDY5MDAwNjkwMTA0ODk0YTAwMDA4YTA1MDEwMjAyMDIwMjAyMDIw MjAwMDIwMg0KMDIwMjAyMDIwMjAyMDFiZDFjMDAxYjk0MDEwMmFkMDBkMDA1MDMwMzAzMDEwYTAx MGIwMTA0MDFkYTU2MDA1NjkyMThlNjIwYmMwMDAwZDIwMTAxMGEwMTA2MDEwMWNlMDBmNTA5MDcw MTAxMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDEwMTAzMDEwMTBiMDYwOTI5ZTY0YTE5MDAwMGY3MDIwMTAxMDIwMjAxMDIwMzAxMDUwMQ0K MGIwYTY5MDAzYTAwMDAwMDAwMDAwMDAwMDAwMDAwNmU2NzA4MDEwOTAxMDkwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAxMDkyODgzMzcxZDAxMDUwYjAxDQowMTg4OWZiMjQ1ZTkxNDRiMDAwMDFiMDAw MDAwMDAxNDA5MDUwNTA1MDEwMTAxMGIwMTA2ZWUxYWU4MDQwOWI2MDAwMDFiYWUwMzAxMDIwMjAy MDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwOTcwMzYxYjAwMmQwNzAyOGUwMA0KZjEwMjAxMDEw NDAzMGIwMTAxNDIwMWViYmEwMGJkMDU5ZTFhYTYwMTAxZTMxYjRiMjUwYTAzMDEwNzAxMGFhNDAw ZjMwNDA5MDEwOTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjA1MDEwMTAxMDcyOTAxMDEwMTgzMDAwMDM4MzczMjAxMDEwMTAyMDEwMTAyMDIw MTBiMDkwYjAxMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwOTJiOQ0KMDgwMTA2MDkwMTBiMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwOTAxMDFkMTAwYTQyODAxMDYwMTAxMGEwNTAxMmEwMTAxMGEwNzAx MDFiMzNhMTgzNjMxDQowMTAxMDIwNDAxMDQwMTA4MDEwMWQxMzcyYzI4MDIyZDM5MDAwMDc3MDYw MTAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDVlNDM5MWExYWZjMmEwMWJmMDBmMTAx MDEwMTAxMDcwMTBhMDEyYTAxZTQwMGFiMDEwMQ0KYzAzNjBlMDgwODAxNGQzNzk2MGIwMTAxMDUw NzA1YjExYmM3NDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwNTA0MDEwMTA3MDEwMTgxZmVlNjAwMDAxYzAwZDEwMTAxMDkwMTAx MDMwMTAxMDQwMTA5MDFjYzcwMzkwMDM4MDAwMDAwMDAwMDAwMDAwMDAwZDQwMTA5MDcwOTAxMDEw MjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDkwOTA2Y2ExYWVlMGEwMTAxMDMyODAxMDcwMTBjMDEw OTAxMDEyNDMyMDAzNzVlMTAwYzAxMDEwYTA3MDkwMTAyMDcwMTAxYjQxYWEwMGEwOTk0DQozODAw MDBkMjA3MDEwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAxYmQwMDAwMDBjNTJjMDFj NjM3ODMwMTI4MDEwMTA0MDEyODAxMDUwOTIxNGE2MzA1MDE3OTAwZmIwMTI4MDEyNTAwYzMwMTAy NDIwMTAyMDE3ZA0KMzYwMDBkMDEyODAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDMwYjAyMGIwMTBjNzMxYTAwDQozNzM5MDAwMDU3NDEw OTA0MDEwMTA0MDEwMTBhMDQwMTI5NmUxYTAwMTkwMDAwMDAwMDAwMDAwMDAwMDAzN2ZjMDMwNzAx MDQ0MjAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAxMDY0ZjAwMzY5YzAxMDQwNzAxMmMwMTAx MmEwMTA1MDVlN2VlMDAxODgzNjkwMTA1MDEwNjBhMDEwMTAyMDQwMTAxMDQwMjZkMDBiZTAxMDll YzAwMDAxOWU0MDEwMTAyMDIwMjAyMDIwMjAyMDAwMjAyDQowMjAyMDIwMjAyMDIwYWRlMWMwMDM3 YjkyYTAxOGQ1NWQ1MDEwMzI4MDEwMzAxODgwMTAxMDZiYjNhMmQwNDAxODE0ODZlMDMwMTAxMGUz NzVhMDEyODAxMGEwMTAxYWIxOTFiZGQwMTA0MDkwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTJiMDEwMzA2YzVmOWQxMDAxOTE4MDAxYTFi NTMwMjAyMDIwMjAyMDIwMjAyMDIwNDcyDQo5ZGYzMDAwMDM2MWExYjFhMDAxYzAwMDAzOTAwMDBk NDQyMDEwMTAxMDUwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwN2EwMTgwMGJkMDcwMTAxMmEN CjAxMDEwMTA2MDE3MWFmY2IwMGYzZmUwOTAxMGIwMjA0MjgwMTAzMGEwMTBhMDkyODAxMDVjYWUy OWYwMTAyMjUwMDkyMDBlNDAxMjgwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAzZGQw MDQ4MDBmYjAxMDEwNzdlDQoxODYyMDQwMTAzMDQwOTA5MDEwNDA5OTAwMGZhMDMwMWQ0MzliMTAy MDEwOGRlMThjMzA3MDEwMTA2MDQwOTEyMDAzOTQzMDEwNDA5MDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDYwMTAxMDEwMTk1M2EwMDAwMDAw MDAwMWMwMGU2MDIwMTAxMDEwMTAxMDEwMTAxMDE1ZDM3MDAwMDkyOTIwMDFiMDAwMDFjMzcxYTM5 MDAxY2ViDQowNDAxMDkwMTA0MGEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDVkZDAwMWFkMzAz MDcwMTAxMDgyODAxNGUzMDM4MDAyMGFjMDQwMzBhMDIwMTAxMDENCjAxMDEyODAxMDEwNzAxMDEw M2EwNDg3NTAzMDMwYmFhMDAwMDE5Y2MwMTAxMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAy MDIwOTA5MDA1NjAwMTYwMTAyMDFmODAwMGQwMzAxMDUwOTAxMDEwMjA5MDFiOTkyYzcyNTAxDQo4 OTAwNjUwMTBjMjUxOTM2ZjAwNjAxMmEwMTAxMGE5NTAwMzdmYzA5MDQwMTAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjA5MDE0MTA1MDlhNjAw NTY1NjFhMzcxYTM5MDAzMjAxMDMwMzAzMDMwMzAzMDMwMzI4YjIwMDFhMzgwMDAwMDAxYzAwMDAx YjM4MzkwMDAwMDA2MzA0MDkwYjAxMDEwNzAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIyOTAxODkw MDAwZjAwMjAxOWYwMTAxMDFkMzQ3MDA0YWZhOWYwMTAxMmIwMTAzMGIwNzI4MDIwMTA5MDEwMTAy MDEwMTA3NzkwMGQxMDEwMTAzMTcNCjFjMDAzNjA0MDYwMTAyMDIwMjAyMDIwMjAyMDAwMjAyMDIw MjAyMDIwMjAyMDQ1MDAwMDAxYmNkMDQwMTAxYjgwMDAxMDMwNDAxMDEwMTA2MDQwMTAxMDI3ZDAw MWMxNTVkMWNmMTAzZGEzODAwY2Q4ODAxMDEyOTAxMDUwMWVjDQowMDAwYzQwNDA0MDEwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMjAxMDEw NDgyMDAzOTAwMDANCjAwMzcxYjAwZWUyODAxMDEwMTAxMDEwMTAxMDEwMTVkMTgwMDFjMDAwMDM2 MTkwMDAwMDAzNzFhMDAzODQ4NzIwNDAxMGIwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAy MDEwMTlkMDAxODg5MDEyOTAxMDgwMTAxYjIwMDAwMDAzYTM0YzIzNDgwMzE5ZTllMjI2MjA0MDYw MTAzMDEwOTAyMDEwNDJhMDBlNjJhMDEwMTNlMWMwMDFhMGQwNTAyMDIwMjAyMDIwMjAyMDIwMDAy MDINCjAyMDIwMjAyMDIwMjAzMGQxODAwMzk0NTA2MDEwYTliMDA3YTAzMGEwMTAxMDcwMTA5MDIw OTAxMDJjMWQ1MDAzYTAwMTk1MGRkMThjMTlmMDEwMTA4MDEwMTJhMDEyOTRhMDBlOTAxMDMwMTAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA5 MDYwMTAxMGFhNjAwMDAwMDAwMDAwMDAwMDBlMmQyNzA3MDcwNzA3MDcwNzA3MDc3ZTYNCjAwMDAx YjM4MzcwMDFjMDAxYjAwMDAwMDAwN2Y5Y2EwMDEwMTAxMDMwMjAxMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDI0MTAxNWM0ODE5NDMwMTAxMjkwNw0KMDE3YTNjY2JjNzNhMTgzOTU2MzYxODAwMDAwMDQ5 OGUwMTI5MDEwYjAxMGEwNDAxMDNlODAwMjEyYTAxMDliMjAwMDAxOGJlMDEwMTAyMDIwMjAyMDIw MjAyMDAwMjAyMDIwMjAyMDIwMjAyMDEwNmM3MDAwMDgwMDIwNDAxZjYNCjAwYzQwMzAxMDYwMTA2 MDEyOTI4MDE0MTAxMjg3MTY4MTc2NWUxMmEwMTQwNzkwMTA2MDUyOTAxMDQwMTBiMDFjZTM2YmMw MTA5MDkwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMTA1MDYwNjAxZjkzNzU1M2EzNjAwMDAwMDAwMDAxODM3MzczNzM3MzczNzM3MzcwMDFi MzkzOTM5MWMwMDAwMWEwMDM4MDAxYTFhMzdmMThlMDENCjA0MDEwMTAxMDMwYTAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDEwMWE0MTllMjAxMDE0MjA1MDEwOTAxMGIwNjAxMDFiZWRhZTA2YTdiODUx NzFmODUwMQ0KMDkwYjAxMmMwNTAxMDkwMTA1MjMwMGMwMDEwNDA5YjgxYjAwODQwODAzMDEwMjAy MDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAxMDE1MzFiMDA0YTAxMGEwMWIzMDA4YTA5MDEw YTAxMDEwMTA4MDUwMTI5MDYwMjAxMDENCjA2MjkwMTAxMGMwMTAxMDMwYjAxMDEwOTI5MDEwNzAx OWIzODNiMDYwMzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDEwMTA5Mjg2OTVjMDAwMDAwMDAwMDAwMzkxOTFjMDAwMDAwMDAwMDAwMDAw MDAwMWIxYTAwMDAwMDM5MWIxYjFhMDAzNjAwMWExYjFiZGYwMTAxMDYwYTAxMDEwMTAzMDIwMjAy MDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjA0MGI3ZjkyN2UwYTAzMDEwMzAxMGIwMzAxMDgwNTAxMDEwMjAx MDEwMTI5MjkwOTAzMDEyYzBhMDEwYTI5MDEwMTAyMDk3ZDAwMmYwMTAzMDEzNQ0KMzcwMDMyMDEw NTA1MDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMTJiYmIzNzAwNTYwMTAzMDFjMDM2 MTIwMjA0MDEwOTAyMjkwMTAxMmMwMTAxMDEwMTBjMDEwMTAxMjkwMTA0MGM3MmM1YWQwMzA5MDMw OTAxMDkNCmJiMDBjYjYyMDQwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIyOTAxMDNmZTAwMDAxOTAwMWExYg0KMzczODAwMDAxYjAwMDAwMDAw MDAwMDAwMDAwMDAwMWIxYTM5MzkwMDAwMzYxYzAwMzYwMDAwMDAwMDgzMDYwMjAxMDEwMTA3MDEw MTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjI3NTUxY2JiMDkwMTAyMDEwNDAzYzZmZWM4MDE0 MTA3MDEyODAxMGIwMTAxMDEwMTQxMDEwNDBjMDEwMTA3MDEwYjAxZjIxODY5NDIwMTA0OTIwMDAw YjEyOTAxMDQwMjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAyMGEyYzUyMzcxYTAwMTAw MTA1MDcwMGJjMDEwMTI5MDEwMjA5MDEwOTAyMDEwYjA5MDEwMTUwOGVmZTEyYjdkNzM0MTkwMGE2 MDEwMTAxMDMwNzAyODIwMDFhMjUwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMTAxMDQwMTA5MDEyODAxMDIwMTA5MjUxYjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAzNzAwMDAwMDE5MWE2ZTAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMmQwMDM3ZGUwMTAxMDUwNTI5DQowMWQ5 MDAwMDQ2NGJjMWNmYTI2MjAxMDMwMTA5MDMwMTA5MGEwMTAxMDkwMjAyMDEwNGI4MDAwMTAyMGFi NjAwMDAwMGFiMDQwMTA5MDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMTAxZjAxOTAw MzllYTAxMDcwMQ0KMWNhNDBhMDEwNDA5MDUwOTAzMDEwMzAxMDZmOWFhZjM0NzAwMDAwMDU2MDAw MDQ4OTE3YzA4MDQwNTAxMDEwODUxMDA1NmI5MDEyYzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMGEwMjAxMDEwNjAxMDEwMTAyMDEwOTI1MWIwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDM5MDAxOTAwMDAwMGU2MDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMzBmMWEwMDBlMDEwOTA5MDEw MTAxYTg5MTFiMzgzNjAwNTUzNzAwOTg4MzFmNjQ4NzJhDQowMTAxMDMwMTAxMDEwMjAyMDJhNDFj MDcwNDAxZTAwMDE5MzZhMzAxMDkwNzAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMGIw OTY5MDAwMDQ5ODYwMTA2MDEzYjQ3MGMwOTAxMDQwMTAxMmEwMTA4MDc0ZTFhMDAwMA0KMDAwMDFj MWM4NWUwNDMyYzAxMDEwMTAxMGEwMTBjMGIwMTE4MDBiNzI4MDEwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMTBhDQowMTAxMDMwMTAxMDUwMjAxMDkyNTFiMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMWEwMDAwMzcwMGMy MjFkZTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIN CjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDU5ZTM3MWE3YTAx MjgwMTQyMjgwYjAxMDEwOGI2NjljMTRhMDAzYTAwMWIxYzM3NmIwYzAxMDIwYTAxMDEwMTAxMGEw NmNhYjUwYTBhMDE2ODM4DQowMDAwN2IwNzAxMDEwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAy MDIwMjAzMDFlYjAwMDAxYjRjMDgwNDAxZjczYWU4MGEwMTAzMDEwOTA0MDEwNTAxNGZmMTc3ZTU5 NDJiZWUwMGQ0NTAwYzA0MDEwNTA3MDEwNzA3MDEwYg0KMDcxYjRhNWIwMzJjMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwNTA2MGEwMTAzMGEwMjAyMDEwOTI1MWIwMDAw MDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDFiMDAw MDAwMzdjZTBkMDYwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAxZGYw MDU1MDEwMTAzMDEwMTAxMDM0MjAyMDEwMjAyNjIwMGRiNDIyZTIzZDI5YTQzMDUwMTA3MDQwMTAx MDQwMTA3OGQ0OGY1MDEwOTA3ZWQwMDFiMWNlNzA5MDEwNjAyMDIwMjAyMDIwMjAyMDAwMjAyDQow MjAyMDIwMjAyMDIwMTAyMDIwMDE5MDBiYjBhMDEwOTIxMzkxMDA2MDEwMTI4MDQwMTAxMGIwMTAx NDEyYjAxMDEwMTc3MDBlYTAxMDEwMTA3MDIwOTA1MDEwMTA1MDEwMTQ2MDAzYjA1MDEwMjAyMDIw MjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjI4MDEwMTBhMDEwMzJhMDEwMjAxMDky NTFiMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAw MDAzNzAwMzYwMDAwYTkwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDEzYjAwNWUwMjA1MDEwMzJjMDQNCjAxMDcwYTAzMDEwNmM1MDBiMjAxMDEwNTAxMDEwMTAxMDIw NTAxMDEwNTAxMDEwMTcyMDA1YTAxMDEwYmY4MDAzNzM4MDEwOTAxMDUwMjAyMDIwMjAyMDIwMjAw MDIwMjAyMDIwMjAyMDIwMjAyMDgwMTM1MzcwMDgzMDEwMTA2DQpiZDM3NDQwYTAyMDEwMTA5MDEy ODA1MDUwODAxMDEyYTAxMDdlYTE4NGMwMjAxMDkyODAxMDIyOTAxMDUwNDAxMGJlMTM5M2E4ZTAx MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMzAxMGEwMTBhMDEwYjAx MDIwMTA5MjUxYjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDFiMDAxOTAwMDBjMjAxMDcwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjA3MTgwMDMwMDYwNjAxMGIwMTA1MDMwMzAxMDMwMTAzOTcxOTk3MDMwMTBhMjgwMTA5 MDENCjAxMDEwMTA1MGEwMTA5MDE3YzAwZjYwYTAxMDk5ODFiMDA0ODAzNDIwMTAxMDIwMjAyMDIw MjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMTAxMDFmMTAwMDBjMjlmMDEwNGEyMzllOTA5MDMwMTAx MDEwODAyMDEwMTA1MDYyODAxDQowMTBiMDhkNWNlMDEwMTA2MDEwNDBhMDEwMTQyMDEwNDA2YzAx YzFjYWMwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxNjgNCmE2MDEw YjAxMDQwMzAyMDEwOTI1MWIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDM5NGI4NmFjMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDJiNjM5MDA4NjA1MDkwMzAzMGMwYTAxMDcwMTA4MDkwMTRjNDg4ZjBhMDgw MTAxMDQwYjAxMDEwMjAxMDIwMzAxMDEwOWVkMWE1MTAzMDE0MjFjMWMNCjAwZjEwMTA1MDMyOTAy MDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDMwMzA1YzMwMDFiMDBlODAzMDE0ZjM2NTMw MTAzMDEwNzAxMDcwMTA5MmMwMTA2MDEwNDJhMDEyODFiYmMyYzAzZWNkYTczZTQyYzAxMDEwMTA1 DQowMWRhMDAwMDk1MDQwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwYWM3 NDcwMzA3MDEwMTA0MDIwMTA5MjUxYjAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzODFhMTkxYzFhMDA1NzAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMg0KMDIwMjAyMDIwMjAyZTUxOTAwZTAwMTAxMmEwMTAxMDQyZWMxMGZjNjBiMDFlNjMz OGUwMTAxMDQwMTBhMDIwMTA5MmEwMjAxMDEwNzAxNDFlNjQ5YmYwMTA2NzEwMDM1MDBlOTA1MDEw NDAxMDIwMjAyMDIwMjAyMDIwMDAyMDINCjAyMDIwMjAyMDIwMjAzMDkwMjJlMDAxOTAwZDMwMTAy MDU0NzU1MmIwMTAxMDIwMjAyMDIwMjAyMDIwMjAzMDEwNDg5ZGQwMDNiZmYzNTAwMWM1Njk4MDQy OTAyMGEwMTAxMjgzNDAwNmUwMjAxMGEwNjA1MDEwMjA2MDEwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDQwMTI4MDEwMTAxMDQwMTA1MDEwNjA1MjkwMTAzMDEwMTAyMDYwMTBhMDkw MWNjZmQ1NjNhOTRkNDAxMDEwMzA3MDFlN2U1NTYwMDAwMTkwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDFhMWEwMDAwM2EwMDAwYTUwNTAxMDYwYzAxMDEy OTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAxMDEyODAxMmEwMzAxMGFmMTU1YzcwODAxMDEwYjAxMDEwNA0KN2UwMDFiMWFi NWQ3NDhhOTRlYzYwMTA1MDkwMjAyMDIwMjAyMDIwMjAyMDIwOTAxOGJjYjAxMDkyYTc4MDA0ODAw ZTAwMTAyMDcwMTAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDEwMjA1MjUwMDAwMWJh MTAxNDINCjAxZjUxY2ZkMDE0MjAyMDIwMjAyMDIwMjAyMDJhZTdmN2UzNzAwY2IwMDQ4MWM3ZmM3 ZTlhZTA4MDkwMTAzMDEwMzA2ZjUwMGJhMmMwMjA0MDIwOTA5MDIwNTAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMTAxMDYwNDAxMDEwYTA3MDEwOQ0KMDEwMTAxMDkwNzAxMGMwMzAx MGIwNzAxMGEzYzAwNTYwMDAwZjcyODUwMDEwMTJjODMzNjAwMzkzOTAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxYTFjMDAzNzAwMzYxZTAxMDENCjAx MDEwOTI4MDIwNDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMTAxMDMwMTA5MDEwYTBhNGIwMDZlMDcwMTAxMDMwOTI4MDliM2Ux OTljMjAwMDAxYzAwMWIzNTNiZmY0ZDBiMDIwMg0KMDIwMjAyMDIwMjAyMDkxMDAwMzIwNzAyMDFm YjAwMzcxYTcyMDEwMzA0MDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjA1MjgwMTlm YTkzODAwYjQwMjBhMDE2NzAwZWEwMTBhMDIwMjAyMDIwMjAyMDIwMjY1MDANCjAwNDgzOTU4NTJm ZTZiMDkwNTAxMGEwNDAyMDEwMjAxMDcwM2MwMDAwMDg5MDUwMzAxMDEwYTA5MDEwNzAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyNTAwNTAxMDEwYTA3MDIwMTAxMDkwOTA5MGIyYTAxMDEw MTAxMDMwNjAxMDFlYmM5MDA0OA0KMDBjYjZkMDEwYTA1MGIwMWE1MzcxODAwMWExYjAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzOTFhMDAwMDM2Zjc0 ZjAxMGEwMzAzMDMwMTA2MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDMwMTAxMjgwMTAxMDg3MTAwMDBjMDA5MDEwMTAxMGEw MTQyMDEyYzI5MDExMGE4Y2RjOTVmM2EwMDFjZWYyNzAyMDIwMjAyMDIwMjAyMDIwMWY0MWJhYjBi MjgwMTkxMDAwMA0KMzU0ZjAxMGEwMTA1MDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIw MTA0MDEyYTFkMWIxYWE0MmMwMTAxYWUwMGFiMGEwMTAyMDIwMjAyMDIwMjAyMDI3ODJmNTEyYTAx MmEyYTJhMDUwMTAxMDMwNjAxNDIwNjAzMDENCjA3MDE0MDAwMDBlNTAyMDkwOTAxMDQwMzAxMDMw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDMwNDAxMDEwMTAzMDgyYTBiMDMwMTA1 MDEwMTA5MDQyODUwMDEwYTcyNmYwMDFiMDA2ZjAzMmIwNTAxMDIyODAxNjAwMDM2MDAwMDAwMDAw MA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxOTAwMDAwMDFh MWEwMDQ5ZDVmYzAyMDQwMTBiMDIwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNTAxDQowMTI4MDEwMTBiNDQwMDM5ODcwMjA0 MDMwMTA0MDQwMTAzMDEwMThlMjgwMTAxMDEwMTAxYjlhN2FhMDEwMjAyMDIwMjAyMDIwMjAyMmI5 ZTFhMTEwMTAxMGI4NDE5MDBiODA0MDEyODAxMGEwMjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAy MDIwMjAyMGIwODAxMDE1YjQ4MDAwMDQzMDEwMTRlM2FkYjA1MDEwMjAyMDIwMjAyMDIwMjAyNDEw MTAxMDIwMTAxMDEwMTAxOWYwMTAxMDMwMjAxMDEwNDAxMDMwMTI4ZDUzYWI0MDEwMTA2MDEwMTA2 MDEwMTAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMTBhMDQyY2EyYTg3MjYyMDEw MTA3MDEwNjAxMGIwNjcxYjYwMTAxMDU0MDAwMzgwMGY3ZjUwNzAzMDEwYzI1YWMyZTUzMDAxYjFj MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMTkw MDAwMDAxYTFhMDA0OWI4ZTcwMTA5MDEwNzAzMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIN CjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDcwMTA5MDIwYTAxMDM5YjM3ZDc4 ODAyMDIwNTA5MDEwNDA0DQowOTQxMDkwMTAxMDkwNjAxOWYwMTI4MDcwMzAxMDIwMjAyMDIwMjAy MDIwMjAxMTUxOWVjMDEwM2ZjMzczOTAwMTUwMTAxMjgwMTAzMDIwMjAyMDIwMjAyMDIwMDAyMDIw MjAyMDIwMjAyMDIwMTAxMmEwNzdkMDAxYTM4NjMyYQ0KMDE0MTU1Y2EwMjAzMDIwMjAyMDIwMjAy MDIwMjAxMmE3MTAxN2EyYzAxMDcwNTAxMDEwMTA3MmEwMWJmMDkwMTAxMDkwMWQwNDk0YWEwMDEw NjAxMDEyOTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjI5MDEwMTJkY2IwMDRh ZjIwNDAzDQoyYjAxMDEwMTA2MDFmMzE4Y2MwYTAxODEwMDAwMzg3MTAxMDEyYTAxZDMwMDAwMTkz NjAwMDAxYzE5MTgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMzkxYTAwMDAzNmY3MDQwMQ0KMDcwNjAzMDEwMTI5MDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA3MDIwNTAxMGEwMWEw MzMwMGU5MGEwMjAxMDEwNDAxMDEwNTI4OTU3NjEwMDcwZDhlMDMwMTAxMDQwMTAxMDcwMjAyDQow MjAyMDIwMjAyMDIwMTFiNDg5ZjAxMDFiNjM1MDAwMGU0MDEwNDA3MDEwMTAyMDIwMjAyMDIwMjAy MDAwMjAyMDIwMjAyMDIwMjAyMGEwOTA3MDE4ZjM2MDAwMGU0MDYwOTAzMzIwMGU4MDEwMjAyMDIw MjAyMDIwMjAyMmNjZg0KYzJhODAxMDEwMTA0MDUwMTJhMDcwMTAxMGEwMTA5MDEwMTAzMDEyZjAw MDA2OTAxMDMwNTAxMDYwMTA1MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxMDZm YzM5MDAxOGJkMjgwMTAxZTgyOTI3OGQyNzNjMWIwZDA0MDFlYzM5NDgxYzcxDQowNTA5MDU0MWYw MWIzNjAwMWIwMDAwMWEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAxYTFjMDAzNzAwMzYxZTAxMDUwMTAxMGEwYjAxMDEwMjAyMDIwMjAyMDIwMjAy MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwOTA0MDMw MTA0MDE2YzFjMDA4MjAxMDQwMTAxMDQwOTAxZWEzYjM4NDgzZTAxZGJjYWIxYmUwYTAxMDYyYjAx MDIwMjAyMDIwMjAyMDIwMjA4MDBiMTAxMDEyYzdkMDAwMDE5DQoxMDA5MDMwMTAxMDkwMjAyMDIw MjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjA1MDEwYTAxNGY5MjFhMzc0NjAxMDEwMTc3MDAxMTAx MDIwMjAyMDIwMjAyMDIwMjAxYzAwMDIyMDEwNTJjMDIwMTI5MDFiZjZhZWU1NDAzMDkwMQ0KMDIw OTAxMjgwMDU2MjIwNzAxMjgwMTA5MDEwNTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDkwMTI4YzYxYTAwMDBmNjBhMDExMDFjMzkwMDU2MDAwMDM4YWQwNTAxYmUwMDFhMDAwODI4MDFh MjM2MDAxYTAwMDAxYTFjMzcwMDFjMTkwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDFhMWEwMDAwM2EwMDAwYTUwNTAxMDEwYjAxMDE0MjAxMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAx MDUNCjAxMDUwOTAxOGEzNzE4YmYwMTBiMDYwMTA0MDU5ZjNhMTkzNGM5MmIwYjFjMWMwMGMyYzAw MTAzMDEwYTAyMDIwMjAyMDIwMjAyMDI2NDAwZDIwNTAxNDJkZjAwMzdjYjI3MDIwMTAxMDkwNzAy MDIwMjAyMDIwMjAyMDAwMjAyDQowMjAyMDIwMjAyMDIwMzA5MDEwOTAzZjczODAwNGIwMTI5MDlm ZDAwMjEwMTA1MDEwMjA1MDEwMTAzMDMwM2NjMzdiMTA2MDcwYjlmZWEzYzMzMDAwMDM3NTY3OTI5 MDEyYTA1MDMwMjVlNDg2ZjBhMDEwYzAxMDEyODAxMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIw MjAyMDIwMjAxMDEwNWFkMDAxYjAwNzYwMTI4Y2NiMTkxZGZlZjAwMDAxYWY5MTAwMTg3MWIxYjAw MmEwMTA0ZmQwMDFhMWIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMTkwMDAwNDhmNTkwMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIyYzAxMDIyODAxMDVjMjFiNTMyYTAxMGEwMTAyMjgwMTE2NTUNCjE1MDQwMTQyYjYxYTFm NTcwMDE4ZTAwMTAxMDEwMTAxMDEyODAxMDIwMTA0ZWQwMDQwMDkwNzAxY2UxYTFiZTYwOTA2MDEw MTA4MDEwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAxMDkwOTA0MDExNzAwMDAxOWFj DQowMTAxNDMzM2E0MjgwMjAxMDEwMTAxMDIwOTAzMDEwMTZmNTU3YmExNDYzODAwNTUzOTAwYmNh MTIzMDgwMTAxMDEwMTAxMDgxZjAwMzg3YTA3MDEwOTA3MDIwOTAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMGIwOTI5YzYzOTE4MWM3MDAxMDENCjAxMmEwMTAxNTIwMDAwMDAwMDVmN2Fj YzM4MzcwMDcxMGEyYWZlMDAxYjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDFhMWIwMDM3MDA0NzJiMDEwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDEwNzAyMDEwNTQxMTkzNzEzMjkwOTA1MDEwMTAxMDE1NTE5MmIwMTBiMDEx NjE4OGYwOTllMWM5YTJhMDEwMTAyMDINCjAxMDgwMTA5MGIwMjY2NDg0ZjBhMjg4OTAwMDAwMDEz MDkwNjAxMDEwYjAxMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMTAyMGEwNTAxNjgw MDAwMWJiZDAxMDEwODk4Mzg0MzAxMDQwMTAxMDkwNDAxMDkwYjAzDQo1YzAwNGEwMDAwNDdjYTY3 NzhkYzAxMGEwMTAxMDUwNjA5MDMwMTA5ZGEzNjFhNjgwMzAxMGEwNjAxMDUwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAxMDFiZTI1MDAwMDM3YjcwMjA0MDIwMTAxMDFhYTdmNWYzNzAw MTkwM2VjMWIwMDFjMGUNCjA0ODhmYTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxYjAwMDAwMDM2NDcwMTA2MDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAxMmEwMjAxMDVlYTE5MDBmNDAxMDQwNDAxMDEwNzUwMTg4MDA4 NDIwMjAxOTkxYzBkMDEwMTQ2YTliNjAxMDQwMzA5MDEyODAxMDQ0MTg4MWNiYzAyMDEwOWM0MDA0 ODAwNmENCjAxMDQwMTAzMDQwMTAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjBh MDMwMWFkNTUzNzAwZTEwMTAxMDllZDFjMmUwMTA3MDMwMTA0MDMwMTA5MDEyOTJmMTkwMDMwOTc4 OTAzMDEwNzA2MDEwYzAxN2EwMTAxDQowMTAyMGIwNmEwMDAzODdlMDE0MjAxMDEwMTAzMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMzI5MTkwMDE4NDkwMGMwMDkwNTA5MGEyYTAxMDcw MTY1MDAxYjAwMDFmYzQ4MWEwMDQ4MDAwMDM1MDA1NjAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMGNiMDAzNzFkMmEw MTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDUwMQ0KMDEwNjAxNTM1NTAwNzkwMTA5MDkwOTA1Mjg0 MzAwYTQwMTAxMDFlODQ4NmUwMTQyMDk1YjAwOTQwOTQyMDkwMTA0MDEwMTA2MDEyNDAwMTMwMTA5 MGJkYjRhMDA5MjYyMDEwMTAxMDcwMjA0MDIwMjAyMDIwMjAyMDIwMDAyMDINCjAyMDIwMjAyMDIw MjA5MDEwOTAyMDEwYjQ2MDAwMGM3MjgwMzAyM2YwMDIyMDEwMTAyMDIwMzAxMDEwMzAxMDE0ZjM4 OTEwMTA3MDEwYTI4MDEwMTAxMDYwMTAxMDYwMTAyMDhhODdhMDE5YjAwMDA0MzA2MDEwMTAxMDEw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDEwNjFhMWIwMDAwNDhjMTAxMGEwMTAx MDEwNzA5MDE1M2NiMDBjYjAxYWMwMDAwMDAzNzE4MDAxYjAwMWMwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAw MDBhNDA1MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA3MDEwMTA0NzkwMDFiZGIwMjAxMDEwMTAx MDEwMTJhMzU1Ng0KYjkwMTJhZjYwMGU0MDUwMTAxM2MwMGRjMDEwMTAxMDEyOTAxMDQyODAxMzEw MGE3MDEyODA0MzMxOTAwZDcwMTAxMDEwMTA2MDEwNTAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAy MDIwMjAyMDEwOTAxMDEwNTA1MTcwMDAwMDANCjI3MDEwMTI4MDBiODA4MDEwMTA0MDEwMTA5MDMw YjA5MDFmMTRhNjIwNDAzMDEwYjAxMDEwNTA5MDEwNTAzODE3ZDlhMDAxMzAzMmQwMDAwOWQwMTAx MDgwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMzAxOGRkNDFhYjEwYTI5MDcw Yw0KMDIwNTAxMDYwMzA1MDEwY2I1MDA1NTMzMDAzNTAwMDAzODM5MDAwMDFhMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMzMx YTAwY2IwMGM3MDE4ZTAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA3MDEwMWE2MDAwMDcyMDEw YTAxMDIwMTAzMDEwMjUyMDA1MzQzMDMyMTkyNDAwMTAxOGYwMGJiN2EwMTAxMDEwMQ0KMjgwMTBh MGIwMTU0MWIwYjAxMDQwODFhMDAzOTIxMDEwYTA0MDEwNTAxMDMwMjAyMDIwMjAyMDIwMjAwMDIw MjAyMDIwMjAyMDIwMjAxMDYwMjAxMDQwMzhjMDAzODAwYjMwMTAxMDE5YTM5MmQwMTAxMGIwMTAx MDYwMTAxMDgNCjA5ZDMwMGRlMDEwMTAxMDEwOTJhNDIwMTBkZTViYTM3MDAzODhiNzY4ODA0YTQx Y2Y3MDgwNTI4MDEwOTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyNDIwMTAxMmQwMGQw ODE0MTAxMDEwMTAzMDQwNjAxMDEwOTI5YjUzNTAwMzk0YTAwMzYwMA0KMDAxYzAwMzkzNzAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwOTlkMTAyMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIN CjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEyYTAxMmI3NTM2 ODQwMTAxMDYwMTBhMDEwYjAxMDQ0M2M3MDBjMjMyMzMzNzA2N2E4YzM0MzgyMzAxMGMyOTA5MDEw OTAxMDEwNDYzMTk5MTAxMDYwOWM0MDAwMDM4N2MwMQ0KMDkwNTAxMDkwMTAxMDIwMjAyMDIwMjAy MDIwMDAyMDIwMjAyMDIwMjAyMDIwMTA4MDQwMTAxMDFkNDM4MDAxOWY4MjkwOTAxZmIzNjhjMjgw MTJjMDEwMTI4MDEwYzAxMGE2YjQ5N2QwNTA0MDEwOTQxMDM3Y2JjNGExOTU2MDANCmJiNmE3YTI4 MDEwOWMzMDAzNTBlMDQwMTAzMDkwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxN2Ew MTcxMDAwMDkyOTAwNjAxMGIwMTBhMDEwOTA1MDEwOWI4MDA1NjAwMDA1NjFhMDAwMDE5MDAwMDM3 MWIwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAxOTAwMDAzNzJjMDUwMTA1MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNTAxDQow MWZlMDAxYTU4MDEwMTBiMDEwNzAxMDMwMTAxMDQ4ZDYwMDA1NTAwMDAzYjNiMDA1NWFmMDUyYTAx MDEwNDA0MDEyYTAxMDE2NDAwZTUwMTI5MDEzMjFiMzYwMDgxMDEwMTA5MDEwMTAyMDEwMjAyMDIw MjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAyMDQwMTA1MDkwNTAxMDRhNDM3MDA0NzBjMDYwN2Zj MDA3ZTAxMDgwYTAxMDEwOTAxMDEwMTBhMDFmYzQyMDEwMTAxMjNlMTM0MDAzNjAwMDBjOTI0MDEw ODA0MDQwOTAxOTQwMDM3MzAwMTAxMGIwNjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAy MDIwMjAxMDRlYzM4MDAxYmFiMDEwNDAyMDEwNTAyMDEwMTA0MDE0NzM5MDAwMDAwMWEwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMA0KMDAwMDAwMDAwMDAwMzYwMGNiMDA4ZTA0MmMwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MmMwMTI5NTgzNzAwNGUwMTAxMDEyOTA1MDEyOTA2MDEwMTAxDQowN2Q4ZWQzYTAwMTgwMGM3MTEw MjA2MDEwMTA4MDcwMTA1MjgwMTAxZjEwMDcyMDIwOThlNWYwMDM3YjgwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMTAzMDUwMTAzMDIwMjQ1MDAwMA0KMzlk OTAxMDEyYzY2OGIwYjBhMDEwMTAzMDIwMTBiMDEwMTQxMDEwMTEwNTkwMDAwMzgzNWM5ZjIyMDgz MzliMjA4MDIwMTAxMDEwNzA1NjAxYjM0MmEyYTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjA2MDEwMTg5MzUwMDAwMTIwMjBhDQowMjAxMDEwMzA5MDUwNTAxZWYwMDM5MWIwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDFjMDAwMDAyMDEwMTJhMDIwMg0KMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAxMDEyYmQ3M2FiYzBiMDEwNGU4MDEwMTAxNjVjMDRmMDcwYzAxMDEwMzA3MDIwODAx MDEwMzAxMDIyYTI5MDEwMjAyDQowMTAyMDk0MTg0N2YwNzA5MDQzZjU2MzgwMDViMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDEwYjAzMDEwMjA0MDEyNTAw MzgwMGMzMDEwMjAxYzMwMDI0MDMwMTAzMDMwMjAyMmEwNg0KMDYwOWViNWYwMDRhMDBiMDBmMDYw OTAxMDYyYjZkNDk5NjAxMDEwMzBiMDIwM2E2MDAwMGE4MDEwYTA0MDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMTQxMDFjY2VmNWYxOWNmMDEwMTAxMDYwYjAxMDEwMWM2YWM4NDAwMzcx YTAwMzcwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzOTk5ZDE4ZTA2MDEwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMTA3MGYxYjAwNDQwMTAzMDEwOTAxOGVmNDAwMDA4YjE2YzQ4ODAxMDgw MTAxMDEwNTAxMDkwNTAxMDEwNDAxMDEyYTAxMDEwNmQ2MDA0NTAxMDUwMTQ1MDAwMDAwYTIwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAxMGIwMTAxMDEw MjAzMDY4YjM4MDA5OTJhMGIwMWUwMDA1YzAzMGEwMzAxMDQwMjAxMDEwMTAxN2FjYjkxMzdiMGZk MDE0MTA2MDEwOTAxYmYxOA0KMzQwMzAxMmEwYjAxMDEyYjAwMDBlZTAxOGUwMTAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDYwMTA0MDEwMWQ4MTliNzA2MDkwOTAzMDEwMjA1MDNjOTFj MDA1NTQ4MDAzNjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDM4MWJiOTJjMDEwMTBhMDEwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjI4MDkNCmJiMTkwMGEwMDMwOThlMDEwNDAxZTdmYWY4MWIwMDAw YzdiMmE3MDEwYjA5MDQwNzAxMDEwNzAyMDE0MjAxMjgwMTBhMDI1YzAwZDYwNTBhMDM3NDAwMDBj YTBiMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyDQowMjAyMDIwMjAyMDIwMzAz MDEwOTAyMDEwNzAxZDAwMDM3MTk0MDAxMGE3OTM0Y2UwYTA2MDEwMTI4MDEwODAxNDEwNjAxZmVj ZDFhOGU1MDBhMDEwMTA1MDEwNDAxZmYwMDAxMjgwOTAxMDEwMTAxNmUwMDM5ODgyODAxMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjA1MDQwMTAxMDY5NTU1MTIyYTAxMDEwOTAxMDEw NjA4MjEzNzAwNGEwMDAwMzYzOTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAxYjNhZmUwMTA3MDMw NjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNTI3NDkxYzliMDEwYTAyMDEwNDI4MjkwMTA1MDdj NWJkZDUNCjAwMTgwMDk4OTBkNDAxMDEwMTAxMDQyODAxMDkwYTAxMDQwNTAxMWQ0OTdhMDcwMWE4 MTkxYjM3MTUwNDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIw MjA3MDEwMTAyMDMwMTA2MDFiMzAwDQowMDAwZTMwMTAzMDExNTFjYzUwMTAxMDMyOTAxMDEwMTA4 MDEwMTA4NDdlOTBiMDEwNzhlMDEwMTA1MDk5ZjNiMWMwMTAyMDEwMTBhMDUyODZiNGExYjcwMDEw NzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwNjBhMDEwMWM0MDAwMDFjNjQNCjA5 MDQwMTI4MjIwMDAwMDAwMDAwMzgzNzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDYxNDEwMTAx MDEwOTAxMDEwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDE0NDAwMDA1MTA5MDEwNzAxMjgwMTAx MDE4ZTAxMGIxMDE5N2YxN2E5MDAwMDAwOWI3MTA0NDIwMTAxMDEwMTA3MDENCjAxMDFiZTFjMTQw YjA0MDE5ZDAwMDAxYmE2MDkwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAy MDIwMjAyMDIwNTAxMDYwMTA0MDEwYTAyNDMzMzAwMDBiNDBhMDEwMTJmMWM3NjAxMDIwMzA5MDEw MTAyDQowNzAxOWYwYTRhNWEwOTAzMDEwMTI4MDgwMTAxYTE0YTU3MGEwMTAyMDgwMjAxMDk0MWZm MDAxZDA3MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjBkMDEwMzdhMDE2YzNhMDAz OWVhMDEwODAyMDRiZDAwMDA1ZjFiMDAzNzM4MDAxYzAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA4 NjAxMDQwYTBhMDUwMjBhMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjJhOTkwMGNlMDYyODAxMDcw MTAxMDYwMTI5MDEwMTJhNzQwMGY0MDE2MjI2MTUwMDkxNDEwMTI5MDEwMTAxMDQwMTA5MDEwNzc2 MWNlMDA1MGEwNDZlMDAwMDQ5ZDQwMTAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAw MjAyMDIwMjAyMDIwMjAyMDIwMTJjMDEwNTA0MDMwMTAyOWEzNjFjMWNjYzAxMDMyOTkyNmYyYzA4 MDEwMTBiMDUwMzAxMDQwMTAxNzU0ODI1MDMwMTAzMDkwMWNjZTEwMDM2DQoyZTA3MDUwMTA3MDEy OTAxMDEzZTAwMWJjYzA3MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTQxMDEwMTQy MGE0ZmMzMDBjN2JhNDdlZmJhMWMxYjAwMDAwMDE4MDAxYjM3MDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwN2IyODAxMDEyOTAxMDIwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyYzUwMA0KMzZjZDAx MDEwNDAxMDkwMTA1MDEwMzAxODgyZjAwMTQwMTAxMjkwMTI4NjIxMDAxMDMwMTAxMmMwMTAyMDE4 ODA5N2EzNDQ5MjkwMTAyNzE0ODAwNDg1ZTA1MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMDAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNGIzMDAwMDFiOTYwMTAxMDMy MDE5MGYwMjI5MDEyOTA3MDEwMzAxMDkwMWQ2MDA1NTQ0YTAwNWQzMWZjYjAwMzdmMDBiMDIwMTAx MDQwMjAzMDEwMTRmNWYxODZlMDcyYTAxDQowNjA0MDEwMzAxMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDUw OTAxMDEwNjAzMDExMjAwMTkwMDAwMWMwMDAwMDAxODAwMDAzOTAwMWEzOTAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDE5MWEN CjAwMWEwMDM2MDBjNzZiNjIwMTAxMDQwMTAxMDQwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMGIwMTAxMDEwMTJiMDEwNDZlMWJi NWM2MDMwMTAyMDIwMTJjMDEwMTAxMDkwMTU3MDA5NA0KMGEwMTAxMDIwYTAxMDIwMjAyMDIwMjAy MDIwMjA5MDQwOTYxMDAxMzA4MDEwMTEyOGIwMDAwYzQwMTBhMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMGQNCjMzMWIxYWIw MDEyODAyZDgwMDE1MDEwMTAxMDEwOTAxMDYwMTAyMDEyN2MzMDAwMDFjMTkwMDAwY2I3ZWEyMDQw MTA5MDIwMjA3MDEwYjAxMDIwNzEyMDAxYTcyMDEwMTBiMDIwOTAyMDcwOTAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMTAzMDUwMzAxMDEwYjUyMDAwMA0KMWMxYTAwMDAxYTM2MDA5MjAwMTgwMDAwMDAxYjAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAxYTAwMWE1NjAwMTljMzAxOGUwMTAxMDEwYTAyMDEwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQow MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMmEwOTAzOGUwMTJh YjYzOTAwNzYwMTAxMDEwMTA0MDEwMzAxMDQwYTA5MDU1ZTAwYTAwMjA1MDQwYzAxMDkwMjAyMDIw MjAyMDIwMjAyMDUwMQ0KMDVkMDAwYTcwNTAxMDU3NTAwMDBhOThlMDYwMTAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxZWUz NzM3MDA2MjA0MDEwNGNiNTU5ZjAxMDUwMTAyMDENCjI4MDEwMTA5MDE0ZmFjODU5ODhiZjExZjI0 MDkwYTAxMGI0MTAxMDEwNDAxMDEwNTA5MDFjY2NlMDBjOTA0MDEwMzAxMDUwMTA2MDEwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDEwMTA2MDMwMTAxMmFhNjRhMDAzNjFiMDAzODAwMDAwMDE4MDAxYTAwMDAxYTFj MDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAxYjAwMDAwMDE4N2QwODAxMDEwMTA1MGEwMjAxMDEwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMTA1MDEw MzAxMDEyYzNjMDA2NmNjMDEwNTBjMDEwMzA0MDQwMTA1MDIwMTAxZTE5MmIyN2EwMTAxMDEwMTBh MDIwMjAyMDIwMjAyMDIwMjA1MDE3OTQ5NDcwYjAxMDJlODE4MDAwMGJiMDEyOTAxMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MGEwMTZjMDAzOTAwNGQwMTAxMDE1ODM3ZmEwMTA5MDEwYTAxMGEwMTAxMGIwMTAxMDE0MTA1NDIw MTA3MDEwMTA3MDINCjA0MDkwMTAxMDYwMTAxMDYwNjAxMDkyMjFiMDAzZjAxMDEwMTA0MDEwNDAx MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjA3MDEwOTAxMDEwMzAxNGY1MDY1MzkxYWU5NjIwYTUwZjM1ZjFjMDAz OTFjMWIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDFjMDAwMDU1MDAwMDMxMDEwMzBhMGEwMjAxMDIwMjAxMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA0 MDEwMTAxMDEwNmQ5MzcwMDczDQowMTAxMDEwYTAxMDEwMTA1MDcwMzAyMmEwMTdiMDAwMGM5NmEw MTBiMDQwMTAyMDIwMjAyMDIwMjAyMDIwMjA0NmMzOWIyMDEwMTA0ZDMxYzAwMzhhNzA4MDEwYjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjA5MDE0MmNiMzkwMGI4MmEwMjA0MGUxYWQwMDEwMTA5MGIwMTAzMDQwMTA2MDQwMTA5 MDEwMTAzMDkwNDAyMDcwMTAxMDEwMjA5MDQwNTAyMjgwMTJhMDEwMWFjMDAzN2E1ODgNCjAxMDIw MjAzMDkwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwNjAxMDEwMTA0MDQwMTAxMDk1YWQ1NWY1ZDBiMDEwOWQw MDAwMDAwMDAwMDM5MzcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMWIzOA0KMWExYjE5NjY3MDI4MDIwOTAxMDEwMTAzMGEwMzAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMTI5MDEwMTUwMDFmMzFjNWZhODAxMDYwNTBjMDEwNDAxMDIwNDAxMDEwNzAxMjlkZTM5 DQo0OTAwNDcxMjUwMGEwMjAyMDIwMjAyMDIwMjAyMDEwMWRmMzkyNDA1MDMwOGIwMDAwMGM3NDI1 MDAxMDQwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMQ0KMDlkYjQ4MDA0YTZiMDMwMTJjYzI0YmM2MDkwMTBhMDEwMjA2MDkw MTAyMDkwMTAyMGIwMTA5MDEwMzAxMGEwYTA2MjgwNTAxMDEwMzA3MDEwYTAxMGIwOTNkMDAxY2E3 MDIwMTAxMGEwMTAzMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwNTAxMDQwMTA0MDkwMTI5DQowMTAxMDcw MTA0MGE2NTAwYTk0YTM2MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNGEwMDAwNjUwNzAxMmEwMjAxMDEwMTAxMDQw OTAxMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDEwNTA3MDEwYWQ2MWMwMDNjMGEwNTA1MDEwNDAxMDEyYTAxMDEwNTA1MDYw MTA5MjkyYjVhMzQzOTFhYmUwOTAyMDIwMjAyMDIwMjAyMDIwMzg4DQoxYTZmMDcwMzA1NzIzOTAw MDAyMDA5MDEwMjAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEwNzNmNTUwMDM5NWEwNzAxMDE1MjE4N2QwNjAxMDkwMg0K MDEwNDAzMDEwMTAxMDEwOTA2MDEwMTAxMDYwOTAxMDkwMTAxMDEwMTAxMjgwMTAzMDkwMTUwMDFk YzE5MDA1N2JmMDEwMTAzMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA0MDcwMTA2MDEwYTI5MDUwMzAx MDEwNTA0MDEwMWI0OGIwMDAwMDAwMDM5MWMwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA0ODM4MDAxYjZkMDkwNTAxMDQwMzAz MDUwNTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDINCjAyMDIwMjAyMDIwMjA5MDEwYTAxMDdiYzFjNTZlYzAxMDEwNTAxMDkwNjQxMDYwMTA1 MDUwMTAzMGEwMTBhMDEwMTI4NjkyMjJjMDEwMjAyMDIwMjAyMDIwMjAyMDZkMjAwYWEwMTA1MDJl ZDAwMDAxOGE3MGEwMTA2MDQwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTQxMDEwNmNiMWMwMGJhMjkwODAxNTA1NWNhMjkw OTAyMDcwMTAxMDQwMjA5MDkwMzAxMDEwOTA0MDEwMTAxMDEyOQ0KMDUwMTA5MGIwOTAxMDEwNDA2 MDEwMTQxMDE2NTFiMDBiNjA0MDIwNDAzMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwNTA5MDEyYzAxMDEw MTA0MDEwNTA5MDEwMzA5MDMwMWViYjgzYTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxYzAwMzhiNDAxMjkw MTAxMDEwMTA5MDIwMTAxMGEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDkwOTAzMDIwZjAwMDAxZjAxZDQNCmIyNDkxYTQ4YTkz M2VkNTk1ODQ0Yjk4ZmI2MmIwMTA1MDQwYTAxMjkwMjAxMDIwMjAyMDIwMjAyMDIwMjBiNWZhOTQy MDYyYzAxY2IwMDM4NWY0MjAyNDIwMTA5MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDQwNDA1MDQ0ZDFhMDAzOWIzMDMwNzAx YmIwMGFjMjgyOTAxMDYwNTAxMDcwYTAxMDEwYTAxMDcwMTAxMDMwMTBhMDEyYTAzMDEwOTBhMDUw NTAxMjkwMTAxMDEwNmNjNGEwMA0KZjcwMTAxMDcwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMWVmMDAxYjAwMTkxOTAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDE4DQowMDQ4 ZjUwNDAxMDQwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDkwOTA5MDIwMjAxMDEwMTA3MDEwNzA2MzIwMDE5NDAwMWIxNDgwMGQ3 Y2VkNzAwMWMwMDAwMWI0ODAwMDBiYWZmNDcNCjlhNTI1MjQyMDIwMjAxMjkwMTAxMDEwYjAxMGFk NjAwZWUwMTA4MDE5NTAwMDAzNmFiMDEwMTAxMjgwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNjAxDQowNzAxNjMwMDNhMDA3 NDA5MDEwOTk0MDBmNzAxMDEwMTAxMDQwYTAxMDIwNDAxMDEwMTA1MDQwMzAyMDkwMTg4MDEwMTA4 MmFjM2I1ODkwMTAyMmE3YTI4MDEwMzMwMWEwMGI5MDIwMTA4MDQwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjQxMDEzYjAwNTYzOTAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMzkx YTFiODZkNDAxMDUwMTAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA5MDkwOTAyMDIwMTAxMDEwYTAxMDJjNjAwMzhlMTAxMmMz NzAwZDYwMTAxOWYzMDAwOGI2Yzc2MTVmMjc0NGEzMzRhMDAxY2U2OGQwMTAxMDEwNjAxMDM0MTAx MDYwMWE1MDANCmZjMDIwMThlNzUxYTM3MTg4MTQyMDEwMTA2MDEwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMGIwMTI4MDEwNTVl MTgwMDRhODEwYTA3MDFiNTkyZDQwMTJjDQowMTAxMjgwMTA5MDMwYTA5MDEwMTA2MDIwMTAzMDUw MTI5Mjk1YzU1MDAxODkwMmIwNjAxMDEwMTAxMDE0MDFjMWI1MzAxMDEwMTAzMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDkwMTU0MWEwMDAwMTgwMDAwMDAN CjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDRlMDEwMzA1MjgwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDkwOQ0KMDIwMjAyMDIwMTAxMDE4ODAxNzUxYjAw ZWIwMTAxOWNmNTJiMDEyODAxMDZiMTVmYzI4MTAxMDEwMTA3MDY1MDI1MjRjNjAxMDIwOTAxMDMw NjBhMDMwMTAzODk0OGM3MDEwMTA3ZWMwMDAwMDA2MDAxMjgwMjAxMDEwMTAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEw NTAxMDcyMzAwMWIxY2FmMDIwMTAxZDMzYTZkMDEyOTBhMDEwMTAzMDcwMTAxMDUyYTAxMDEwMTAx NDIwMWFkDQo5YzkyMDA1NWI4ODEwMTAxMDQwNjA4MGIyYzAxMDE1YzFiMDBjZDAxNTAwMTAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMmM2NjAwMTkwMDQ5 MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDQ5MDA2YjA2MDkwMTBhMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQow MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIyODAxMjIw MDU2YzMwMTQxMDUwMQ0KZGMwMTAxMDEwYzAxMDE2ZTU1Mzc2ODAxMjgwMTAyMGEyODA1MDEwYTI5 MDEyODAxMDcwYTAxMmMwMWUxMDBkZTBhMGIyODljMDAzNzAwZmEwMTAxMDYwNjAxMGEwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMTAxMDEwMTA3MGI2ZjFhMDA0YTA1MDE3YTI4MTg0YTYzMDEwNzA1MDEwYjA5MDEwMTAxMDEw NTA4MDgwMTg4MTYzNjQ4MDA5OGQ4MGEwNzAxOGUwMTAxMDQwMTAzMDEwMTI3DQpiMDAwNTY4ODAy MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTBiOWEw MDAwMTkwMDFjMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDM3MWINCjAwYWMwMTAxMDMwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDg0MTAwMzhmZjI4MjgwMTAxMDEwNjhlODgwMTAxNDIwMTAxY2QwMDAwM2YwMTBhMDEwMQ0KMDEw MTA2MDgwMTAxMGIwMTAxMDQwMjUwNjI0YTE4N2EwMzUwMDUzNTFhMDAzNDI4MDgwMTA5MDcwMTA3 MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjA1MDENCjAxMDEwMTAxY2QwMDFhMzdkMzAxMmEwMTY3MDA3ZDAxMDEyYTAxMDQwMTI5 MmMwMjBiMDIwMWM4MzExYTFjNDgwMGJiMDEwYTAxMDEwMTUwMDEwMTI3MDEwOTA0MGEwMTc4MDAx YmRiMDEyYjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAy MDYwMWZkNDAwMDM4MDAzNzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMWI4ZjAyMDEyYzAzMDIwMjAyMDIwMjAyMDIwMjAy MDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTAyMDIw MjAyMDkwOTAxNjUwMDM3N2MwMTAxMDEwMTJiMDEwMTAyMDUwMTA1MGIwMjI5ZjI0ODAwZjkwMTAx MGIwYjAxMDEwNDAxNDEwMTBhMDIwMTA3MDE5ZTAwYjc0Mg0KMDEwMWQzMDA0ODAwY2QwMTAxMjkw MTAxMDYwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwNTA5MGEwMTAzMDM2MzQ3MDAzODdmMDgwMTA1NGZjMmVmYzUNCjAxMDMw MTAzMDEwNjBhMDEwMTUwZTAxOTAwNDliMDI0YTMwMDU0Y2ZhNmEzN2NhM2ZhNDIwMzAxMDEyODAy MDIwYTE2MDAwMGQ4MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMTA2MDEwYjRhM2EwMDM5MDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzODM2YTIwNTAxMDEwMTAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAx DQowMTAyMDIwOTA5MDk1MTAwM2EzZDhlMDEwMTJhMDEwYjA4MGEwMTQyMDMwMTAxMDUwMTQxMTMz N2E5ZjAwNDAxMmMwMTAxMDQwMTAxMDEwYjI5MDEwMTlmY2UzNDhlMmEwMTQxNGIzOTQ4Y2JmYzAx MDEwYjAxMDEwYTAxMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwNzA0MDE4ZTAxMDE2ZDFiMzgwMGQzMDcwOTAzNzMwMDc3 MjgwMTA5MjgwMTAxMDEwYjA0MDJlNzQ5MzJiNjAxMDENCmIyNDZmMTM3MDAwMDAwMDAwMDZhMDEw YTA3YWRmOGY1MDE4OThiMDA2NjUwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDkwNzA0MDEwNDRlYTkwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDFiMWEwMGI2MDEwYTA0MDEwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDEwMTAxMDIwMjA5MDkwOTg0MDBjYjYzMDMwMTA0MDEwOTAxDQoyODAxMDEwNjAxMjkwODAx MDcwMTAxMzEzNzFiOTUwMTAxMGIwNzAxMDkwMzBiMDEwMzAzMDI5NjAwODUwNDAxMDlmMDE5Mzkw MDE2MDEwMTBjMDEwNjA0MDEwNDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA0MDEwMTA3MDEwMTlmYjYwMDFhNGEzNTJjMDEw NjQxOGJkNTYyMDEwMTA4MDEwMjA1MDEwMTAxMGE3YTJjMDcwMTZhMWNlOTg4ODE3MDY4MjY4M2Y4 ZTkwYTdhZmIwMDAwOTINCmM2MGJjMTFiMWFmYjAxMDEwNDI4MDEwNjAxMDkwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjA2MDMwMTI5MGE0MDkyMDAwMDAwMWIxODFhMDAwMDFhMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMzcwMA0KMWNhMjAxMDIw YTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAxMDEyOTAxOWYwMTAxMzE0ODAwY2YwMTBhMDcwMTA5MDEyYTAxYjlmNjU4YWY2 N2I5MDYwMTI4MDEwMzRjMzgwMGZlDQowYTA5MGEwMTAxMDEwMTI4MDEwNjUwZTI1NjJiMDQwMjJi NTUxOTM3MDBkYTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDQwMQ0KMDIwYTAxMDEwMTQyNTcwMDAw MTg5ZTAxMGIwMWZiMDA5NjAxOGUwMTAxMGEwMTA5MDYwMTA5ODgwMTAxY2M5OTE5OTQwMTJhMDEw NDQyMGIwMTA0MmY4MDAwNDgyMGE4MDcwMTQyODQxYzQ4NjMyODAxMDFiZjAxMDEwOTAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMTAxMjkwMTA0MDNmYzYwMDAwMDAwMDAwMDM5Mzkw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDJl MDEwNzA3MDkwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwYTA1MDEyYzAxMDUyNTNiMDBmNzI3MDEwODAxNDIwMTA1MDM5NzVm MDA0ODAwMDAwMGYxZTcyNzI4MDIwMWRiODRiZTAxMDEwNzA1MGEwYzAxMmMwYjAxYzMwMGJkMDEw MTAxDQo5ZDE4MDAwMGRiODgwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAzMDMwMTAxMDE1 MTQ4MDAwMGJhN2EwNTAxODg5Mg0KMzU2MjAxMDIyODAxMDEwNTBiMDEwMjA5MDEyYjdmMzZhYzAx MmMwMTI4MDEwYTAxYTgzZDM5MDA1ZWUzMmMwMTAxMmEwNjY5MDAxYmVlMDcwOTAxMjkwMTAxMDMw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDkyYTAxMjgwMTAxZjgxYTRhDQo0ODFj MWMwMDAwMWEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz NjAwMWNhMjAxMDIwMzAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA1MDENCjA0MDE4ODAxODAzOTFjODIwMTAxMDIwMTAxMDEw MTExMzkxOTMwODJhYTZkNDkwMDU2ZjkwMTAxMDFhMGQ4MDEwNTA3MDUwMTAxMDEyYTAxMDI0MjNi NDc3MTAxMDFlYjFkMDAwMDAwYTIwMTAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTAy MGEwYTAzMDY3ZTAwMDAzOTlkMDEwYTA1ZTUwMDY3MDEwNjAxMDYwOTAxMDEwMjAzMDEyODY0MTg1 Mg0KMDEwMjBhMDEwNzI5MDFkMjc0MDAwMGYyNTAwMjAxMDMwYzAxMGEwMzg1MDAwMDY5MDEwOTAx MDEwNDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA2MDEwMzBhMDY0MmE1MDAw MDAwMDAzOTAwMDA1NTAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAzNjAwOThhYjBhMDEyODAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTI4MDMwMTAyZjQxYjFhNGMwODA3MDMwMTJh MDEwOTA0MzMNCjFiYzgwMTAzMmMwMTk0NjUwMDMzMTEwODAxMDUwNDAxMDQwMTA0MmIwYjA0MDYw MTAxNWQwMDk3MGEwMTAxNzAwMDAwMTk5YTA1MDMwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDkw NDAyMDEwMTAyMDkwMTAxYWUzOTAwMzZlMjI5MDEwMTI3OTI1ZjhlMmMwMTAxMDUwMTAxMDEwNzAx MmE3YzAwNzMwMTA5MDgwMTAxMmRkNzAwMWE0YTkyMDA5OWU3MjkwMQ0KMDEwMTAxMDYwYmNiMDA3 ZmM2MDE4ODAxMDYwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIN CjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwNjAxODgwMTAx NDJlMTU2MWIwMDAwMWEwMDAwMzcwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwDQowMDAwOWIwYTAxMDkwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDkwYjI5MDE5ZmMyMTg0NzYyMDEw MTBiMDEwMTBiMDE4YzAwOWMwOTBiMDMwMTBiMDkwMTUyMDA0OTUwMDUwNTAxMGENCjBiMDEwMTAy MDEwMTAxMDE3MTU1Y2IyYjAxMDUyYzc1MDAwMDE4ZTMwMTI4MDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMTA5DQowNDA5MDEwMjAyMDEwMTQzZWYxYjAwMDA1MTAxMDEwODE1MDBmMjBhMGEwMTA0MDIw MjAxMGEwYTAxN2FmM2FiMDcwOTAyNTBlZDFjMDA5MTEyYmU2YmYyMDBhOTYyMGEwMTQxMGIwMTA3 NjExOTAwYjEyOTAxMDUwMzAxMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAxMDkw MTA3MDEwMTAxZTYwMDAwNTYzNjAwMWExYzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMzYwMDM5MWE2ZTAxMDMwMTAyMDIwMjAyMDIwMjAyMDIwMjAyDQow MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA1MDEwMTAzMWUwMDM2 YTMwMTAxMDIwMzBhMDMwMTA1ZTMwMDc3MDMwMTAxMDUwNjAxMDEyY2I1NmZlMzQxMDEwNDA0MDIy ODAxMDMwMTBhMDUwMTdkMDA5ZDAxMGEwMTI2MzkNCjAwMWExZDQxMDkwMTAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDEwMTAxMDQwYTA1MDQwNDA0MDE0NDU2MDAwMGRmYmYwYzAxDQo4OTM1MWIyOTAx ODgwMzAxMGEwMTAxMDYwMTAxYmYwMTA1MGIyNmNhMDA0N2EzMDIwMzAxMDEwMWFiMDA0NTA5OWYw MTAxMDEwYzAxMTY2ZjAwOWUwMTBiMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDEwNDQxMDQ2NTRhMDANCjAwMTkwMDAwNGEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMzgxYTAwYzkwNDAxMmEwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwOQ0KMDE1 MjAwMWMzMDAxNDEwMTJjMDEwMjJjMDEwYTY4YzI5MDA4MDIwMTAxMDEwMWEwMDFkMjAwNzcwMTJh MDEwMjAxMDQwMTA2MGIwMTAxMDg4YjkyMGQwMTBiMDViNDAwMDAzYWJkMDEwYjAxMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjA4MDIwMTAxMDEwMTAxMDEwNDAxMDY1ZjM4MzgwMDNmMDkwMTBhYWYz ODExMmEwMTBhMDEwNTA0MDEwMTAxMDgwMTA0DQpkNDIwMDAwMDRiZDgwMTAxMDMwMTI5MDcwM2Q1 NGEwMTAxMjkwMTAxMDEwOTBhNjYzNjM3YTcwMTAxMGEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAxMGEwMjAxMDEwNTAxODdkNmI4MDAzODAwMDAxOTAwMDAwMDAwMDAwMDAwMDAwMDAw MDANCjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA0ODAwMTljMGJlMDEwYjAxMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjBh MDEzZjM2MTg3NDdhMDkwMTBhMDEwMjAxMDE0MTAxNDMwMA0KYzc4ZTAxMGEwNzAxMGIwMTAxYTMz OGExMDQwMTA3OTBiYzEzN2EwMTA0MDIwNzZhMDBiMjAxMDEwMTZhMDAwMDNhZDUyODAxMDUwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDINCjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMmEwMTAxYTYxODM3MDBkMTAy MDEwYjQxMDA0YjAxMmMwNDAxMjkwMTI4MGEwMTA1MDkwMWQyMzcwMDFjNzAwMTA5MDEwMTI5MDMw MTBhMWQxOTAxDQoyYjAxMDEwMTA0MDYwMzhkOTIwMDRiMGQwMjBiMDMwMTA3MDEwMTBiMDkwOTAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA2 MDMwMTAzMDEwOTAxMDcwNzAxMGE4ODAxMDEwNjAxMDc3ZjFhMDAxYzAwMzgwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwYjYwNTAyMDEwMTAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA3MDEwNDAzMDEw MTUwMDEwMTg3NmYzOTM2NDAwMTJhMDIwMTAxMDIwOTAzMDMwMzAyNjUxOWNhODEwMjAxMDYwYTA5 MGE1NDM3ZGM4ODAxOWUzOQ0KMDBiZDAzMDEwMTBhMmFlZjAwOTQwMTJhMDQ3NTM4MDA0OGY5MDEw MzBiMDQwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAxMGIwNjAzY2Ex YzU2MDA4MjI5MDEwNjMxMDA5YzAxMDMwYTAxMDEyYTAzMDEwNjA1MDcwNTczYmI0YTA2MDEwOTAz MDcwMTAxMGEyZjAwNTUwMTAzMDEwNTA3MDEwMTBhMGI4MjQ4M2FjOTg4MDEwMTQyDQowMTI4NDIw MTA5MDMwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDEwMQ0KMGIwMjI4MGEwNjAxMDEwMTAxMDExOTM2NDgxOThiMDAwMDE5MDA0ODAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDBiNjA1MDIw MTAxMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMTBh MDE4ODAxN2EwMTA1NDFmNTM2MzllMDI4MDUwMTA1MGIwMjA5MDEwMTA2MDEwMWM1ZTJjYjAwYWE4 ZDAxMDE4OGQxMDAxZjA3MGE3MjM5MDA2ODAxMDEwYzAxMDk3NzAwYzEwMTAxMDFiMzAwMDAwMA0K MWQ4ODBiMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAy MDFlYTAwMDAwMGI4MDcNCjBiMDFlYmMyMzZjYzAxMDYwMTAxMDQwMjAxMDUwMTAzMDEwMTNiNTUw MTdhMDEwNzA3MjgwMTI5ZmYxODEyMDEwMTAxMGEwNzAyMmEwMTA2MDExZjAwMDA5YzBhMDMwMTI4 MDEwMTJjMDEyOTAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjA2MDIwMTA3MDEwMTJjMDEwMzI4MDMwMTAwMzc0YTM5MDAxOA0KMDAzODAwMWEw MDQ4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw YjYwNTAyMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAxMmMwMTAxMjkwMTBjMDViNzM3DQowMDU4MDEwMTAxMDUwMTAzMDEwOThkMDEwMTBjMDE0MWNj OTMwMDAwNTY4YmNiMzQ4YmI4MDEwOTAxNjYzNzVlMGI0MTI5MDEwYzQzNDc5MmM1MDE5ZjA1NTMw MDM2MDBmYTAxMDMwNDAxMDkwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAxNDIwMTBhMDFjYTFiMTgwMGUwMDMwNTAxOWU0ODZkMDkwMTJhMDEwMTAyMDYwMTAxNDINCjA3 MDFjOTAwZmQwMTA2MDEwNTAxYTdlZTFhYmE4ZTAxMDEwOTAyMDEwMTAxMDEwMTlmMmJlMjRhMDBm OTAxMDgwMzAxMDEwNDQxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwOTQxZGQ5MzdlOTNiY2I4YjBiMDQ2NTQwMDAwMDAwMDAwMDAwMDAw Y2IwMDAwMTkwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMGI2MDUwMjAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwNDAxMDkwMTAxMmIwMWM0MzgwMGY3YWQwNzI4MDEwYjAxMGE4ODAxMmNkM2QzMDcw ODA0DQowMTA2NjczNzM3MTgwMGRiNzAwMTJjMDg3MzM3MTk4NzI4MDEwMTA5MmFmNTAwN2MwMjAx MDE3ODAwMWEwMDdmMDEyODAxMjkwMTA5MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwNDAxMGEwMTAxNjQwMDM5MzdlZjQxMmMwMTQxMjAwMDExMDEwNjAxMDEwMjA2MDEw MTAxMDQyYzg5NTZmODQwMDEwMTYyNGM1NjAwOGJjNTA0MDINCjAxNDIwYTAxMDEyOTAyMGEwMTAz YWQzNzAwN2ZkNDA5MDE4ODA5MDEyYTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMjk0MzkwMDFiMzYwMDAwMzgwMDAwM2ExOTAwM2Ex YzM2NTYwMDE5MDA1NjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMA0KMDBiNjA1MDIwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDEwNjAxMjgwYTAzZTdjNzAwNDcwZTAxMDEwNTBhMDEwYjAxOGZiYjAw MDBjMjAwNzUyYTA4MDI0MmFkN2UwMDE4YTU2YjI5OGQ5YzAwMDA3YzAxDQoyYzAxMmE0MTk0MDBm NTQxMDE0MjJhOTkwMDAwMDBmNDBhMDEwMTAzMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMjgwMTA5MDYwMTAxOTEwMDM2MDA4NTAxMDcwMTEwMDA3NGNjMDEwMTBi MDIwMTAxMGEwMTI4MDE4ZTcwMzkzODAwMWIwMDM2NGI2ZDc5MDUwNzJiOTcxMzJkMDEyYTAxMDEw YjAxMDEwNjdjNTUwMDMyN2ENCjAxMDEwYTA2MDEyOTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwYzBhDQo1MDhjOTU2OThjMjNhMzc4MTE2YTAw MDAwMDFjMDAwMDAwMWEwMDAwMzkwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMGI2MDUwMjAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDINCjAyMDIwMjAyMDIwMjAxODgwMTA5MDIwMTFkMDA0YWEzMDEwMTAxMDEwNTAxMDM3 YjFiMDBiMDYwODA0ODAwMDBjNDA2MDEwMWU3OGYxZDM3NGExYTAwMDA5MjVjMDE0MTAxMDYwMTQy MWQwMGFjMDcwMTA3NWMwMDQ4MWE5YjAzDQowMTA3MDYwMTA4MDEwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMTI3MDEwMTBjMDFmYzhiMDAzNg0KMDBlYzA2MDQwNjkwMDAx MzI4MDkwNTAzMDEwMzA2MGEwOTAxMGEwNTk3YjUzNjM5Y2I3ZTZjMmEwMTBiZDgzYTAwM2EwMDEz MDcwNzAxMmIwMTA2MGIwMWNkMTkwMDIxMmIwMTA3MDE0MjAxMDIwMjAyMDIwMjAyMDIwMjAyMDIN CjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwNzAxMDMwMTAxMDEw MjBiNDgzNzAwMDAzNjAwDQpjMjAwMWEzNzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDBiNjA1MDIwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDQwMTBiMDIwODIxMDAxODViMDENCjAxMDEyYTAx MDEwMzAyYmE1NmQ5MDEwMTBjMjVlZTFiMWFjMDhlMDkwMTJjMDEwZTdkYjBiYTU4YjYwYTBhMDEw MTA2MDFlMTAwY2QwMzAxMDE5NDMzMDAwMDMzYjkwMTAxODgwMzAxNTAwMTAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMjgwMTBiMDE5NjFiMDAzYTgwMDEwMTA0 NDIxODFjYmUwNzAxMDUwMTAzMDEwMQ0KMmMwYTAxMDEyYzAxZDRmZDBkMDEwMTA0MjgwYTFkMDA0 NzFmOGIwMDhhMDEwMzAxMDIwNzAxNDEwYWE0MzYwMDE0NDIwMTI5MDEwMTAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA0MDcwMTA5MDEwNjAx MDcwMzAyMDUwMWZjY2NmZGNjZDQ4OWVjMWMwMDAwM2EwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQow MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwYjYwNTAyMDEwMTAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA5MDEwNTAxODMwMDRhNjYyODBhMDEy OTA1MDEyOTAxY2YwMGI3MDkyODA1MDEwMTAzYWENCjM4MzliMzA3MDcwMTI4MDIwMTBiMDEwMTJi MDEwNDA5MDEyY2ZkMWE3NDBhMDYwMTI5OTMxODAwOTI5ZTAxMDEyYTAxMDEyODAxMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDJhNDAwMzYw MGY5MDEwYTAxYjMzN2UyMDcwNzAzMDEwNDAyMDIwMjAyMDIwMjAyMDIwMTAxMDIwMTAxMmMwMTQ0 MDA1NA0KZWI0MWEwNTQ0OGJlMDYwMTA2MDMwMTA0MDEyYmQ3MDAxOGY5MDEyOTAxMDYwYjAxMmEw NzAxMDIwMTBhMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMGEwMTA3MDEwMTAxMDkwOTAxNDIwMjAwMDAxYzAwMzkwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDFiMWEwMDFjMWMxYTFiDQozOTcyMDIwNzAxMDEwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDYwNDAxMDEwMjA1MDEwYjAxMDU3N2NiMDBlZjhl MDIwMjAyMDIwMjAyMDIwMmQ3MThlNzAxMDEwYTI4MDEwYTAxZTUwMGNiMDEwNjAxMjkwOTAxMDIw MjAxMDEwOTAxMDYNCjAxMDU1NDAwM2YyOTAxMjk3YzE5MDA0YWNhMjgwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy NmIzNzM4MTk4YjdhMDEwMTAxMWYxYmY2MDEwMTAzMDEwMjAyMDIwMjAyMDIwMjAyMDEyYTAxMjkw MTAxMDFiMzE5YzkwMzAxMjgyYjFiYzMwMTAxMDYwYTAzMDkwMTA2MGJjZQ0KMDBjYmYyMDEwMTAy MDEwNjAxMDEwNjI5MDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDINCjAyMDIwMjAyMDIwMjA0MDEwMjJhMjA2ZDE3ODkyYTA1MDcxYTAwM2EzNzAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMWIzNjFjMDAwMDAwMDA0NTY0MmEwNzAyMDEwODAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMGIwMQ0KMDEwNzAyMDUwNzAxMDE4ODY4MWMw MDdlOWYwMzAyMDIwMjAyMDIwMjAyMDI2NjRhMDEwOTAzMjkwMTAyMDMwMWU3NDczYTRlMDEyOTAx MDEwOTBhMDUwMzAzMDU4ZTAxMjlmNjM2YmIwNTAxOWYwMzZmMTkxYTAwZDYwMTAyMDINCjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMWRiDQoxOTAwMDBlOTAxMGIyOWFkMWI1ZjUwNDEwMTBiMDIwMjAyMDIwMjAyMDIwMjAx NDEwMTA1ZGJkNjJiOGQ1NTZmMGMwYzAxMDExNTZmMDEyYTAxMDEwOTAxMDIwNDA5YzgzNDAwYzJh MThlMDEwMTI5MDEwNjAxMDEwYjBhMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyNDIwNDAxMDMwMDAwNTY4MjAxMDENCjBkMzMwMDFiMWEwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDFiMWIwMDAwMTgzODM4NjQwYTAxMDMw MjAxMGEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA1MDEyODAxMDIwODAxMGIwNjY0 MDAzOGMyMjYwMTAxMDIwMg0KMDIwMjAyMDIwMjAyYTQwMGFiMDEyODAxMDE0MjAxMDgwMWVmMDAy NjAxMDEwMTAxMDQwOTAxMDEwMTAxMDEwM2JmNGEzNTQzMGIwNTAxZGIzNjAwMDA1ODA3MDEwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDRhZGMyMDA0ODM2MjYwMTA2MDFjNDAwNTk0MTI4MDEwMjAyDQowMjAyMDIw MjAyMDIwMjAxMDMwZTAwMzQwMTBhNjcxODlkMDkwYTA5NWRjYjZiZGEyOTAxMjkwNTA5MDEwNTAx MmYzNzE4MzlhMzAxMDUyYTAxMDEwYjAxMDQwNTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEyYTA0MDA1ZjAwYzdjYTQ2NDYwMDFhMDAw MDQ4MDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDkyMDAxYjAwMDAzOTAwMDAwMDcw MDEwNjAzMDIwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwOTAxMDFhMDAxMDE4 ZDAxZDIwMDAwNDhkYTAxMDQwNzAyMDIwMjAyMDIwMjAyMDI5N2E5NDc4ZTA4MDMwODAxMDkwYQ0K MDFiODFiMjcyOTAzMDEwNDA5MDEwMTAxMDIwMTA5ODgyMDAwZTUwMTAxMDk0ZTFhMDA0YTVmZWIw NDA0MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMDAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAzMDFlNTAwMDAwMDk4MjgwOTA1MGJiMDFiNjkwMTAxMDIwMjAy MDIwMjAyMDIwMjBiMDEwNzVkM2FjMTI5MDJkNDU1DQpjYTlmMDEwMWNlMzcwMGQ3MGYwMjAxMDEw NTAxMGIwMTAxNGUzODAwNDljODAxMDYyODAxMmE0MjAxMDQwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIyNzA3MDEwNTM5MDAwMDE4MDAwMDAw MWNjYjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzOTE4MDAz OTU2NjQNCjAxNDIwNDAxMDEwNTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwYTAx MDE0MTAxMDFiOTAwNDkzNWQ4MDEwMTAxMDUwMjAyMDIwMjAyMDIwMjAyODgzMzM4ZDc5ZjBhMDEw MTA1MDFlYTAwNTQwMTA5MDEwMjAyMDEwMTAzMDYwNzA5MDNlMA0KMDBlNjBhMjkwMTA4Y2U5MjE5 MDA5NTA1MDEwNjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTg4MDE5ODAwMDA1NTY3MDEyYjA1MmQwMGQ3Mjkw NjAyMDIwMjAyMDIwMjAyMDIwMTA0MDRhMTAwYzg4ZDAxMDE4YTM4OTYwMWUzMDAxYTU2ZGZiOTAx MDEwMTBhMDcwMTA2DQoyYTAxMmQ1NjAwNGJkYTAxMDIyYzAxMDEwMTBhMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyZDIxZWYxMjEwMDAwNTYw MDM1M2EwMDAwMWEwMDFiMzkwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNDg4YjM3 MWIwMDAwNmQ2YWJlMDEwNzAxMDIwNTA5MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MTA2DQowNjAxMDkyOWRjMzQwMDQ5NTEwMTA5MDkyNzAxMDIwMjAyMDIwMjAyMDIwMjA5MGM3ZjAw MzkxNzcxMjgwNGZlYjg1ZjJmMDUwOTAxMDkwMTAxMDUwYTAyMDEwMTg4NjY0OTZiMDUwMTAxNzYw MDAwMDBkNzA0MDMwMTAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjI4MDENCjBiMmQ1ZjFiMDAzNjg4MDMwMTBh YjEzOWMzMDkwMjAyMDIwMjAyMDIwMjAyMDIwMTA1Yjk0YTlhMDEwMjA1ZTgzYWM3MWUzOTAwNjAy YjAyMDEwMTI4MmMwMTAxMDUwMTAzMDMwNTljNGEzNzVmYjkwMTA3MDEwNTBjMDEwMjAyDQowMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDJkMDAwMDAxYjAw MDA5MjAwMDAwMA0KMDAwMDE5MzgxYzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDFhMWEwMDFjMDAwMDg1MDEwNDA4MDIwMTBhMDMwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDEwOTAxMjcwMWZjMWMwMDE4YzEwMTAzNTAwMTAxMGIwMjAyDQowMjAyMDIwMjAyMDIw MTI5N2E3NTE4MTgwMDRhOTIwMDAwMzAwMTA0MDEwMTA1MDEwMTBhMDkwMTAxMjk0NTAwMjEwMTA2 MDM0MzM3MTkzODAwY2MwNjAxMDIwNDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwYTAxMDcwMWU5MDAwMDM2OTMw NjJhMDkyYTdmMWE2YjAyMDINCjAyMDIwMjAyMDIwMjAyMDYwMTAzZDExODNmMDkwMTA3NTkxOTAw ZDVjMzAxMmEwMTA2MDMwMTAyMDEwNjA0MDEwMTA5MDEwM2Y2MDAxYjhiZTAwMTA2MDEwMTJhMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyNTcw MDU1MDAwMDAwMDAwMDE5MDAzNjAwMWEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAw MDAwMDAwMTgwMDAwNmZlNGY5OWM4OTJhMDEwMjAxMGEwNTAxMDYwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAxMDE0MjAxMGViYTAwMzY5ZTI5MDcwMTAxMDgwNDAxMDIwMjAyMDIwMjAy MDIwMjA3MDEwMTA0N2M4MDM2MDAwMDc0DQoyZDQyMDkwMTA1MDEwNDAxMDEwNTAyMDE1MDRlMWJl Zjg4MDIyODAxNWUwMDAwMzdkMjA1MDEwNDA4MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMjUwMDE3YWQ1 M2EwMDFjZDkyYTAxMDE2YzFjNTVlNzAxMDQwNzAxMDEwMTJhMDIwMTA2MDE4N2NlMWE5NzlmYWUN CjRiMDBhOTZiMDEwNDAxMmIwMTAxMDkwMTQxMmEwMTBhMDYwNDAxMDE0MWZiMDAzOWNiZDYwMTAx MGEwMTA1MDEwNzAxMDEwNTAxMDkwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMmUxMDAxYjM5MDA0ODAwMWMwMDAwMDAwMDAwMDAwMDAwMzkwMDAwMTkxYTAwMTkzNzAwMDA0 YTM3MDAwMDM4MDAwMDM3MDA0NzAyMDE1MDAxMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjI4MDEwOTAxNTAwMTAxMDMwMTAxMDFkNjRiMDAwMDk2MDEwNzA5MDQyODAxMDEyOTAxMDEw NjAxMDE0MTAxMDUwMTAyMDQwOTA5Mjk2MmRjOGQwODAxMDIwNDAzMDEwMTAxODgwMTBhMDEyYWU3 NTUwMDBmDQowMzAxMDExMTFiMWIwMGM3MGIwMTA2MDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjI4MDEw MTBiMDFkOTAwNTYwMDM4OGUwMTBhMDE0ZDFhZTYyYjA1MDEwMTA1MjkwMTA5MDIwMjAxMDFjNDNi MDAwMGJhMzg3NWM2MDE2MjAxMmIwMTAxMmMwMTc4NTNhMDI4MDENCjAxMDEwYTQyMDEwNDk2NDgw MDU2YWMwYTAxMDIwMTQyMDEwNzJhMDEwNzAzMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQow MjAyMDIwMjAyMDI0MDYzZmYwMDAwMDA1ZjAwMDAwMDAwMDAwMDAwMDAwMDAwNTUxODAwMDAwMDAw MWEzNmY2ODE4OWY0MzcwMDAwMzkxYTZjYTg4ZTBjMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDE3OTAxMDcwMTA3MDQwNDBhMmMNCmVjNDgwMDVmOWMwMTBhMDEyYTAxMDEwNjJj MDEyOTAxMDEyYjAxMDEwODAxMDkwNDA0MDEwMTAxMDkwYjJhMDkwMTAxMDQwMzAxMDIwMTAxMDEw MTQyMmM2MDAwNGQwMTAxMDFhMGMyMDAzNzAwNjEwMTA3MDQwMTAxMGIwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDUwMQ0KMDEwMTA0MDExZTAwMzYxYWVlMDI0MjAxMDJlZTAwN2QwMTBiMDE3YTAxMmEwMTAyMDQw NTAxMDFiNmU5Mzc5MjkwMGMyODAxMDEwNzAxMDU2MjAxMjY5MjAwZDAwNDAxMDgwNTAxMDEwMTAx MDE5NjFhNDgzNjg2MDEwOTA1MDENCjA4MDEwMjJjMDEwYjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjI4MDE0NzAwNDkzNTE5MDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAx YjFhMDAwMDM5MzZkYTQxYTAyOTAwMzcxYTM3MDA0MjAxMDEwYTAxMDYwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjUwMDEwYjAxMDQwOTAxMDEwMWY5MzUzNzM5ZjYwMTAxMjgwOTAxMDEw OTAxMDEyZjU3ZTcNCjAxMDEwODAxMDEwYTAxMDIwOTAxMDEwMTAxMDEwMTAxMDEwMjA0MDkwMTAx MmMwMTg4MjkwMWMzMTkxNDAxODgwMjA1ZjUxODM4MDBiYjAxMGIwMTAxMDYwMzAxMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAw MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAxMDcwYTAxMjkwNTRmNGIwMDE5MTk4NTAxMjkwMWJmODAwMA0KZDMwMTA2MDEwMTAy MDcwNDAxMDk0MTAxMDEyYTBiMGIwMTAxMDEwOTAyMDMyODAxMDE2YzFiMDAxNzBhMDIwMTAxMDEw NTAyMDQyODA0MDJiMzAwMDBkNWQwMDUwMTA3MDIwNTA5MDEwNzAxMDIwMjAyMDIwMjAyMDIwMjAy MDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxMjM0NDAwMDAwMDFjMDAwMDAwMDAwMDAwMDAwMDhi MDAzNzQ5MDAxYzM2MDAwMDg3DQowMTBhMDMwMDFhMDAzOTAwZTEzMDAyMDEyODAxMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTUwMDEwODAxMDEwYTA3ZWQ0ODAwMzY5NzBiMDEwMzAx MDYwMTI5MDQwNmNjZDUwMDkzNTAwOTJiMDEwMTAzMDEwMTAxMDIwNDA1MDQwMzAxMDINCjAzMDUw MzAyMDEwMTAxMDMwMTAxYTMzYWM3OGQwMTA0MDFjMTM5MDBjYjRhZGQwMTJhMDEwYTA5MjkwMTAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDAwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMTI5MDEyYzAxMDEwMTExMDAzNjAwM2ExMDAzMDEwMmFjNTVhOTg3MDQw OTQxMDEwOTA5MDEwMTAxNDIyOTAxMDIwMg0KMDkyOTI5MDEwMTA4MDUwNDE1MDAwMDMxMjkwMTAx MjkwMzAzNDIwNjAxMDEwMTA4MDYxMWQ3MDAzNzY3MmIwMTAxODgwOTAxNDIwMTAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwYTAzMDc0ODAwNWYwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMzkwMDAwMWEwMDQ4MWNlYTAxMDE4ODFhMWMzNjAwMzkzNjdmMjgwMjA3MDcwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDEwYjA2MjgwMTAxMDFiMjAwMDBkN2IzMDEw MTAxMDcwMTAxMDkwMTAxMDEwMWU4YTQwMGE1ZTcwMTI4MDEwMzA0MDIwMTAxMDEwMjAxMDEwMzA1 MGEwMzAxMDEwMjA5MDIwOTBiNzFhOTFiYzgwMzQxMDENCmI2MDAxYzRhMDA4MjAxMDUwMTA1NDEw MTAxMGEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDcwMTAxMDcwMjAxMDMwMzkwMDAzNjAwODQ0MjJjMGEwMTdi MDA0NjUwMDEwYTI5MDEwMTJhMGEwMTAxMDUwMTI4MDFjY2JiMDEwODAxMDEwODNkMWIzODdkMGEw MTJiMDEyYw0KMDEwMTAxMDEwMzAzMDEwMTAxMDE0M2VmMDAwMDEzN2EwMTAxMDEyYTAxMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAxMDgwMTAxMmVmOTM5MzkwMDAw MDAwMDAwMDAwMDAwMDA5MjM4MDBjMjAwMDAzZWNjNDEwMzAxN2ExODAwMDAxYjFhMDAwMDYwNDUw MTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNTAxMDEwMTA0MGJhZjAwNDkzYg0K ZTgwMzAxMDEwNDBhMDEwNjlmMDE4ZDAxMDYwMTcyMWQ0YTkxN2EwMTA3MDEwMzAyMDEwMTAxMDIw OTAyMDEwOTA5MDEwMTAyMDQwMzAyMjk5ZjlhMDAyMzAxMDEwMWEwM2EzNjAwMDBmYjAxMGEwMTAx MjgwMTA3MDIwNDAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMzAxDQowNjAxMDYyODAxMDkwZDFlMDAwMDM4ZjUw NjAxMmMwMTZkMDA1YjAxMDEwMjBiMDkwMjAyMDEwMTA3MGIwMzAxNWIzNzIwMDcyODA0MWUwMDAw NDUwYTAxMDEwMTBhMDEwMWI2MDUwNzA3MDEyYzAxNDIwMTA5ODlkNTM4MzljOQ0KNjMwNjAyMDE0 MjAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNjAxMjkwMWRkMDAw MDAwMDANCjAwMDAwMDAwMDAwMDFhMDAwMDAwMzcwMDE5OTUwMTAyMDMwMTJiMDAwMDM4MDAwMDM2 MzMwMDkxMDEwNzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMGIwMTA1MDU3OTUzMDAx ODVmMGQwMTAxZGQwMTA1MDEwNzAxMDEyMzg0NDViNjAxMDFlNw0KMDAxOTQ2NDEwNDAxMDEwMTAy MDkwMzA0MDUwYTAxMDIwMjAxMDEwNDA1MDIwMTAxZTEzOGUxMDEwYjA3MDFiMDFhMzkwMDMyNDI0 MTA2MDEwNDAyMDEyYzI5MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwNTAxMDcwMTAxMjkwMTAyYmVjMjM4 MDAwMGMzMDEwMTAzDQowOTg0MDBkMzI5MDEwMjAzMDEwMTBiMDkwMTAxMDEyYzAxZTYzNzNkN2Fk ZjAwNWY4NzAzMDEwYjAxMDkwMTBiZjAzODIzMDUwMTA1MDkwMTAxMDYwMjAxNTBmZjFjMDA5Mzk0 MDEwNTAxMjgwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDMwMTAy MDUwYzgyNTQwMDAwMDAwMDAwMDAwMDAwMzcwMGMyMDAwMDFlYTNiZTA3MDENCjA3MDQwYjAwNDgw MDAwMzgwMDAwMDA2ZDAxMGEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTk0 Y2EwMDM4ZDU4ZTA2MmEwMTAxMjkwMTA0MDkwMTdhMWQwMDAwOGJiOGQ5MDQyYjFkMDA3NDhkMDkw MTA5MDQwNDAxMDEwMTAxMDEwMw0KMDMwMTA5MDcwNDAxMDE5NjE5YzcwNzAyMDkwMTMxMDA5MjAw MzNhZDAxMDEwMTA4MDEwMzA2MDEwMzAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MTAxZDY0ODAwMDAzYTUxMDEyYTA0YzZjNzM2MmUwOTA1MDEwMTQxMDEwMTI4MDEwMTBjDQowMzJj YjQwMDQ5MDA0YTYzMDkwYjA5MDE1MDAxMGFmMDkyMDA3NzAxMDUwOTA3MDEwMTAzMDEwMTAxNDI1 YjMzMDBkNzI0MDQwMTI5MDIwMTA5MDUwMTAxNDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIy OTAxMDYwMTAyMDEyYTZlMDAwMDM5MDAwMGMyMDAwMDAwNDkxYjAwMWFjZDAxMDkwYTA1MDEwMjdh MzYwMDM5MWEwMDM5MDAwMGY4MDEwYTAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNTAxDQowNzg4MDEwMTA0MDEw NDAxYTc5OTAwMWM1ODA5MDkwMTJjMDEwMTI5MDIwMTA2MDEwMmFhNGE4NDZkNDcxOWY3ZDhjY2E0 NDk0OTJjMDEyODJhMDEwMTI5MDEwOTA1MDMwMTBiMmMwMTA0MDE3MjAwNmZlNzAxMDUwMWQ4MTgw MA0KNWYwMGQ5MDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDViZjAxZmIwMDE4MDA1ZmViMjgwMTBjNGQ0ODgwMmMwMTA0MGEwMTAyMGEwMTAxNDIw MTAxODgyYmI4M2EzNjhmMDEwYTAxMDI4ODAxMDRkMzAwDQowMGExMDE3OTAxMDUyODAxN2EwMzAx MmMwMTA0MDExNDAwMWMzOWMzOGUwMTAxMDQwYTAxMGEwODAxMDEwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDQwMTBiMDEwNTAxMDFmOTEyMzkxYTAwMWMwMDAwMTgwMDFiMDBjNzkwZmEyODAyMDEw MTAxMDE0MTAwMDAxYTAwMDAwMDM3MDAzYzAzMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDQwYTAxMDEwNzA5 MDEwYzQyNTgzNzAwMzkzMTA1MDUwMTI4DQowMTAyMDgwNjAxMjg2YjBhMmIwM2Q1MzRiZmZjYzM0 YjAwOWI3MDM1NGFjZWM2MDEwMThlMmEwMTAxMDkwMTAxOGUwMTAxMDUwNTI3MWQzNDIzMDgwMTQx NjIxOTAwMzcwMDkwMDE4ODAxMDUwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIN CjAyMDIwMjAyMDIwMjAxMDEyYjAxNzQzOTAwMDBhNDAxMGMwMTAxYjExYmYxMGEwMTBiMDEwMTI4 MDIwMzAzMDMwMTAxNDIwMmNlOTIyMzAxMGEwMTA0MDEwMWYwMWEzNjk2MDE4ZTAxMDEwMTAxMDcw MTAxMjgwMTAxMDEwNjAxDQphYjU2MDA0YTlhYjYwMTAxMDEyODAxMDE3OTAxMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAxMDUwMTBhMDUwMTQyMDk2Ng0KMDAwMDFiMDAxODAwMWExOTAwODMwNDAx MDEwMTQyMDEwNzA3MDY0YTQ4MDAzNjM5MDAwMDM2YjRhMDAxMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxOGUw YzAzNDIwMjA5NDA5OTMzMWIzOGExMDEwMTA2MDEwNzAxMDMwNzAxMDY5ZTM1NGMwMTAxODIxOWYy MDEwNDJjDQpjZjkyMzYwMDM3MDA5OTg5MDEwYTAxMDEwNjA3MDEwYzAyMDEwYzAxMDMxZjAwMTY0 MjA5MDkwODU0OTIzNzAwZDEwMTQyMDEwMzBhMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDEwYTAxMmEwMTRhNGE0YTM5OWMNCjA5OGUwNjAxZjcwMDllMDYw MTI4MDEwMTA5MDMwYTAxMmMyYTAxOGUwNzdmMDA5NTA2MDEwMTQyYWEwMDAwY2YwMTA1MDEwMWQ5 NWFjMzlmMDUwMTAxMjkwMTA3MDMwMzAxYjZiNTAwNWYxODEyMDEwMTBjMDEwMTAxMmEwMjAyDQow MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDQwNDAxMDEwMTA1MDUwMTAxMzQzNjYxZjYxODAwMzllOWVhNjE2 YjAxMDQ4ZTA3MDYwMQ0KMDEwMjhlMDAwMDAwMDAwMDAwNGJmYTcyMDEwMTAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwODAxMDEwMjAxMDFhMzU2MzkwMDg0MmUwMTQyMDEwMTAzMDEyYzAxMDEwOTAxZjkwMDAwODUw NDAyNTMxY2U4MDIwMzlmMDEzMDhiMWM4YjRlMDEwMTQxMDEwMTA1MDEyODAxDQowMTdhMDEwMmMz MDA2ZTlmMDEwNjAxNzYwMDAwMTkzYjRmMDEwYzAxMDEyOTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAw MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjg4MDEwMTAxMDEyZTE4MDAwMDAwODIwMTAxMDZjNjg0 MDA3ZDI5MDcwYzAxMDEwMjAzMDENCjBiMDEwODAxMGE3MjFjMzZhNjA5MDE3MjkyMDBhOWRhMmVh NjUyMTkzOTE4MDBkMDAxMDE0MTAxMGEwMTA5MDEyYTAzMDUxNjAwMzdhOWFmN2EwMTBiMDkyYzAx MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAzMDkwMTA5MDEwMTA4MDE4ZTRiNTUwNGZkMWEwMDM3 NDQwNjAxMDMwNjAxMDkwMTAxMDEwNTAxYTAxYzQ4M2EwMDE5MzdjNzAxMjkwMTI5MDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAxMDMNCjBiMDE0ZjE3MDAwMDAwMWYwOTAxMmEwMTA0MjkwNjAxMDEwMTA4MDIwMTAz MjM4YjAwNTkwMWQ2MDA2NzA1MDEwMTA4MDEyOGNkODcwNjA1MGMwOTAxMDIwMTAyMDEyOTBhMDEy OTdkMWM3ZmZjMDEwMTAzYTM0OTFhMDAxOTZiDQowMzAxMDQwMTI4MDEwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAzMDEwMzc5MDE5NjAwMTkwMDAwZmM3 YTAxMDU4OWUyMDAxMjAxMDEwMjA1MDEwMTI5MDEwMTA2MDEwNjAxYmVhNTJhNDIxMGQ1MDBiNDU0 YTkNCjAwMWMwMDM3YmNhMTUxNDIwNTJhMDEwYjA4MDEwYzAxMDEyYTAxMDQ2MWNlMDAwMDk5Yjkw MTBiMDEwMzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMTAxMDEwNzAxMDEwYTA5MDFlMzc3MGJh ODAwYjRjMWZkMDkwNDAxMGMwMTBiNDIwNzAzMDgwMTAzY2YxZjAwMWEzODAwNDgwMTI4MDEwMTAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwNDA3MDE3Mjk5MDBjMjg0ODIwMTJiZTcwMTAxMDEwMTAxMDMNCjdhNjdh YTAxMDMwMzA1MjZkNTAwNGMwYWQxMzliZTAxMGMwMTAxMjkwMTAzMDEwMTAxMDEyODg4MDEwMTA3 MDEwMTAxN2MwMGNlZWMwMTAxMjdjNTRiMDA5MjRhYTEwOTAxMDgwMTQyMGEwMTAyMDIwMjAyMDIw MjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDEwODAxMDEwMTAzMmMyMTE4 MDA0YWIwNTAwMjAxMDE3MjZmYTk2YzA5MDMwYTAxMDEyODAxMDQwNDAyMDEwODA2NTAwMWU3MWI1 NjgzMmI4MjRhZjBjZDIzZGQyYzAxMDEwMzAyMDIwMTAxMDE0MjAxMDkNCjA2MDcwMTAxMjhjY2Y1 NTYwMDMzYWUwMzAxMDMwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEwNTAzMDEwMTAxMDIwMThk DQowOTAxNGUwMDY3MDM4ZTA5MDEwMTBiMDEwMzAxMDEwMTAyMDkwMTA2NTE0YjFiMDAwMDdmMDEw MTAxMmEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTllNGEwMDAwZjNhZDAxMDkwMTAxMDEwMTA4MDEwMTJj OGYwMDFhMTEwMTAxMDEyODIzMzUwMDE2NjMzNzViOGUNCjAxMDE5ZjAxMDEwMTA1MmEyYTAxMDEw MTAxNTAwNTA2MDE2YjQ5OGJjODAxMDIwNzg4OTgwMDM1MDBjOTBhMDEwNjAxNzkwMTA4MDEwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNzAxMDEwYTA1MDEy OTJjYjgwMA0KMzcwMDk4N2EwNDBhMDFmMDAwMzQ2OTA5MDEwYTBhMDEwODAxMDEwYTAxMDQwMTAx MTAzNzM2ZWU4ODAxYzEwMDg5MDEwYjAxMDUwMTI4MDExMmM5YTU1OTc5MDEwYjA5MDEwMTBjMDEw MTAxMDEzZWNiMDAwMGM5NjMwMTAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA5MDcwMTAxMDcw MTAxMDIwMTAxMjk0MmQ5ZmUwMTAxMDEwNDA3MDEwMTBhMDEwMTI5DQowNDAxNDIwMTA3ZWE1MWEy MGUyNDAxMDgwYTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjg5ODMxOTAwM2FmYjBhMDEwMTA2MDEwMTBiMDQw MTA2MDcwMTJhZGYzOTNhYzYwMjBhMDEwMTY4MTkxOGVlYjQwMGQ4MDUwOTAxMGEwNzAxMDEwMTA5 MDEwYTI5MDEwMTBhMDENCmEyNGEwMDc4MDQwMTAyMjg5YTAwMzgwMDgwMmIwMjBhMDEwYTAxMDEw MTBiMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjcyMTkzODAwMzlhNDAxMDcwYjA5ZDYwMDAwZDkwNTAxMDQwMQ0KMDMwYTAxMDQw MTA4MDEwMTI3NTgxNTJjMjgwMWNlM2I3OTAxMDEyODAxMDE5ZTVmNDgwMDAwM2EwMDVjOGUwMTA2 MDEwMjA5MDEwNjJhMDFkYWUyMzkwMDkyZTQwNzAxMDEwNjAxMjkwMTAxMDEwMTA5MDIwMTAxMDkw NzAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAxMGEwNDAxMDEwNDA0MDEwMTJjMDEwMzA3MDEwN2Y2OTI0OA0KMDBiODNmMDUwOTAyMDEyODA5 MDEwMTA3MDVjNDI5MDEwNzAxNjAwMDkxNTAwOTAxMDQwMWQ2Y2IwMGQ3M2E4NDAxMmMwYTAyMDEw NjAyMDIwNzAxMGEwYTAxMDUwMTNmMWExODUxMjkwMTBhMDE5YTM4MDAwMDU1MjUwNDAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwNzZiM2IwMDM5MzcxNzAxMDEyYTI4M2ZiYTU2YWMwMTAxMDkwMTAx NzkwMTdhMDEwMjA2MDEwNTYyMDEwOWM1MDA1OA0KMDIwNTAxMDIwMTVjMDAwMDdmYTNmMmMwN2Yx YjZkMDgwMTAyMDkwODQyMDMwMTJjMDEwZDE2MDAwMDQ4ODMyZjAxMDQwNTAxMmEwMTA2MDIwMTA0 MDgyYTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwNDAxMDEwNDA2MDMwMTA0MDEwMTA2MDIwNTY5ZjM0OTAwMDBlZWViMDEwMTA3MDE4 ODAxMDEyYjAxMDE5YjAwNWU2OQ0KMDE0MmFkNGIwMGQwMDEwNjAxMDIyOTZiNGExYjAwYmM3YTAx MDEyYTA2MDEwNjAxMDFiZjAxMDIyODAxZGQ1ZjRhZWEwYzAxMjcwMTU5MDAzNzAwZTJkYTg4MDEw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMGEwMjJlMzYzNzAwMzg1OTI4MDE0MjAxOTAwMGY3ZTcw MTQyMDcwMTAxMmIwMTA2MDEwNzAzMDEwNjAxMDkzMTQ5NjMwMTQyMmEwMThmNDk0YWVlNzkwMTAx MDcwNzkxMWJlMw0KMDkwMTBhMDEwMTAxMjkwMTQyMDMwMWUwODAwMDAwMzlmNTlmMDEwNzAxMmEw MTAxMDIwMTAxMDEwNzBjMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDQwNTA0MDMwOTAyMDEwMTAxMGIwNWJmZTEzYTAwMDA4NDRlMDEwMjA1 MDMwYjAxMDEwNjAxMDUwMjA2ODMzOTM4MDAzZGEwMDEyZWQ1MDAzMDAxMDkwMTAxMjlmZTFjNzQy NA0KMDkwNTA3MDEwMTA2MDEwYTA1MDEyYzAxMDRkY2VmMDA5ZDA1MDEwMjAxNTkxOTAwMDAwMGQ4 MjkwMTAzMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNjAxDQowMTVkMDAwMDNhMDA1YzJiMDE3YTAx ODUwMGY3Y2MwMTAzMDEwNjAxMDUwMTAyMDEwOTA4MDYwMTA1MWUwMGZlMDEwNjAxOWZmZjAwYzkw YTBiMDE4ZTAxMDhkODQ5NTMwODAxMDgwNTA5N2EwMTI5MDkwMTQyMDEwOThhMzgzNg0KOTJjMjVk MGEwMTAxMDQwNTBhMGEwNTAyMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwOTAyDQowMjAxMDEwMTAxNDIwYTA3NzM1NTM3MzlkNWMxMDEw YzQxMDkwMTAxMDEwYTAxMDYwMTA4MDcwNDBlMDAxZTFlMWE0YjY4MmM2ODM4MDBjODA5NzkwMTAx MDEyZTQwMDEwOTAxMDEwNjA3MDEwMTBiMGIwMTAxNTA0MTkzMDAxMw0KOWYwMTA0MmI1YzE5MWIw MDM4YWIwNjA5MDEwNzAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIN CjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTA2MmMxMjAwMDAxOTAwYmQw MTAxMmEwMTE3MDA1NDg4DQo4ZTAyMDQwYTAxMGEwNjAzMDEwMTAxMDEwYWEyMDA0NzRmMDEwNDUy ZDU0OTYyMDEwMTA5MDE4ZTAxZGMwMDNhMDIwYjAxMDEyODAxN2EwMTA5MDkwMjBiMDEwMWM2MWUw MDE5MThmZjJlMDIwMzAyMDEwMTAxMDEwMzA3MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMzAxMDEwMzI5MGEwMTRlYjgzNzE4MDA2MDgx MDEwMTBhDQowMTAxMDYwMTAxMDYwMTRmYzM1ZDlmMDFjYzRhNGIwMTJmMzgzNzMyODk1YjU2NGFk OTAxMDEwNjlmMDEwMTA5MDIwOTAxMDMwNDAxMDEyOTAxNDEyYTI5MzM0ODRjMDMwMTJhMDVmMDAw MDAwMDAwOTYwNjAxMDEwNDBhMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxODgwMTAxMDE5NjAw MDAzNjM3OGMwMTAxMDEwNDhhMDA2NjBiMDEwMjA0NDEwMTAxMDIwMzQyMDEwMzA0MDFkOGE4DQow MTAxMDNkNzAwYzEwMTAxMGIwNzAxMDMyYWE4MDAxODAxNDEwMTA3MDIwMTAxMDEyOTA3MDEwMTBh MDQwMTQyMTBjZTAwMDA2ZjgzN2EyODAxMDEwNjI5MDQwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA5MDEwMTI3MDEwMTgxMWYzNzM4MWFi YWRhMDEwMTA2MGEwMTAxMGEwMTAxMmEwOTAxYWQ0NzAwMzEwMTA3YzEzNmZhDQowYTAxMTMzNzU2 NjdjNzAwNDYwMzUwMDEwMTBhMGI0MjAxMDgwNjAxMDEwYTAzMDEwMTAxMDNkMTAwOGEyODAxMDQw MThmMDAwMDU2MzZmYjBhMDcwMTA4MDEwOTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA2MDIw Mzc5MDE1YzM2MzkwMGQ1ZDYyYTAxMDE4ODEzMDAzMTJhNDIwMTAxMDEwNDAxMDQwMzAxMDEwMTA1 MjgwMTI5MDEwYzY2MWJkODAxMjgwMjAxNzkwMTAxMzAwMDQ2DQowMTAxMDEwYjAxNDEwYjI4MDEw MjJiMDEwMTAxMDkwMTAxMDg0ZDkyMDAwMGJhNGNhODAzMDEwNzA2MDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwYTI5MDEwMWM4ZTEzMzM2 MDBjMmY2NDIwMTI4MGEwOTAxMmEwMTAxOWYwMTBiNjRhNzAxMjM5MjAwMmYwMWQ2MzcxNzAxMmEw NGViZWYwMDFhMDA1Zjk5MDQ5ZjAxMDEwMTBiDQowMTAxMDEyYzQyMDEwMTBhNTAwOGMzMzYxZjA3 MDEwNzAxODIwMDM2MzczOTQ1MDEwNjA5MGEwNTAzMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjBh MDENCjAyMGEwMTQyMDQ5MTAwNDkwMDQ5NmEwNjA2MDE4ZTY2MWE5YThkMDEwNDA5MGEwMTI4MDEw YjI4MDEwMTAyMjgwMTA1MDE1NDAwNmEwNTAxMDMwMTAxMGFjYzAwMWFjZjA0MDY3YTRjOWE3NTkz M2U2MjAxMDEwMTA2MDEwNDAxDQo0MTAyMDFlNzE1NTYwMDAwNDgzZDBlMDEwMTA2MDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDENCjhmYzkw MDFiNDgwMGJiOGQwMTI4MDcwMTQyMDEwMTA5MDcwMTAxMjhhYjFiNWEwNzA5YzEzODRhYWMwYWI1 NGFkZDAxMGIwMTAxNGQ1ZjAwMzhiOTAxMDEyODAxMDgwMTAzNDEwMTAxMDIwNjAxMDFkZDMwMDBi ODdhMDkwMTAyDQo4YzM1MDAwMGNiNDYyOTQyMDEwMTAxMDEwMTA3MDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMTAxMDEwMjAyMDkwOTA5YjAzNzQ4MDAxOWI2MDEwMTBhNDMNCjE1MDA3ZmFkMDEwMTA5 MDEwMTAxMDUwYTAzMDEwMTI4MDEwMTAxZjYwMDViMDE0MTAyMDEwYjA2YjQwMDlhMjgyY2EyOTI1 NTAwM2ExOTM3MzhhMjAxMDEwMTAxMDEwNzMyNjQwOTJjMDEyZDUzMzgwMDAwMzc1NzI1MDMwMTA1 DQowNTA5MDIwMTAxMGEwMTAyMDQwNTAyMDEwMjA3MDMwOTAyMDkwMzAzMDEwMTAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMTAxMDEwYTA1MDEwMTAyMDkwNDAzMDEwOTA1MDMwMTAxMDkwOTAxMDMwNzA0MDFiOWVl MDAwMDE4MDBmMzQwMDEwMzA0MDkwMzAxMDEwNDAxMDENCjBiMDFkODdjMTIwMDAwZWIwMTAzZTkw MDkxNTA3NzM5ZGU0MjAxMGIwMTAxYTBhYjg5MDE0MTAxMjkwMTA5MDEyODAxMDEwNjAxMmEwMjcx ZDUwMGJiMmMwNzAxMDFlYzNhMDAzMzAwZGY5ZjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDEwMTAxMDIwMjA5MDkwOTAzNmQwMDNiMDAxZDdhMjgwOTAxMGExMjFjNTY4 NzA5MDEyYjA3MDEwMTAxMDEyYzAxMGINCjAxMDYwMTgxNDYwMGFhMDUwMTA0ZDQ3NTAwZDViOTA5 YmYwMDFjZDdlODBjMjk4MjM5NTZlMDBiMDQwMzQyNjE1NjAwYTAwMzAxMDkwMThkMWYwMDM5MDAw MGY4YWMyYTAxMDEwMTA0MDUwMTAxMDkwOTAxMDEwYTAzMDEwMTAxDQowMTAxMDEwMjA5MDkwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDUwOTAxMDEwMTAxMDQyODAzMDEwMTA0MDEwMTAxMDMyODAxMDEyYzAxMDFl MGJjMzcwMDAwMDBkYmE4MDEwYjA3MDIwMTAxMjkwYTAxMGEwNjcxNGQwMDU2OTIwMDRhMzdmMTBi MDZlY2ZmMDA5YTJjMDANCmE1MDE0MTAzMGEwNDAxZWIwMTAxMDIwMTA5MDEwMTAxMDEwYzAxMmMw MTAyYWRhNDAwMTIwODg4MDEwMWJlOTEwMDAwMDBmMzI3MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEwMjAyMDIwMjA5MDkwMjdhNWUwMDAwMWFhNGZkMDFiZjAx MGJmNjQ4NmYyZDAzMDkwMjAxMDIwYTA0MDEwMjBhMDEwYjA5MDEyZjk5YzI1NWNkZmYzYTAwYzI3 MjAxMDMNCjFkMzgzYjA5MDEwMTAxMGExMTM2NmQwNTAxMDEwMWIwMzkzMTA2MDYyODI4MDY0MTA5 NjMzZGE5NDgwMDAwZjhkNjI4MGIwMTAxODgwNTA0MDUwNTAxMDEwMTA2MDEwMTAxMDEwMTAxMDkw NTAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMTAzMDUwMzAyMDIwMjAxMDkwMQ0KMDEwOTA1MDQwNzQyMDQwYTAx MDRlYTdlMTk1NjM3NTZiMjcyMDEwNDAxMDEwMTBiMDEwMTAxMDUwMTAxNzkxZDM5NmRhNzBjODkx NDAwMzdjNDAxMDFmZDM0MWEzMDNkMDAwZTAyMDEwMTAzMDQwMTAxMmEwYTAxMmEwNDAxNzkNCjAx MGIwMTA5MDU5NGNhMDBiMzBjMDEwMTAxOTRiODAwM2EwMGIwMDE0MTAxMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDkwOWRjYTkwMDFjMDA5 OThmMDEwMTAxMGI5ZTQ4MDA5NzBhMDEwMzJjMDE0MjAxMDMwNDAxMDIwYzAxMDE2MzNjMzMxODU1 NDdhNTYyMDYwMWQzNTYzYWJlMDEwNTQyMDkwMzI5NTUwMDAxMGIwMTY4MTkNCjU2ZDQwMTAxMDEw MTAxMDEwMTAxMGIyZDUyMWQwMDAwMDA3NDY0ZTc4ODAxMDEwMTAxMDUwYjA1MDEwMTAyMDMwNDAz MDIwMTA5MDQwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTA5MDIwMzA2MDUwMTA3MGIwMzAxMDEwOTAxMDEw MWFkYmRiODAwMDAxOTU2NzNiZQ0KMDMwOTAxMDEyODhlMDEwYTBhMDEwOTAzMDQyOWQwMDA1YTBi MmMwYjAxNDE3ZDAwZWZiZTc5MDFiMzAwMzdmNWE5YWYwMTAxNDIwMTBhMDEwNzA3MDEwNjA2MDEw OTAxMDEwYjAxMDFhYTM0MWNhZTA2MDEwMTA3YTJhNDAwMTgNCjFiZDVjODAxMDEwNjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyDQowMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA3MDU0MGMy MDAzNTAwOTI3Nw0KMDEyYzAxMmNhY2JhMDBjZjA0MDEwNzA0MGEwNzAxMDIwNjAxMDMwYTAxMDIw MTQwNjMyZWRkMDEwMTAxMDg5MTAwYjcwMTBiMDgwMTA3MDE3OWE5MzkwMTJhMDk2MDAwM2UyYzAx MGIwMTI4MmIwMTA3ODgwMTAxOGUwOGFlYmENCjAwMWEwMDAwNmQ2YzA2MmIwODAxMDEwMzI4MDMw MTAxMDMwNDAzMDkwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA1MDIwMTAxMDEwNzBiMGEwMTAxMDk1MDA1 MDE3OTdiOTM0YTAwMDA1NjU0YmQ1MDAxODhmYzAxMDMwMTAxMDEyOTAxMDEwNzA2MDEwMWViM2Ex YQ0KOWYwMzAxMDEwNzA2NDE1ZjE4YjIyYzA2MDE5YzAwMWIwMDg0MDEwMTAzMDcwMTAyMGIwMTAx MDYwMTAxMDcwMTA3MDEwNzRkMDBkNWQ5MDQwMTA3MDU2ODE5Mzc1ZjAwYzJmZDQyMGIwMTBhMDIw MjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwOTA5MDIwMjAyMDIwMTAxMmEw MTAxMDdiZTQ3MDAzNjAwMDBjNDAxMDEwMTUwODEzYjAwYWE5ZjAxMmIwMTA1MDEwMQ0KMDcwMTAx MDQwYjAzMDEwMTI4MGEwMTAxOWYwOThkMDAzODBjMDIwMTA5MDYwMTBjYzQwMGI1MjkwMWU0MDAz NTQxMDEwOTBjMDkwOTAxMGEwMTAxMjgwMTAxMmEwMTA2ZjA3ZjFjMzYwMDAwMWJhZjcyMjgwMzAy MDEwMTAxMDENCjAxMDEwMzA0MDkwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwNTA5MDIwMzAyMDEwMTAxMDEy YzA0MDFhMmYxMWEzNjQ4MDAwMGQ3YmQ0MzAxMDE0MTZlYjViZTAxMGIwNTBhMDEwYTAyMDEwMTA3 ODgwZDQ5MzYwZTI5MDIwYTk0NDQ5MTE4MDAwMDY4MDEwYjAzYmIwMA0KMTk1ZDAyMmEwMTQxMDEw YjBhMDEwYTAzMDEyOTAxYTAwMTA1NzYwMDc0ZWMwYjAxMDIwOTQ0MWExODAwMDA4Yjg5MDEwMTAx MDIwNTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIN CjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDkwOTA5MDIwMjAx MDEwMTAxMDE0MjA0MDFlYzkxMDAxYTAwMDBjNDhkMDQwMTAxZDRhNDAwMjBlYjAxMDE0MjA2MDEw MTA0MDEwMTA5MDEwYjA5MmMwMTAxMDUwMTAxYTAwMA0KZjEwMTAxMDgwMTAyMmEwMTAxMmU2ODA2 ZTc2ZjM4Y2VkNTAwZjhiNmEwMDEwMzAxMDIwOTAxMDEwMjA5MDEyYjA2MGEyZTRjNjYwMDFjMDAw MDM1NWJhODA1MDEyYTA1MDEwMTAzMDUwMzAxMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDEwYTA4MDUwMTA5 NTAwYWZlDQo0NTVmMDAxYTM4MDAzYTNlODEyYTA1MDEwMTA1MDM5MzAwOTYwMTAxMDEwNjA1ODdi NjUwMDEwMTAxMDFlMjkyMWRkZWRlZWUwMDAwY2FiYmJiNmY1NjBiMDMwMTAxOTFmNDAxMDcyYTAx MDkwMzAzMDEwMjA5MDEwMTAyMDEwNQ0KMjc5YzAwZWY4OTAxMDEwYzQxZDIzNjAwMzUwMDlhNDMw MTBiNDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwOTA5DQow OTAyMDIwMTAxMDEyYTBiMDE0MTBiMDEyOWFmMWEzODAwMDA3NjBjMDIwMjAxYmU1NDAwOWJlYjI5 MDEwMjA5MDEwYTBhMDEwYTAyMDMwMTAxMDMwNTAyMDkwNTQzMzZiYTQyMDMwMTBiMDIwMTA0MDcw MTAxMDExMzM5MDBiYQ0KZjhkYjU1MDA3ODAzMDMwMjAyMDEwMTAxMDIwMTAyMDEwMTJhMDEwMThk NmNiYjZmMDAxOTFiMDBiY2QyOGQ4ODA0MDEwMzA1MDkwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMzAxMDEw NDAyMGJjOGUzZWYxODAwMTkxOTM1MTQyNjQyMDQwMTAxMDIwMTAxMDQwMjZjDQo0ODFiYWQwMWU4 MzFjMjAwMDA3ZmExOWYwMTQyMDZhNDAwMDAxYjM3NTNhNzc5MDFiZjhiMzgyZjAxMGIwNDQyMDEw NDAxMDcwMTAzMDIwOTAxMGEwMTAxNDEwMTAxNGY5MzAwOTE4NzAxMDEwNTJhNWQxYzAwMzcwMGU5 MDYwMQ0KMDEwMTAxMGEwMTA5MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMDAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIyMDAwDQo0ODAwMDBiNDg4MDIwMTJhMDEy MTAwOTM1MDAzMDEwMTAxMGIwOTBjMDEwMTAyMDIwMjAyMDIwMjAyMDIwMWJjMzdkOTAxNDEwMTJh MDEwODAxMDEwMWRjY2EwMGNkNzkwYjAxZDkxZDAwMTAwMTJhMDUwMTI5MGEwMzAxMDEwYg0KMDQw MTA5MDUwNTAxMDE4ZGUzNjAzNjAwMDAxYzAwOGI2ZTcwODcyOTAxMDEwNDAxMDEwMTA5MDEwMTBh MmEwMzAxMDkwYTAyMDEwMTA2MDEwMTAyMDUwMzAyMDIwNTAyMDEwMTAxMDIwMjAxMDcwNDA5MDMw MzA5MDMwNDAzMDINCjAxMDEwMTAyMDIwOTAxMmEwMTA1MDMwMTI4MDEwNzAxMGEwNjAxMDkwMTA3 MDIyOWZkZjAzY2MyMWIzNzAwNTYzYTc0YzQ4ODA5MDMwNTAxMGIwMTAxMDcwMTAxMDEwYmUyNGEz MTBjOTEwMGE0MWY1ZTkyMDBkYjA1MGEwMTg4DQo5NTNkOTA4MjAxMDUwNjA1MDI2NjAwZWEyODAx MDUwMTAxMDEwMjAxMDEwMjA1MDIwMzAxMjkwMTA2MDFhMGI4MDA0YzBhMDEwMTA2MGRiMTAwMDAx YTAwMTYwOTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEyMDAwMTkwMDAwOWEyNzI5 MDEwOTAxM2UwMDM0MTEwNTA1DQowNjA0MDEwMTAxMDYwMjAyMDIwMjAyMDIwMjAyMjg3MjMzMDBi MzAxZThmNjFlOGUwMTAzMmNhYjAwZGIwMjAxMDEwMTAyOWMwMDMwMjkwMTAzMDcwMTA1MDEwMTA1 MDEwMjI5MDEwMTAxMjgyODAxMDEwMWFkZjBiYzAwMzcwMA0KMDAzNzQ4NjY1ODk1OWYwNjAyMGEw NDAxMDEwMTAxMDEwOTA5MDEwMTAxMGIwMTA0MDYwNTAxMDEwMTAyMDEwOTA1MDQwMjAxMDIwNDAx MDEwMjAxMDEwMTAxMDEwOTA5MDEwMTA5MGEwYTAyMjgwMTAzMDEwMTA4MDEwMjBhMDENCjA0MDEw MTJjYzVlMDNkOWExOTAwMDAzNjM3MDAxZDk3N2EwMTA5MjkwNTAxMDEwYTAxMDEwNDAxMDEwYjAz MDE5NDAwNGE3MDAwMWYyYzAxMDRlYTZmMDA2ZTAxMmMwMTAxMGEwMTAxMDQwMTAxMDFkOTRhNTYw ZTA5MDUwMTAxDQowMjA0MDQwOTAyMDMwMTAyMDEwMTAxMDEwMWY5NmYxODFmMDEyYTAxMmEwN2Y1 MDAwMGMyMTllOTJhMGIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjdhMDE3MDQ5Mzkw MDQ4YmM3YTBjMDE0MjQyNWQxYjQ5MjJhMDAxMDFkZDAxMDcwNjAyMDIwMjAyMDIwMjAyMDI0MjAx DQphMzRiMWIxOTFiMDAzODZhMmIwMzQxMThlMjJhMDEwNDJjMDEwMWRjMDBkNzAxMDgwMTAxMDQw M2EwMDEwMTA3MDEwMTAxMDUwMTAzMDkwYTA4MjkwMTAxMjhlYjc4MjFhOTAwMDAwMDAwMWMwMDQ3 MTRiM2FkMGIwMjAxMDcwMQ0KMjgwMzA5MGEwMTAxMDEwMjAzMDEwMTAyMDUwNTAxMDEwMTA5MDkw MjAyMDIwMTA3MGIwOTAxMDMwNDAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMjAxMDEwNTA5MDEwNTA0 NjNlM2UxM2IzOTAwMWEwMDAwMDA4YjFlYTY0MDAzMDENCjA5MDMwMTAxMDMyYjAxMGIwMzQxMjkw MTA3MDEwNDA0NDFhNTAwMzhjMjBhMDEwMTAxMDY3MjU1MDBhMzAxMmIwNTAxYWQ2N2U3MDIwODY4 MTkwMDhhMDYwMTA0MDEwNDA1MDIwMTAxMDEwMTAxMDIwMjJjMDEwMzVjMzg5MmYyDQowNjAxMDFh MDI4ZTIwMDAwMWIzYWQyMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTA1 MmFiNjNhOTIwMDU2ZDUyNjA5MDMwMTA5Yjk0NzAwYzliOTA4MDEyOTAxMDEwMjAyMDIwMjAyMDIw MjAyMDEwMzAxOGRlZGQ1NzU2ZDBmMDEwOTA0ODMwMDVkMDEwYzAxDQowMzA5MGFkNDAwYTQwMzAx MGM4MWU5Y2VlMjkyNWI0MDA0MjgwMTA5MDQwMTAxMDEwMTAxMDEwMTAzMGIwODA3MDM2MmIzZWU0 NzQ4MTkwMDFjOTIxYzFhNzQ2N2ZiMmZlYzQyMGE0MTAxMDIwODAyMDEwMTAyMDEwMTAxMGEwNA0K MDkwMzA0MDMwMTAxMDEwMTAxMDEwMTAyMDMwYTAxMDkyODQyMDMwMTAxMDYwMTlmMDFlNzYzNzJi N2MzNDc0YjAwMDAxODAwMDAwMDM1NTdiMzQzMDQwMTAxMDEwMTAyMDEwMTA2MDUwMTAxMDkwNjAx MDEwMTAxMDcwMTA1MDENCjQxMjQ0YTAwNTgwMTA3MDYwYjA0MDFlZDAwYTQwMTBiMDEyNzUzNGE0 OTQ2NTYzOGE5NjQwMTAxMDcwNTAxMDMwOTAxMDEwMTAzMDIwMjAxMmMwMWViZDcxYWQ3YTcwMTBh MDEyOTI0NTUwMDQ4MDA4YmY0MDEwNDAxMDMwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAxMDcNCjAxMDI2MWNiMzYwMDAwMzVlYTJiMDEwNDI4MDdmMTFjY2E3YjAxMDEyOTAxMDIwMjAy MDIwMjAyMDIwMjBhMDMwMTAxMDEwOTAxMDgwMjAxMDExMDAwY2IwZDAzMDEwMTAxNDEwMTVkMWIx NjAxMGM5NDQ5MDAxYzZmNTUxYjFkDQplNDBiMDEyODAxMGEwYTAyMDIwYTI4MDcwMTAxMDEwMTAz MGEwNDBiYmY0MDkwZjE0ODAwMWIzNzFhMDAwMDFjMDAzNWM3NWU1OTIyYTg3MTBkYWQ0ZjA1MDEw MzAxMDkwYTA0MDEwMTA0MjkyOTAxMDEwYjA4MDEwMTAxMDEwMg0KNDI0ZjhkYzZkOGQyZWRiYzU0 MDAwMDM1MDAzNzAwNGEwMDM3MzM5ODlkODcwMzBhMjgyYTI5MDcwNDAyMDEwNDAxMDEwMTAxMDIy YTAzMGIwMTJhODY5NTAxMDcwMTAxMDEwNjdlNDkzYzA5MDEwMTAxMDE0MjUwMzYxY2I5MDENCjA0 MDk3OTVlY2I0OGM3MTY0MDAxMDE0MjAyMDEwMTAxMDEwMTAzMDcwNzAzMDEwMTAxNjE0ODFiODMy NzA0MDEwYjAzZGEwMDAwNTUwMDQ5ZDkwMTA3MGIyODAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwNTBhMDkwMTAxNmI2ZjAwMWEwMGE5YWUwMTQyMDEwYTAxOWQNCjFhMWEzMDJiMDEy YTAyMDIwMjAyMDIwMjAyMDIwYjAxMDMyYzA3MDEwMTBhMDE4ZTAzZjMwMDAwMDgwYjAxNDEyYTAx OWZjYjAwMjMwMmFkNDgxYTZlODk0ZjAxMTEzYTAwZjQwMTI5MDEwOTAxMDIwMzA5MDEwMTA5MDUw NjAxDQowMTAxMDEwMTAxMGEwMTAxMDdhODk3NWI1ZTQ4NWYzODAwMDAzNzE5MWMxYzAwMWMxYTAw YTlmN2I0NzVmMTc1MzIxZjk2Zjk2NDg2YTNhNmQyZTliNGYxZDFiY2E1NTQzNjAwMDAzOTE4MWEw MDNhMDAxOTM3MDA1NTE5N2UxZg0KOTY4NzAxMDEwMTA1MGMwYTAxMDEwMTAxMDEwMTAyMDEwMTA0 MGEwNTAxMDEwMTBhMDFlYzM4ZDU0MTA0MDE3YTBhMDFlYTkyMWIwNDBiODgyODAxMDQwMTZlMDA4 YTAzMDEwMTA5MDE3MjJkMDEyYTAxMmM4ZTAyMDEwOTAxMDENCjAzMDcwNTAxMDEwMTAxNTBlMTFj NDg3MDA0MDEwMTJhMDI5ZTAwMzc1NjAwN2Y3MjAxMDkwMzA0MDEwNzAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDEwNjAxMmE0MTBiOGVmODAwNTUwMDAwN2U4ZTAxMjkwOTA0NzEzYjRh YTQ4NzAxMDIwMjAyMDIwMjAyMDIwMjAxMGINCjA5MDEwMjA2MDQwMTA2MDFlMDAwMDA0OGZjMDEw MTA5MDIwMWI3MDBhNGU3MDE4MzM3OTgwNjAxMGIwMTAxODkwMDE5ZWIwMTg4MDEwMTAyMDMwMTAx MDEwNTI5MDEwMTAyMjgyYTA3MDEwMTAzMDEwMTQyMjkwMTAxMDQ0MjI1DQo4YzNlYjE3NTE5MDAx YjAwMDAwMDAwMDAwMDAwMWIwMDAwMDAzOTM4MzcwMDM4MWMwMDAwMDAwMDFhMzczNzAwMzg4YjU1 MDAwMDAwMTgzMjliMjI4Y2RhMDEwMTAxMDEwODA1MDI0MTBhMDEwMTAxMDcwYTAxMDEwNTQyMDUw MQ0KMDEwNjAxMDEwNDAxMjgwMTAxODg3ZTAwOTUwYTAxMDEwMTAxODhlZTAwOTYwMzAxMDEwOTAz MGRlZDM3YWE4ODBhMDMwMThlMDEwMTAxMDgwMzAxMDEwMTA0MmMwNDAxMDkwYTAxMDEwMTg4MmRi MDkyNDhlODA2MDE0MjA2Y2MNCjE3MTkwMDM2M2FmMzhlMmIwMTAxMDEwMTI5MDEwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDIwMzAxMDEwMTI4MGI4MzAwMzcwMDM1MzVlYTAxMDEw MTBhMDkxNDAwM2FjNDAyMDIwMjAyMDIwMjAyMDIwNTAxMDEwYTAxMDEwYjAxMDEwNjlkZWZiZDAw N2QwYjAzMjgNCjAxOGMxODM3ZTMwMTBlMTkwMDEwMDEwMTAxMDIwNDBiYzkxODcwMDgwMTAxMDIw OTAyMDEwMjA5MDEwMTAxMGEwNTAxMDEwMTAzMDMwMTBhMDQwMTAxMDkwNzAyMDE4ODAxMDQwMTAx N2EwN2M0YzQ3ODg2MzFhNWY3ZjhmN2YzDQpmMWVmNDgwMDAwMzkzNzAwMzY1NGYzZDE3ZTliMzI3 ZTE2NDRhNjk3ZDgyOTJjMDEwMjAxMDEwNTAxMDcwMTg4ZmQ4ODAxMDEwOTBhMDMwMjAxMDIwMzA0 MDIwMTAxMDUyNmE1NTYwMDQ3NTdiZTA5MDEwN2M0Mzc5MTAxMDEyYw0KMDkyODAxMmUwMGI1MDg0 MjAxMDkwMjAxMWUwMDczMDEwMTBiMDEwMTQxMDUwNzAxMDcwMTAzMDMyODAxMDQwMTAxMDkwMTAx OGRkYTM5MWNkZjAxMDIwMTQyMDFhYzU1MDA0ODFiMDBmMTI4MDEwMTA0MDIwMTA1MDkwMTAyMDIN CjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDAwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMmNmMjM3MDA0YTAw NDk5YzA4MDEwYjA0MDc4YzVmMDAxNjQyMDEwNDAxMDE0MTAxMDEwNTA5MDEwNjA5MDEwNzAzMDEw YTAxNjJmNTFjZWRkNGU4MTIwMDAwYTE0MjAzNjcwMGY3MDEwOTI4MDEwMzA1MDENCmRiMDBhMTA0 MDcwMTA5MDEwYjAxNDIwNDAxMDQ0MjAxMGIwMTAxMDEwOTI5NDEwMTAxMDEwMTA3MDkwNTBhMDEw MTA5MDEwNDA5MDQwNDAxMDEwMTA5MDMwMTAxMjkwMTAxNDIyN2EwNzk0M2EwZGQ3OTA0MDQwMTAx MDMwMTI4DQowMTAxMDcwMzAxMGEwMzAxMDEwMTA5MDkwMjAyMDc1NDAwZGQ3OTAxMDE4ODAyNDEw MTI4MDEwMTA1MDE0MWYxMDAwMGIwZmY0YTFjMzM3YjAxMDEyOWUyMDBiOTAxMDEwYjAxMDUwMWE1 MDAxNTAzMDEyYTAxMDU2NjFiZWIwOA0KMDEwMTA1MGEwMjAxMDcwMTA5MDkwYjAxMjkwMTAxMGEw NjAxMDFiZmFmMDA1NjdiMDUwNTAzMDFlOGU1NDgwMDM5NDgxYTNlMjkwMTAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQow MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNjAxNjRi NTFiMzYwMDM3NWU4ZQ0KMDEwMzAzMDFmZGE0NGE1Zjg3MDEwMTA2MDEwMTBhMDIwMTAxMDUwMTAx MDEwMTAxNDIwOTAxYWQyMDM4MDAwMDAwZDU3MzYyMDEwMTQ2OTJjMDA0MjgwMTAxMDgwMTA0OTgw MGEzMDIwMTA4MDEwNTAxMDQwMTAxMmEyMjEwODgNCjAxMGEwOTA5MDEwMTAxMDEyODg4MDEwMTA1 MDEwMTAzMDQwOTBhMDQwMTAxMDEwNTI5MDMwMTAzMGEwMzAxMDEwMTAxMDMyYTA3MDEwNzI4MDEw MTA2MjgwMTA5MDEwMTAxMGEwOTAxMDEyODAxMGEyODBiMGIwOTAxMDEyYWIwDQozNjcwMDEwNzJi MDEwMTAxNTAwMTAxNjIwMTA5ODU1NmNiOGYwNjBiNzk1ODAwNDZhYzI4MDE5YzAwNWMwNzAxMDEw MzAxMDdhYzE4MDAzY2E2MGJkOTM0MDBjZDJhMDkwMTAxMDMwOTAyMDkwMjAxMGIwMTAxMDEyODAx MDcwMQ0KMDUwNTgxZDUzODkxYzYyOTAzMDEwMmViOWIwMDAwNWYxYjM0NzgwMjAxMDcwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDEwMzAyOTRlZTAwMDA5MjM5MDBhODAxMDYwMTAzOGU1YTE4MDBmNjUwMDEwOTQyMDEwMQ0KMDMw NDAxMDMwYjA1MDQwMzAxMDEwMjAxMGMyNDU5ZTE4YWEyMDMwMTA5MDgxOTFiYjYwMTAxMDEyODA0 MDlhMDU2MWEyNDAzMDcwMTBiMDUwMTJjMDIyODBlNGEwMGU4MDcwMWM0MjkwMTA4MDcwNDAxMDEw MTAxNDEwMTA1MjgNCjAxMDEwMTAxMDEwMzAyMDEwMTBhMDQwMTAxMDcwNTBiMjkwNTAxMDEwMTA3 MDEwMjA2MDcwMzAxMDEwOTBhMDEwMzI4MDEwMTBhMDIwOTAzMDEwMTAxMDIwMTA0MDFkZTAwMjEw NzI4MDEwYTA2MDEwMzI5MDEwMTAxNTA5MjAwDQpjNjAxMDkwMTAxMGI3NTAwMjEwMTAyOGQzNzky YzUwMTJjMDMwMjAxMDlkMTAwMDA0OTNhMDA1ZmMwNDEwMTAxMDEwOTAyMDEwMTA0MDcwMTAzMGE4 ODAxMDEwYTAxMDUwYWZiMDA1NjMwNzkwMTJhMDEwYWE3Mzc5MjFhMTgwMA0KZWVlODAxMDkwMTAx MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjA3MDIwMTAxODgxMmMyMDAwMGQ1MDBkZjAxMDgyODAxMDEwZmNiMWI0NjExMDkwMTA4 MDEwMTAxMDEwNzA4MDEwMTI5MDEwMTI4MDYwMTAxMGEwNw0KMDEwMTAxMDYwNjAxZDUzNzBmMGMy ODA1MDEwMTBhOTAwMGUyMDIwMTAxMDEwMTAxMDEwMTA1MDE1YzAwYTUwMTAxYWMzNmNhNzkwMTAx MGEwMTAxMmEwOTAxMDYwMTAxMDEwNjA0MDIwYjAxMmEwMTAxMDMwNzAyMDEwOTA1MDENCjAxMDEw MTBhMDQwMTA2MDkwMTAxMDQwMzA1MDgwOTAxMDkwOTAxMDcwYjAxMDEwMzA1MGEwYjA5MDEwMTAx NmEwMDk5MDkwMTIzMjEyMTY1ZDQwOTAxMmEwOWZiMzk3NTAxNTAwMTI5MDIwNmI2NDg0OTI5MGIw MWRmMDA5ZTAxDQowYTAxMDEwNTAxNjM0YjM2OGNiMzhjOGQyODA0MDEwOTA1MDUwMjAxMDEwMzAx MGEwMzAxMDkwMTAxMjkwOTgyNTQzOTU1NjEwMTBhMmEwMTQxMjAwMDM4MDAwMDU2OWQwODAxMjgw MTAxNDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDINCjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy DQowMjAyMDIwMjAyMDIwMTJhMDEwMTBiMDFhMmNlMDAwMDAwNTZiYTYyMDMwMTA5MGI3OTIwMzMw MGVlYzYwMTAxMDE4ODA1MDEwMTAxMDEwMTA5MDkwMTAxMDY4ZTBhMDIwOTI4MDgwNTAxMDE3MzAw MTUwYjAxMGEwOTA1ODE5Mg0KMDA2OTJhMDEyZDNlZjNiMWJkNGYyOTAxYTQ1NWYwMDEyYzk1Mzk5 MzAxMDMwMTA5MDZjODUyNjgwMTA0MDkwOTA0MjkwMTAxMDgwMTAxMGEyODAxMDEwNDA0MDEwMTI5 ODgwYTAxMDIwOTAxMDIwMTA5MDcwNDAxMDEwMTAxMDkNCjAxMDIwYTAxMDEwMzAxMDQwYjAxMDEw NDI5MDEwNjQyMWExYmFjNDc0YTAwMDBjYjAwYWY4ZTAxMDEyMjAwYWYwMTI4MDIwMTg4MDEwMWE0 MDBiMzAxMDcyZDM3MzQyYjJjMDcyOWU1YTAwMWE1Zjc3MTAxMDcwMTJhMDEwNTA1DQowMzAyMDIw OTA5MDIyOTAxMDEwMTBiMDEwMWFkZWU0YTAwZTE3OTI5MDEwMzAxYzZhNDAwMzkwMDAwZWYyZjA1 MDEyOTAxMDJhMDAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjBhMDEwOTA4MGEwOTA2MmFiMTAwDQo1NjAwMDA1ZjQ0MDUwMTAx MDEwNWZlMzIwMGE5OTY4OTAxMDEwMTAxMDEyODA3MDEwMTBhMDEwOTAzMDEwMTAxMDkwMTAxMDEw MzI4ZGQzNDAwYzQ5ZjA5MDQ4OWNhM2E3ZThlMDEyZDkyMDAzNjAwMzk2ZjljYjk1NjAwMmMwMQ0K MDcxNjAwZjkwMTBjNDEwMTAyOWUwMGVlMGIwMTJlMTI5MDk3ZGE4OWZkMDkwNTAxMDEwMjA0MDEw MTAxMDMwMTAxMDIwOTAxMDEyODA5MDEwNTA1MDEwNTI5MDQwYTA5MDkwMzA0MGEwMzAxMjgwMTAx MDFiZmM0MTEwMTAxMjkNCjgzMDBiMGE5NWNlODcxNmM5MjAwMTQwMTAxZDIwMDgzOWYwMTA5MDYw MTJhMDkyMDAwYjcwOTJhMDE5YTFjMTI3OWFhM2E1NjZkMjgyYTQyMDEwMTBhMDEwMTBiMDMwOTAx MDEwMTA0MDUwMjAxMDYwODA2MDE2MmFhNDgwMDdlDQo3MjA2MDEwMTA4MDFkZWNiMDAwMDFhMDBk YmJmMDEwMTAyMDMwNzAxMDEwOTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTBiMDEwMTA5MDIwMTA3MGI0NDAwMTgwMDRhMDAy MDhlMDU4ZTAxMjgwOTY5MDAwMDUzDQphNzA0MDEwYjA0MDEwMTBhMjgwMjAxMDcyYTA5MGEwNzA1 MDEwMTA5MDkwMTAxNTE1NDAwNGFjOWY1MDAwMGNiZmUwMTc5Yjg4YjQ2ZTAyZWVhOTgwMDM5MDBi MjBhMjcwMWNlMTg3ODJiMDEwMTAxMjlkZjAwZTUwMTI4MGU5Mg0KMDBhOTM2MTk0OGM3MjJjODAx MDFiOTdiMmQwMjI5MjgwYTAzMGEwNjAzMDEwMTAzNDEwNzAxMDEyOTAxMGIwMTBhMDE0MWE2ZTMw MTAxMDEwNDJiOTUzNTYwMDEwMjA1YjExODAwYTEwYjAxMjgwMTI0MzY1NjhmMmE3OTM5MDANCjhl MDEwMTAxMjgwMTA1ZjIwMDY3MmMwMTAyZjAwMGI1MDBjYmJhYWZkZDAzMDIwMTAxMDEwMTJhMDMw YjAxMDIwMTAxMDEwNDA1MDkwMTA4MDEwMTUxYjUwMGNiODIwNDA5MDE0MTAxYWQxNDAwM2EwMDky MDBkMzAxMDQyOTAxDQowMTAzMDEwNDA3MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwOTI4MjgwMjAxMDMwMjAzMDJhZDhi MDAxOTFiMDBhOTk1MDEwYjA2MDEwNTI5OTAxYzAwNWJmZDBhMDIwOTAxMDkwMTAxMDYwMTAxMGIw MTAxDQowMTA5MDQwMjAxMDMwYTAxNDA1ZGQ3MDAwMDhiZWQyYzA5MDE3MjAwMDBhZDAxMDUwMTJh NTIxYjAwYTYwMzAxZGMwMDE5MDEwMTBiMDYwMTI5ZTIxYmZlMDEwMTcyMDA5OWY0NGQyMTQ2Mzkw MDNkYmYwMTEyMWNkYjA5YzY5OA0KMDBiNzBhMDEyOTAxMDdmMjAwNWY3ODAzMDEwOTAxMDEwYjAx ZGM0YjRhNzkwMTA1MGEwMTEwMDA0OTBhMDIwMTZhMDAxYWI2MDMwNjAxMjgwMmU5MWNjOTAxMGMx ZDFjY2QwYTAyMGIwMTAyMDFhZjM3YmIwMTA0MDEwMTE4MDANCmRmN2QwMTAxMDEwNDAxMmIwMTA3 MDEwMTAyMDEwMTA0MGEwMjAxMDMwNDAyMDQwMWZjZDEwMDFhMjIyYzA0MDUwMTI4MDFmOWZmMDA0 YTAwMDA3ZmM1MDkwYTAxMDEwMTA5MDkwMTAxMDIwMTAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MTUwMDE0MjIxMDAzOTAwMTkwMDVlZGQwMTBhMDkwMTA5YTg5MTAwMDBlM2ViMDEwMTJiMDEwMTJh MDEwMzBhMDQwMTAxMDQwMjAzMDQwMTAxMDIwOTAzMDUwNzA2MDYwMTA3DQowNDAxMzAxYzRjMDMw MjBiMDEwNDBkMWExYTlmMDEyOGQ5MDAzNzcyODEwNDAxMDc3MTAwMDA4ODAxMDNlNDAwODUwMWEw MDEwMTgxMzQxOWE2MDFmMjAwZjI0MjA1YmUxYTE4ZTAwNjAxMDRmZDU1MWMyMzAxMDYwMTAxMDEw MQ0KMDEwMTI4ZDUwMGQ4MjgwMTAyMDNjYzFjMWMwYTA5MDMwZDAwY2UwYTJjMDEwNTA1MDFjYzAw MDAwMTA2OWMwMGI1ZTgwMTA2MDkwMTJhM2ExOTJlMDEwNzAxMGExMTg3MjgwMTAxMDEwOTA5MDcw MTA5MDcwMTAxMjkwMzBhMGENCjA0MDIwMTAxMDkwYTBjNGQzNjAwZDdkYzA2MDEwMTI4MDFmY2Q3 MDAzODE4MDAxODE3YzYwMTA1NDIwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjhlMDENCjBhMDQwMWY5NDcxYjkyMDAwMDAwMTc5ZjAxMDEwMTAxMGM4MjdmMDA5OWEzMmIw MTAyMDUwMTAxMDUwMTAxMDIyOTAzMDEwNTI5MDEwMTAxMDEwOTAzMDQwNTA1MDUwMjAxMmIzYjAw ZGEwMTAxMDEwMTBhYjcxOGE1MDIwMjAxDQo4NTU1MDAwMDFhY2UxM2NkOWMzNWY1MjgwOTAyYWYw MGFmMDkwMTAxMDgwMThhNGEzZDJjNjUwMDY4MDEwMTA1ZmIwMGJhMmEwYjg4M2QwMDVjOWYwMTAx MDMwOTA5MDEwMTAxMGE0NjU2NmIwMTAxMDQwYmFkNTYzNjQxMDcwMQ0KMDEzOTE5ZTcwOTA3MDEw MTQxZmMzMzkyMmQwMTdhYjgxYTliZDQwMTA5NzFlZjAwNTcyYjAxMGIwMTAzMGMwNTAxMDkwNjBh MDEwMTAxMDEwNTA0MDQyYTAyMDEwMTAxMDEwYjAxMDE3OWE3Y2EwMDU2NmM3YTBhMDEwODA1NGYN CmU5MWIzODAwMDAwMDdmNzgwMTAxMGIwMTAxNDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMThlMDEwMTQzMDE1MDIxMDA0ODFhMDAxYjQ3YTcyYzAyMjgNCjAxMDFiZTRj YzcwMGQwMmQwNzAxMDE0MTA0MDU0MTAxMDEwMTAyMDMwMzAxMDEwMTAxMDEwMTAyMDIwMjAxMDEy OGRhNDg1ZjI4MDEwMzQxMDEwMTU0MDA5NjAxMjkwMTliMzg0NDc2MzA0ODFhMzMwMDAwYjcyYTAx MDExNzM2DQpjMzA5MDkwNTAxMDExZTAwZWQwNWUyMDA4MjAxMDEwMTBjNTMxYjg1MDZlMzAwZTI3 MTAxMDcwYTAyMDEwMTBhNDIwOTAxMTc0ODIyMDIyODBhMDEwMTc0MDBmYTAxOGUyOTg1MDA2YzAx MDUyYjAxMDkwMWJhMWNjNDA3MDFkYQ0KMzMwMDhiOWE3NDQ4MzhmNTI1MDEwMTI4MDEwMTAxMDEw MTAxMDMwMTAxMDEwNjA1MGIwMTAxMGIwMTI4MDgwMjAxMDM4OGEyMjAxYjQ3NDU3YTBiMDEwMTQx MDE2YjE4MDA0YTAwMDA3ZmJiMjcwODAxMDEwMjA0MDkwMTAyMDINCjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQow MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDEwNDI4MDQwMTAxMDUwMzEwN2UzNzFiMzYwMDM5ZjhkNDA3MDEw YzAxMDFkNjYwMDA0YTNkYzgwNjA0MDEwMzAxMDENCjBiODgwYTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEyYTAxMDEwMWFkZDkwMTJhMDE4ODAxZTgzMzM3NDAwMTAxMGIzYTFjZDYwMTAxMDFiNjBlM2Ix YmRhMDEwMTI4NTMzOWFmNjFiMzc4Zjk1ODAwNGE2MzAxY2IzOWY0MjkwNzAxDQowNmE4MzQwMGQy M2E0ODJmMDEwMTA5MmEwMTAyMDcwMTAxMDEwMTQ1MDA1OTAzMDMwMTAxMjliYzAwOGMwODAxOWY5 ZDFjYjIwYTA5MDkwMjI5MDE5MzAwMjcwMTQxMDFlNzQ1MDAxYzAwODA3OGViMDEwMTAzMDEwMjA5 MDYwNQ0KMDIwMTAxMDEwMjBhMDEwMTBhMDEyYTg4MDEwNjAzMDEwNzEwZTE0YTQ4NzRkNDI4MDEw MTAxMDJjOGI4MDA0YTM4MWMxYjgwYTg0MTAxMDEwMTAyMDkwNDA0MDkwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAzMGIwYTAxMDEwMzA2MDEwMTA1ZjY0YTAwMzMwMDAw MTk1Y2NjMDEwMTA3MDMwMWVhZjcwMDAwYjAxMTdhMDIwMjAxMDEwMTAxMGE4ODBiMDIwMjAyMDIw MTAxMDEwMTAxMGENCjQxMGMwMTI5MDQwMTAxMDEwMWU0Mzk5MzAxMDQwOTZjMzY0ODAxMDEyOTQx MDQ0MzQ4MDBlNzAxMDEwMjAwMDAzYTAwMDAxYTNhMTljNzVjMjk3YTMzYmEwODAxMDEyOTAxMDM5 ZDFiNWYwMDk2MDMwMjI5MDEwMTA0MDQwMjAxDQowMTA1MDZhZTM2YjEwMTBhMDUwMzAyNDUzYWY2 MDIwYTAxNGUwMDE4ZGQwMTAxMDE0MjcxMTgwMDQyMDEwNzAxMGE0MjAxMmMwMTQxMGEwMTAxMDgw MTAxMDQwNDAxMDEwMTAyMDMwNDAyMDEyYzA0MDQwMTAxMDEwMTI5MDNmMA0KMWQwMDAwYjA3YjAx MGEwMTg4MDE0ZjRjM2ExOTAwMDAwMDU2ZDIwMTA3MDE5ZjAxMDEwMTAzMDEwMTBhMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMGEwMQ0KMDE0MTg4MDEwMTJhMDEyODQyMDJl MTAwMzUxODAwMDBjMjk1NTAwMTA3MmIwMTA0YWNiMDAwMDA5OWM0MGMwMTAzODgwNTAxMDEwMzA5 MDkwMjAyMDIwMjAyMDIwMTQyMDEwMTAxMDEwMTAxMmEwMTA3ZTA0NTdjMDEwMzBhODINCjAwMjEw YjAxMDcwMTAxZGExYWNlMDcwNTA3MDExYjRiNzg5NWRlNzc5NzRkZDQwMTAxYzgwMDAwMGIwODAx MmEwMTAxMDY4YjAwMWQ0MjAxMDEwNTBhMDEwYjAxMDEwNzA4MmEwMWM4Mzc0YTA5MDUwODAxMDFk ZTM3YTUwMjAzDQowYTI5ODQwMDkxODkyOTAxMmNkMTQ4MTQwMTAxMDE4ZTAxMDEwNDAxMDcwNTAz MDEwNzBiMDEwMjA2MDEwMTAxMDEwMTA5MGEwMzAxMDEwOTA2MDYwMTAxZDQ5NTZmMDAxYmY1YTcw NDAxMDEyODAxMDE5NzAwNDgwMDM5MDBhOQ0KMjAwYzA1MmIwMTAxMDEwNzg4MDUwMTAxMDEwMTAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA5MjkwMzAxMDEwNjA1MDEwNzAx MDE1MDA2ODk4MDAwMDAzNQ0KMDAwMGVmMjQwOTAxMDEwYTBhMDFiZmNkMTgwMGJhZjAyODAxMDcy OTA0MDEwMTAxMDIwMjAyMDIwMjAyMDYwNzAxMDE0MTA1MDEwYjAzMDEwMTAxMGIwNjA0MDEwMjVj MDAzZTAxMmEwYTAxMDFjZDM4MTYwMTAxMDEwYzAwNWYNCjI4MDEyOTI4MDEwNTA5MDEyYThmMDBj MjAxMDEwMTAxNzkwMzg2MWExOTM2MjY4ODAxMDEyYzAxMDUwMTA4MDMwMTAxMDE4OTAwMDAyOTAx MDEwMTRmZDMwMGYxMDUwMTA5MDEzNDFhNDk2ZmYyODY1ZjE4Y2IwMTI4MDkwNDAxDQo5ZjAxMmMw MzAxMDEwMjA0MDkwMTAzMGIwNTAxMDcwNzAzMDEwMTAyMDQwOTA0MDQwMTAxZThhNjQ2Mzk0YTY3 ZDQwMzAzMDQwNDA2MDEyNTRiM2E5MjFhMDAzNmYzZjQwMTA5MjgwMTA0MDYyODAxMDEwMTA0MDkw MjA1MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNzAxMDQyOTAxMDEw YTA5MDEyOTAxMDEwMTA5MDk3YzU1MzcwMDU2MDAzOGQwMjUwOTAxMDkwMjA3MDVjNjVkNGEwMA0K MzRjMDJhMDEwNzAxMDEwMTAxMDEwMTAyMDIwMjBiMDEwYzAxMDUwMzAxMDUwOTA0MDUwNzAxMDEw ODAxMDI0ZjJkODg0MjAxMGEwYTA5ZDEzYTkwMDEwMTA1ODIxYTc0MDEyYTAxMDEwNjAxMDEyYjA5 ZWMwMGQwMGEwMzJhMDENCjAxZTA1NTAwOTAwMDAwNzEwMTAxMDEwMTAxMjgwMTAxMDEwYjAzMjc1 NjM4MGIwMThlMDEwMWRjMThhOTJjMDQwMTAxOTYwMDMwYjgxYzFiMzNlZDI5MDEwMTA0MDYwMTAx MjkwMTA0MGEwMTAyMGIwMjAxMDQwMTAxMGIwMTA5DQowNzAzMDIwMzAzMDEwMTA2NDFiZDFkMDAz Nzg1YmYwYjAyMDUwMTAxMmFjNWVlY2IwMDM4MDAwMDM0NzAwYTAxMDEwNjAxMGIwMTAxMDEwNzBi MDIwMTAyMDMwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MDAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIyOGMzMWIwMDFjMDAwMDFjMzI4OTA1MDQwMTI4MDgw MWU4OWUzNTAwMzQ5ZTk0MDUwOTA1MDUwMTAyOGUwMTAxMDYwMQ0KMDEyOTA1MDEwMTA2MDMwMTAx MDIwNzA2MDIwMTAyMDIwMjAyMDIwMjAyMDIwMWQwY2IyZTAxMmEwMzgyMDA5OTAxMDkwNTI5MDEw MTAxMGIwYTU5MDAzZTI5MDEwMTAyOGVkNzM3ZTk4ODEzMWMxZDA3MDEwNzAxMDE4ODA5MDINCjAx MDEwNTAxNjYxOTI2MGIwMTZiZGFkMzRhMDAyODQxMDEwMWVhNTcxMjAxMDgyODA3MDMwMjAxMDEw MjAxMDEwMjA5MDIwMTAxMDIwMTAyMDIwMTAxMDEwMjA5MDcwNjAxMDEyOTA3MDEwYWQ0Nzc0YjAw NGFiN2ViMDkyOTAxDQowMTAxMDMxMGRmMDAxYzAwNDgwMDAwODUwYzAxMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDkwMzEwYjQwMDAwNTUwMDAwMDBlNjUx MDEwMTAxMDEwYjAxZTc5MDU2MDA0YjNjMmQwMTBhOWYwMTAxMDQwYjAxMDEwMTAxMDcwODBiMDEw MTAxMDEwMTAxMDEwYTI5MDIwMg0KMDIwMjAyMDIwMjAyMGEwOTI3MGEwMTAxMDE2OTY2ZDAwNzAx MDEwMTAxMjkwODAxMDE0YzAwN2QyOTBhMmEwMTY3M2FiNTgxMDE0MjQ2MDAxNzAxODgwMThlMDEw MTAxMDIwOTAxMDE3NTAwMDA1NTRhMDA0ODM3MDAzNzc5MjkNCjAxMDEwNDBhMDIwMTA3MDUwMzAx MDEwMTAyMDkwNDAzMDIwMTAxMDEwMTAyMDQwMjA1MjgwNTAxMDEyOTAxMDEyOTBiMDEwMTBmNjUw MDM4NGE4YWJmMDEwOTAxMDE0Mjg4YjkzYzAwMDAxOTAwMDAwMGU2MjQwNDAyMDEwMjAyDQowMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwOTBiDQowMTI5ZTNjZTAwMDAz NjAwMzYzYTkzYTcwMTBiMDEyODAzMDEyYTk3NDYwMDAwMWRkMzI3MDEwMTA5MDEwYjA4MDcwMTAx MDEwMjAyMDMwNzI4MDYwMzAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwYjAxMDEwMTAxMjkwNjAyNDMw ZA0KMDEwMzA1MDYwMTAxMDEwMTJiMTU1NmNmMDYwMTAxNTEwMDM5NjgwMTI4MmExMDVmMWJiMzAx MDEyYTA0MDEwMTA0MjkwMjAzNWQ0YjdmZTJkNzMwMjJhZTcxMjcwMTAzMDYwNjAxMDEwMTA4MDIw MTAxMDEwMTAxMDIwMzAxMDENCjA5MDQwYTBhMDQwOTAxMDkwMTAxMDEwNzBhMDE0MjAxMDFkNGFh MWQwMDRhN2VlNTdhMDEwMTI4MDEyYTJhNzJkZjAwMDAxOTAwMWM0OWQ1OTcwYTA2MDEwMWEwMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTA1MmEwYTJi ZTNkNzAwMWIzNjAwNDgxYTRiZDMwYzBhDQowMTdhMDEwMTQxMjRiMmE5MDAzNzYwZDk0MjA1MDEw MTAxMjgwODAzMDEwNDAxMDEwMTAxMDEwMjAxMDEwMjAyMDIwMjAyMDIwMjAyMDEwMTI4NTAwMzAx MGEwMTAxMDEwMTAyMDEwNzA0MDIwYTAxMDFiZjg3MmEwMTA2MGM5Nw0KNTk5ZTAxMDQwMTAxMDFk ZTIyN2MwOTQxMDEwNTBhMDIwMzA0MDEwMThlZDYyYzAzMDgwMTAyMmEwMTA2MDEwMzA0MDEwNjhl MjkwMTAxMDEwMTAxMDEwMTAyMDkwNDAyMDEwMTAxMDEwMTAxMDEwMTA5MDYwYjA0MDEwMTA1ZTAN CjFlYTkzODU1NTc3YjQyMGEwMTQxMGEwMTA4ZTQ3ZjAwMDAxOTFhMDA0OGE5ZTQyNzAyMDUwMTA1 NjIwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA5MDIw MTAxMDMwNTA1NDI3YzQ3MDAxYjAwNGEzOTAwNGI5NjBiMDEwMTA4MDEwNDBiZGM5N2UyMDAzN2Q1 NWIyZTQzDQowOTAxMDEwMTAxMDQyOTBhMDEwMTAxMDEwOTA0MDIwMjAyMDIwMjAyMDIwMjAxMDEw MTAzMDcwMTAyMGI1MDA1NDEwMTAxMDMwNTAxMDEwYjA3MDcwMzAxMDQwNTAxMGIwMTAyMDE0MjAz MDIyYTAxMDYwNjJhMGEwMTAxMDMwMQ0KMDMwMTAyMDUwMTAxMmEwMTAxMDMwOTAzMDQyYzJhMDEw MTAxMDIwMTAxMDkwMjAyMDEwMTAxMDEwMTAxMDQwMjAxMDEwMTBhMjgwODA4MDMwMzA1MDEwOTBm MTY4YjM2MDA4NDc3NDMwMjAxMDEwMzAxMDEwNmMxZDUwMDE5MDANCjU2NGEwMGJhODYwNTAxMDEw MTJhMGIwMTAxMDkwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQow MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwOTJhMGIwMTAxMDEwMTA5MDMwOTdiN2YwMDAwMDA0ODM4MDA5MmMxMmIwMTAxMDYwMTAyMDEw MTJkNTg0ODAwMDBkNTEzOGYwNDAxMDEwOTAxMDEwYTBiMDQwMTAxMDIwMjAyDQowMjAyMDIwMjAy MDIwMTc5MDQwMTAxMGIwNDAxMDEwMTAxMDIwMzBiMDMwMTA5MDEwMTAxMDEwMTA5MDUwMTBhMDI0 MjAxMDEwMTAxMDEwMTI4MDEwMTAxMDUwOTAxMDEwYTAxMDM1MDAzMDgwMzA0MDEwNzAxMDEwNjAx MDQwMQ0KMDEwYTA0MDEwMzJiMDMwMzA5MDkwMjAxMDEwMTAxMDEwNDA0MDIwMTAxMDEwMTAxMGEy NTFmMzYwMDM4NTY1YmI2MDUwMTA3MmMwYjUwMDE4ZTQ1NTUwMDAwMWIxYjFjMDAzNDY4MDYwNDA2 NDIwMzAxMDIwMTA5MDYwNTAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAxMDQNCjA5MDEwMjA2MDMwMTAxMDEwNTQxOGM5OTAwMDAxYzM5MDAwMDMzNTgyNTAx MDQwMzAxMDQwYzAxMDU2OWUxMWQwMDAwNTQzZThmMDQwYjAzMDEwMTAxMDMwMzA5MDIwMjAyMDIw MjAyMDIwMjAxMDEwMTA0MDcwMTAxMGEwNDA0DQowMTAyMDEwMTA5MDUwMzAxMDEwMjA2MDYwMTAx MDEyYTAxMjgwMTg4MmMwMTAxMDUwMTBiMDEyYTA2MDEwNjAxMDcwMTAxMDEwMTAxMDEwYTAxMDIw MTA0MmIwMjAxMDUwNzAyMDEwNDAxMDEwMjAyMDkwOTAyMDIwMTAxMDIwMw0KMDQwOTAxMGE4ODRm NGU0NWNhM2EzYWQ1ZTEyNjA2MGIwMTAxMDMwNDAxMDFkYzIxNDc1NTAwMWMwMDAwMDBlMjY4MDEw MTBiMDEwMTAxMDEyODI4MDEwMTI4MDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwOTAxMDEwNTA2MDEwMTI4MDEwNjA0MDEyODI4YzUzYzFjMWMNCjAwM2Ew MDAwMzk4NDY0N2EwNTAxMDEwNjAxMDkwMTJiZGE1YTNiMDAxYzM1ZGI3N2RjMDEwMTA1MDQwMTAy MDIwMjAyMDIwMjAyMDIyYTAxMDYwYTAxMDUwOTAyMDEyODAxMjkwOTAxMDEwNDAxMGEwYTAxMDEw YTAxMDEwMTQxDQowMTAxMGMwMTAxMjgwYTAxMDEwNjA3MDEwMTA0MDYwMTA0MDQyOTAxMDQwMzAx MDcwOTAxMDYwMjAxMDQwMTAxMDIwOTAyMDEwMjBhMDEwMTAxMDIwMjAyMDEwMTA0MDEwMTA0ZGRk ZWRmNGIxOTE5YzcxN2UwMmIwMTAyMDIwMQ0KMDEwNTBiOGVjNGQ3MWMwMDAwMDAwMDFjMThiYjRl MDgwMTA5MDkwMzBhMDEwNzA3MDEwMTBhMGEwMjA5MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDJkNGFm MDAwMDQ4MDAwMDNhMDBkNTViZDYwYzA5MDkwMjAzMDENCjA5MDc0MTcyMzAzYTM2MDAwMGQ3ODVk ODlmMDEwNTAxMDkwYTAxMDEwMTQyMDEwMzA5MDEwMjAzMDIwMTAzMDcwMTI4MjgwMTA0MDEwNTAx MDEwNTA1MDEwMTA1MDIwMjAyMDIwMjAyMDIwMjAxMDkwMjAxMDEwNTAzMDEwMTAyDQowNTBhMDQw MjAyMDIyODAxMDQ1MDAxMDEwNzAxMDEwOTAzMDEwMTAzMDQwMTAxMjkwMTAzMDIwMTA3MDEyYWQ5 NTk0NjU2MDAzODMzNTk2YjA0MDEwNTAxMDEyODA2MDEwNTBlMTUzYTAwM2EwMDE5MDAwMDM1NDUy ZDA5MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyNDEwMTA4OTdjZTAwMDAwMDRhMDAwMDAwYmNjZmM1MDcwMTA0MDMwMTAxMDcwNDAxOTRhNmQw NDcwMDAwNGI1ZWIyYjMNCjI3MDEwNjJjMDYwMTAyMDIwMTAxMDEwMzA1MDkwMTAxMDEwMTAxMDEw NjJhMDEwMzA5MDEwMTAxMDIwMTA5MDkwOTA5MDkwOTA5MDkwOTAyMDMwNTA5MDEwOTI4MDQwMTAx MDEwMTA5MDkwMTAxNDEwMjAxMDEwMzAxMDUwNDAxDQowMTBhMDMwMTAxMDQwNTBhMDEwMWFkMjMy MWQxMWMwMDAwMzU2MGQyNDAwMTAxMDkwYTA1MDQwNDA5MDFjNjkwYzIwMDFhMzgwMDAwMTkwMDY2 ZDM0ZjA4MDcwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAxMDEwMTA0MDY2MzQ1NGEwMDAwMThhOTM3MDAxYzk5OTBhYzAyMDEyOTA2MDIw NTA0MDkwNTYyNjk2NzgwMzMwMDAwMWJjNzY1YWU3MjBkMDEwMTAxMDEwMjA0MDkwMTA0MDUNCjJh MDkwMTAyMDEwMTAxMDEwMjAyMDkwNDAzMDEwMTAxMDEwMTAxMDEwMTAxMDkwMjAzMDQwOTAxMDEw MTA3MDUwOTAxMDEwMTAxMDEwMTA0MDQwMTAyMjkyOTA5MDEwMTAxMDEwMTA0NDFiZjRlNGQzY2Ni MDAzNzFjMzU3NWNkDQoyNDJjMDEwMTAyMjgwNzAxMDEwMTA1MmQ4NWM3MDAwMDAwNDkzYTAwMDAz NTY1ODIyODAxMDkwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDEwNw0KMDUwMTAyNDE4ZTJhNjhjOTAwMDAzOTM3MDAwMDAwMDA4NDUy NjMwMzAxMDIwMTAxMDEwMTAxMDEwYTI5NmI3N2IxMWQ1NjFiMDAxYmNhYjA0YzY4NjM3YTBhMDEw MTAxMjkwMTAxNDIwMTAxMDQwMTAxMGEwNTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDQwMzAx MDEwNDAxMDEwMTAxMDMwNDA5MDEwMTA5MjkwMTAxMDcwMTAxMDEwMTAxMGRiNjZjOWM5ODMzY2Iw MDAwMzgxZGJiNzc2YmNjMjkwMTAxMDQyOTA1MDEwMTAxMDM0ZTMxNjY0YTE5MWM1ZjE4DQowMDAw MWI5ODdjMjgwMTAxMDEwMjAxMDEwOTQyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA0MDEwMTAxMDkwMTAxMDEwMTAxODE1ZGJhMWIzNzE5MDAw MA0KMzgzODAwMzMzZDdjMGIwYTAzMDEwMTA5MGIyYzAxMDEwOThlYjZhZTU5YmI0NzQ5MzcwMDFi NDk3ZmJjNWFiZDhjYmUyYmJmMDYyODAzMDMwMTAxMDEwOTA2MGIwMTAxMDEwMTAxMDEwMTAxMDkw MjAyMDEwMTAxMDY4ZTA3MDMNCjAxMDIwYTA2MDQwMTAxNTBhMDYzYzBjMTVjYjg4MGMyMzcxYjAw MDA2ZjgzYzNjNGM1MDcwMTA5MDEwMTAxMDEwYjA1MDEwMWM2MmZiNDM0MDAxYjE4MDAwMDAwMDAw MGM3NWNjODAxMDE0MjAxMjkyOTAxMDEyYTBiMDEwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxMDQyOTA0MDEwMTI4MDQwOTAzMDMwNjk0 ODU4YjM3MWMwMDAwMDA0YTE4MDAwMDlhYWJhYzhlMDEwMTAxMDEwMQ0KMDEwMTAxMDEwNTJjODhh ZDI0YWVhZjU0MTgwMDNhMzgwMDAwMDA5MmIwYjEzYzgzYjJhZTZhYjM2YWEyMDIwMjAyMDIwMjAy MDIwMjA1MDEwMTI4MDIwMTI5MmQxMTJmNjE4NjMxNmRhNWI0MzQxYzFiNDgxYTAwMzcxYTAwYjUN CjIwOTcyNDQzMDUwMTA5MDEwNDAzMDQwNjAyMGIwNjAxMDdiNmI3YjgxODAwMTg0YTRhMWMwMDAw NDk3ZjdkYjkwMTAxMDEwYTAxMDEwNzAxMDEwYjA1MDEwMTJjMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDMwYTAzMDEwMTA1MDcwOTAxMDQw NDAxMDEwNDAxMDE2MzMwNGEwMDM2MDAwMDAwMWEzNzAwMDA1ZjgzYTE4MjJiMDUwMTA1MjkwNTAx MDEwMTAxMDIwMjA0MDYwYTAyYTIyNg0KYTMzMTNjOWEzNTM5MTkwMDAwMzgxOTAwMDAxYTAwMDAw MDAwMDAwMDAwMDAwMDM3MWIwMDAwMzcwMDAwMDAwMDAwMWIxYTAwMDAwMGE0OWJhNTE2YTZhN2E4 MDkwOTAxMDEwNTI4MDUwMzBiMDQwMTI4MDEwMTAyN2EyNTljM2MNCmE5MDAwMDM3MWMxYTAwMWIw MDAwM2JhYTQwMjkwNzA0MDcyOTBhMDEwMTA1MDEwMTAxMDEwYTA3MDEwMTAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQow MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMzAxDQowMjA1MDMwMTAx MDEwMzAyMDEwOTAzMDIwMjAzMDkwNThlOGY5MDkxNDgwMDFhMWIwMDAwMDAzOTM3MDA5MjkzNDU3 Yzg5MDYwMTBhMDMwMzAyMDEwMTAyMDIwMTAxMGEwMTBhMDkwMTQxN2E2MjdhOTQ5NTk2NDQ5Nzkw NWU1ZQ0KNWU1ZTVlNWU1ZTVlOTg5OTkxMzI5YTg0OWI5Yzk1OWQ5ZTY0MmQ1MDJjOWZhMDA0MDEw MTBhMDkwMTA5MDEwYTBhMDEwMTAxMDIwMTAxMDM4Nzc4NTk3NDQ3MDAxYzAwMDAxYTM3MDAwMDFi MWI5MTIyOGZhMDA3MDEwMTA5MDENCjAxMDEwMTAzMDQwOTAzMDkwMTAxMDEwMTAxMDEwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwYTA5DQowMTAxMDEwYTgxODI4Mzg0MDAwMDAwMWEwMDFh MTk0YTAwMWEzNzRiODA4NTg2ODc0MzAxODgwMTA0MDcwMTAxMDIwOTAxMDEwMTAxMDEwMjA3MGIw NTA5MDkwNDA5MDkwOTAyMDEwMTAzMDUwMjAzMDQwMzA0MDQwMjAxMDMwMg0KMDIwMzA5MDEwMTA0 MDEwMzA0MDIwMjAxMDEwNTAyMDE0MjAxMGQ4OTRkOGE1ZTQ3MzkxYjFiMDAwMDAwMzkwMDFiMzkx YjhiMjA4YzhkMDgwMTAyMDQwMzAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTA1MGIwMzAxMDI0MTAxMDc3MjczNzQz NjAwMTkwMDAwDQowMDU2NGEzOTAwM2EwMDQ4MzU0Njc1NzY3Nzc4MGI3OTI4MDEwNzI5MDEwMTA3 MDkwMTAxMDEwMTAxMDEwMTAxMDIwOTA5MDkwMjAxMDEwMTAyMDEwMTAxMDkyODAxMDEwMTAxMDIw NTAxMDEwOTA3MDEwMTJjMDM3YTdiN2M3ZA0KN2U3ZjAwMWIwMDAwMTgwMDAwMWExYjAwMDAxOTFi M2E4MDczNzIyODAxMDYyYTA5MDEwMTA0MDMwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjA5MDEwMTA1MDkwMTAxMDEwNzA5 MDEwMTAxMDQ2MzY0NjU2NjM3MDAwMDFhMzkwMDFjMzcwMDAwMDAxYjM3MWIxODAwDQo0YjNjMWU2 NzY4Njk2YTEwNDMwYjA5MDQwNzA2MDYwNDAxMDEwMTAxMDEwMTA3MDEwMTA3NDIwNjAxMDEwNzA2 MDIwMTYyNmIyMzExNmM1ODZkNmU1NTAwMzYwMDAwMDAwMDE5MTgxODFiMDAwMDAwMDAwMDFhNmYz ZDcwNzEwOA0KMDEwMjAyMDEwMTAyMDEwMTAxMDIwNDA5MDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwNzAxMDEwMTAxMDIw NTJhMDEwOTA3MjgwMzAxMDEwNzBhNDE0MTUxNTI1MzU0M2EwMDAwMzkxYzU1MWEwMDAwMDAwMDFh MzUxYjAwMDAwMDAwMWMzYTU2NDgxODU2MzM1NzE0DQo1ODU5NWE1YjU4NWI1YzEzMTYxMzVkNTk1 ZTAwNGEzYTM1NWY0ODAwMDAxYzFiMDAzODQ4MDAwMDE5MDA1NjM3MzkwMDAwMDAwMDAwNjA1NzVk NjE2MjAxMDEwMTI5MDEwMTA3MDgwNTAzMjkwMTAyMDMwNTAzMDIwMTAxMDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDAwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAxMDENCjA5 MGEwNDAxMDEwMjAxMDEwMTAxMDEwYjA0MDEwMTBhMDEyODAzMDQwMTQzMGU0NDQ1NDY0NzAwMTk0 ODM2NDkwMDAwMWExYzAwMzYwMDAwMDAxYTFhMWEwMDAwMDAwMDFiMWMxYTAwMDAzNzAwMTg0YTFh MDAwMDFjMWMxYTFjDQoxYTAwMDAxYjM5MWExYTFiMDAwMDM2MTgxYTFiMDAwMDRiNDY0YzRkNGU0 ZjUwMjkwMTAxMDQyODA0MDEwMTAyMDMwMTAxMDEwMTA5MDMwNTBhMDMwMTAxMDIwOTAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MTAxMDQwNDAyMDEwMTAxMDEwNzJiMDYwMTAxMDUwNDJjMGENCjAxMDEwMzBhMDEwYTAzMDUwMTI4 MmMyZDJlMmYzMDMxMzIzMzM0MzUwMDAwMzYzNzAwMDAxYjFiMDAwMDM4MTkxYzAwMDAwMDFhMTkw MDAwMDAwMDAwMDAxYjFiMDAzOTM3MDAwMDNhMzkwMDM2MzYxYjNiM2MzZDNlM2YyZDQwDQo0MTA2 MDEwYTAyMGEwMTAxMDQwOTAxMDEwMjA3MDEwMjAxMDEwYTQyMDYwMTAxMDkwOTAxMDEwMjA0MDMw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw Mg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDkwOTAxMDEwMTAyMGEwNjA0MDIwMTAxMDEwMTAzMDkwMTAxMGMwODAxMDEwMjBhMDEw MTAxMDkwMTAzMDEwMjAyMDENCjAxMDcwYTBkMGUwZjEwMTExMjEzMTQxNTE2MTcxODE5MWEwMDAw MDAwMDFiMDAxYzE4MWMwMDAwMWQxZTFmMjAyMTE3MjIyMzI0MjUyNjI3MDEwNDA5MDEwMTAyMDEw MjAxMDQwMTA2MDEwMTI4MDEwMTAxMjkyYTAxMDEwOTA2DQowYTAxMDEwMTA3MDgwMTAyMDIwMTAx MDQwNTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAxMDEwMTAyMDMwNDAxMDEwNTAxMDEwNjA3MDEwMTAzMDcwMTAzMDEwMzAx MDgwMTA0MDIwOTA3MDUwMTAxMGEwMTA3MDUwMTAyMDUwMjAxMDIwMzA0MDkwMTAxMDEwOTAzMDMN CjA5MDEwMTAxMDkwNTAxMDYwNzAxMDEwNzA2MDEwMTA0MDYwMzAxMDEwMzA0MDIwNzAxMDEwNzA1 MDEwMjA1MDUwMjAxMDEwMjAzMDIwMTAxMDQwNDAxMDEwMjBiMDEwMTAxMGEwYjBhMDEwMTAxMDMw MzAxMDkwNzA0MDEwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMDAyMDINCjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQow MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAw MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy DQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAwMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMDAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0K MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyDQowMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyDQowMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMg0KMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDAwNDAwMDAwMDI3MDFmZmZmMDMw MDAwMDAwMDAwfVxwYXJ9fX17XGluc3JzaWQ3NzU3NTQwIFwnYzIgXCdmMVwnZjJcJ2VlXCdlOFwn ZWNcJ2VlXCdmMVwnZjJcJ2ZjIFwnZTJcJ2Y1XCdlZVwnZTRcJ2ZmXCdmMiBcJ2VjXCdlNQ0KXCdm MlwnZWVcJ2U0XCdlOFwnZjdcJ2U1XCdmMVwnZWFcJ2U4XCdlNSBcJ2VjXCdlMFwnZjJcJ2U1XCdm MFwnZThcJ2UwXCdlYlwnZmJ9e1xmMzlcaW5zcnNpZDc3NTc1NDAgLn17XGluc3JzaWQ3NzU3NTQw ICBcJ2MzXCdlZVwnZjFcJ2YyXCdmZlwnZWMgfXtcaW5zcnNpZDIyMzAyNDUgXCdjZlwnZTVcJ2Yy XCdlNVwnZjBcJ2UxXCdmM1wnZjBcJ2UzXCdlMH17XGYzOVxpbnNyc2lkNzc1NzU0MCA6fXtcaW5z cnNpZDc3NTc1NDAgIFwnZTFcJ2YwDQpcJ2VlXCdlZFwnZThcJ2YwXCdlZVwnZTJcJ2UwXCdlZFwn ZThcJ2U1fXtcZjM5XGluc3JzaWQ3NzU3NTQwICx9e1xpbnNyc2lkNzc1NzU0MCAgXCdmMlwnZjBc J2UwXCdlZFwnZjFcJ2Y0XCdlNVwnZjB9e1xpbnNyc2lkMjIzMDI0NSAsfXtcaW5zcnNpZDc3NTc1 NDAgIH17XGluc3JzaWQyMjMwMjQ1IFwnZWF9e1xpbnNyc2lkNzc1NzU0MCBcJ2YzXCdlYlwnZmNc J2YyXCdmM1wnZjBcJ2VkXCdlMFwnZmYgXCdlZlwnZjBcJ2VlXCdlM1wnZjBcJ2UwDQpcJ2VjXCdl Y1wnZTB9e1xmMzlcaW5zcnNpZDc3NTc1NDAgIX17XGluc3JzaWQ3NzU3NTQwXGNoYXJyc2lkMjIz MDI0NSANClxwYXIgfVxwYXJkIFxxbCBcbGkwXHJpMFxzbC0yMzJcc2xtdWx0MFxub3dpZGN0bHBh clxmYWF1dG9ccmluMFxsaW4wXGl0YXAwXHBhcmFyc2lkNzc1NzU0MCB7XGxhbmcxMDI0XGxhbmdm ZTEwMjRcbm9wcm9vZlxpbnNyc2lkMjIzMDI0NSANCntcc2hwe1wqXHNocGluc3Rcc2hwbGVmdDE2 MzFcc2hwdG9wLTMwMlxzaHByaWdodDQ2NjBcc2hwYm90dG9tMTUyN1xzaHBmaGRyMFxzaHBieGNv bHVtblxzaHBieGlnbm9yZVxzaHBieXBhcmFcc2hwYnlpZ25vcmVcc2hwd3IzXHNocHdyazBcc2hw ZmJsd3R4dDFcc2hwejJcc2hwbGlkMTAyOHtcc3B7XHNuIHNoYXBlVHlwZX17XHN2IDc1fX17XHNw e1xzbiBmRmxpcEh9e1xzdiAwfX17XHNwe1xzbiBmRmxpcFZ9e1xzdiAwfX0NCntcc3B7XHNuIHBp Yn17XHN2IHtccGljdFxwaWNzY2FsZXg0NFxwaWNzY2FsZXk0NFxwaWNjcm9wbDBccGljY3JvcHIw XHBpY2Nyb3B0MFxwaWNjcm9wYjBccGljdzEyMjUwXHBpY2g3NDA4XHBpY3dnb2FsNjk0NVxwaWNo Z29hbDQyMDBcanBlZ2JsaXBcYmxpcHRhZzEzNjg0NTg0ODF7XCpcYmxpcHVpZCA1MTkxMDRmMTk2 MzkwMzY5ZTViMjY2Zjc0MmZjZjAzOX0NCmZmZDhmZmUwMDAxMDRhNDY0OTQ2MDAwMTAxMDAwMDAx MDAwMTAwMDBmZmRiMDA0MzAwMDgwNjA2MDcwNjA1MDgwNzA3MDcwOTA5MDgwYTBjMTQwZDBjMGIw YjBjMTkxMjEzMGYxNDFkMWExZjFlMWQxYTFjMWMyMDI0MmUyNzIwDQoyMjJjMjMxYzFjMjgzNzI5 MmMzMDMxMzQzNDM0MWYyNzM5M2QzODMyM2MyZTMzMzQzMmZmZGIwMDQzMDEwOTA5MDkwYzBiMGMx ODBkMGQxODMyMjExYzIxMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMg0K MzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIzMjMyMzIz MjMyZmZjMDAwMTEwODAxMTgwMWNmMDMwMTIyMDAwMjExMDEwMzExMDFmZmM0MDAxZjAwMDAwMTA1 MDEwMTAxMDEwMTAxMDANCjAwMDAwMDAwMDAwMDAwMDEwMjAzMDQwNTA2MDcwODA5MGEwYmZmYzQw MGI1MTAwMDAyMDEwMzAzMDIwNDAzMDUwNTA0MDQwMDAwMDE3ZDAxMDIwMzAwMDQxMTA1MTIyMTMx NDEwNjEzNTE2MTA3MjI3MTE0MzI4MTkxYTEwODIzDQo0MmIxYzExNTUyZDFmMDI0MzM2MjcyODIw OTBhMTYxNzE4MTkxYTI1MjYyNzI4MjkyYTM0MzUzNjM3MzgzOTNhNDM0NDQ1NDY0NzQ4NDk0YTUz NTQ1NTU2NTc1ODU5NWE2MzY0NjU2NjY3Njg2OTZhNzM3NDc1NzY3Nzc4Nzk3YQ0KODM4NDg1ODY4 Nzg4ODk4YTkyOTM5NDk1OTY5Nzk4OTk5YWEyYTNhNGE1YTZhN2E4YTlhYWIyYjNiNGI1YjZiN2I4 YjliYWMyYzNjNGM1YzZjN2M4YzljYWQyZDNkNGQ1ZDZkN2Q4ZDlkYWUxZTJlM2U0ZTVlNmU3ZThl OWVhZjENCmYyZjNmNGY1ZjZmN2Y4ZjlmYWZmYzQwMDFmMDEwMDAzMDEwMTAxMDEwMTAxMDEwMTAx MDAwMDAwMDAwMDAwMDEwMjAzMDQwNTA2MDcwODA5MGEwYmZmYzQwMGI1MTEwMDAyMDEwMjA0MDQw MzA0MDcwNTA0MDQwMDAxMDI3NzAwDQowMTAyMDMxMTA0MDUyMTMxMDYxMjQxNTEwNzYxNzExMzIy MzI4MTA4MTQ0MjkxYTFiMWMxMDkyMzMzNTJmMDE1NjI3MmQxMGExNjI0MzRlMTI1ZjExNzE4MTkx YTI2MjcyODI5MmEzNTM2MzczODM5M2E0MzQ0NDU0NjQ3NDg0OQ0KNGE1MzU0NTU1NjU3NTg1OTVh NjM2NDY1NjY2NzY4Njk2YTczNzQ3NTc2Nzc3ODc5N2E4MjgzODQ4NTg2ODc4ODg5OGE5MjkzOTQ5 NTk2OTc5ODk5OWFhMmEzYTRhNWE2YTdhOGE5YWFiMmIzYjRiNWI2YjdiOGI5YmFjMmMzYzQNCmM1 YzZjN2M4YzljYWQyZDNkNGQ1ZDZkN2Q4ZDlkYWUyZTNlNGU1ZTZlN2U4ZTllYWYyZjNmNGY1ZjZm N2Y4ZjlmYWZmZGEwMDBjMDMwMTAwMDIxMTAzMTEwMDNmMDBmN2ZhMjhhMjgwMGEyOGEyODAwYTI4 YTI4MDBhMjhhMjgwDQowYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEy OGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4 YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MA0KMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEy OGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4 YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODANCjBhMjhhMjgwMGEy OGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4 YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDBhMjhh MjgwDQowYTI4YTRhMDA1YTJhYmRjZGRkYjVhNDJkMmRjNGU5MTQ2YmY3OTlkYjZkNzMxN2RmMTFm YzMzNjUyMTg4NWZiNWQ0Y2EzZmQ1ZGI0NmQyNjdmZWY5ZTI4MDNhZmEyYjg5ZmY4NGQ3NTZiZDhk MGU5M2UxMWQ0ZTdkZmZjNzczYg0KNjA1ZmZjN2E5YzU3ZTIwNWYwNWRiMjY4ZGE1YzY3ZWYyZWQ2 OWE0NWZmMDBkOTY4MDNiM2FhZjM1ZWRhZGFhZWU5ZWU2MTg4N2ZkMzQ3NTVhZTRjNzgyNzUyYmRl NzU2ZjE1NmE5NzBhN2VmNDUwMTU4NTNmZjAwMWRhYjkwN2MNCjNlZjBiYzRkYjliNDk4YTY3Y2Vl Y2NlNWE0ZmYwMGQwYTgwMjViY2YxZGY4NWVjMGVkOWI1YWI0ZGZmZGQ4ZGI3OWZmMDBjNzZhYTFm ODlmZTEwNWViYWJmZjAwZTRiNGJmZmM0ZDZlYzFhMTY5NTZiMTc5NzA2OWI2NzFhN2Y3DQo1MjA1 NWFiMWZkOWY2OWZmMDAzZWQxN2ZkZjE0MDBjZDNmNTRiMmQ1YWQ1NmU2YzJlNjJiODgxYmY4OTFh YWVkNDExNWFjMTAxNjY4YTI0NDJkZjdiNjJlZGNkNGY0MDA1MTQ1MTQwMDk0MmI2ZTVjZDJkMTQw MDUxNDUxNDAwNQ0KMTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQwMDUxNDUxNDAwNTE0NTE0 MDA1MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQw MDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQwMDUNCjE0NTE0MDA1MTU1MmU2ZmVkMmNhM2YzMmVlZTYy ODUwN2YxNGIyMmFkNzJiN2JmMTNmYzMzNmQzMTg2ZGFlYTViZjlmYTc5NzY3MGI0OWZmMDA4Zjdk ZGEwMGVkNjkyYmNmMWJjNWRlMmVkNTkwN2Y2Mzc4NTRkYmFjOWY3NjVkDQo0MjRkYjlmZjAwODBk MzkzYzMxZTM0ZDYxNTViNWFmMTRiNTlhMWZiZDA2OWYxZWNmZjAwYzdhODAzYjZiY2Q0YWNiNGU4 YmNjYmNiYjg2ZGQzZmJkMmM4MTZiOTliOGY4OTNhMDA5M2NhYjE5YTZkNGFlMThlZDU4NmQyMTY2 Mw0KZmYwMDdkN2RkYTY1ODdjMzRmMGVkYjRhYjJkZDQzMzZhMzI4ZmYwMDk2OTdiMjE3ZmYwMGVi NTc1NTY3NjE2OTYxMGY5NTY3NmIxNWI0M2ZmM2NlMjhjMjhmZDI4MDM4YjZmMTNmOGQ3NTJmZjkw Njc4NTUyY2UzM2ZmMmQ3NTANCjliZmYwMDY1NWE5N2ZlMTE3ZjE1NmE1ODkzNTZmMTU0OTZlYTRm Y2QwNjliMTc5NmJmZjdkN2RlYWVlYThhMDBlNDYyZjg3MWUxYzEyMzQ5NzE2ZDJkZWI5ZWY3YjJi NGRmZmExNTZmZTlmYTVkOGU5NzZlYjA1OTVhNDUwMjdmDQo3NjM0MGI1N2U4YTAwNGEyOTY4YTAw MjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAy OGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOA0KYTI4YTAw MjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YWFiNzU3YjZkNjUxMzQ5 NzU3MzE0MzE4ZmUyOTVkNTQ1NzJiN2RmMTJmYzM1NmIzMTg2MGJhOWFmZTcyNzZmOTc2NTEzNGJm ZmQ2YTAwZWQNCjI5MmI4OGZmMDA4NGFiYzU1YThiZWNkMmZjMjMzNDMxOWZmOTZmYTg0ZWIxMjhm ZjAwODBmZGVhYWRmZjAwMDhlZjhlNzU4NDY2ZDRmYzRmMWU5Y2E1YmZkNDY5ZjBmY2RiN2ZlYmE3 Y2FkNDAxZGFkZTZhMzY1YTc0NWU2ZGVkDQpkYzM2ZTlmZGU5OWMyZDcyYjc5ZjE0N2MyZjA0YmU0 ZGI1ZGNiN2YzNjNlNThlZDIyNjdjZmYwMGMwYmVlZDQ3NjdmMGI3NDE4ZTVmM2I1MTM3M2FhNGZk ZGVlZTY2NmFlYWFjZjQ0ZDMzNGY4OTYzYjViMGI2ODE1N2E3OTcxMg0KYWQwMDcxYTllMzNmMTRl YjRjYWJhMTc4NTFlMTg5OWI2ZmRhNzUyOTNjYjU1ZmY4MGFmY2Q1M2NkZTFiZjE4NmIwYWE3NTNm MTNmZDhiMmRmMzQzYTVjN2I1NzZmZjAwYmNkZjM1NzczYjU0NzZhNzUwMDcwOTA3YzI5ZjBlMmMN CjhiMzVmN2RiMzUxOTU3ZjhhZWU3NjkyYmFkYjJkMmI0ZmQzYWRiYzhiM2IyODIwODU3ZjgyMzhj MjhhYmQ0NTAwMzU1NTU1NzY4MTgxNGVhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEy OGEwMDI4YTI4YTAwMjhhDQoyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhh MjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEy OGEwMDI4YTI4YTAwMjhhMjkyODAxNjhhYzVkNjNjNA0KZmEyZTg2ODRlYTNhOGMzMGI3ZjczNzZl N2ZmYmU0NzM1Y2U5ZjFhNmIxYWJiMzI3ODY3YzM5NzMyYTFmYmI3OTdmZmI4ODdmZjhhNmEwMGVl ZWIyYjUyZjExZThmYTM5ZmYwMDRmZDQ2ZGUwNmZlZWI0OWYzN2ZkZjM1Y2IxZjANCjlmOGFiNTk3 MmRhZWY4OTVhMjgxYmZlNWRiNGY1ZDgzZmVmYWFkNmQzN2MwMWUxYWQyZGJjYzhmNGU4ZTU5ZmYw MGU3YjRmZjAwYmM3ZmZjN2E4MDI4MWY4ODgzNTE3NjhmYzM5YTFlYTFhYWIyZmYwMGNiNTExZjk1 MTdmZGY0DQpkNTE5ZDNmYzdiYWRmMzc1YTlkOWU4NzAxZmY5NjU2OTFmOWIyZmZkZjRkNWRiYzUw YzcwNDYyMzhkNzZhYWQ0OTQwMWM0NWFmYzMxZDE5OWZjZWQ2MjViYmQ1ZWUzNzZlZGY3NzJiMzBm ZmJlNmJhOWI0ZDI3NGZkM2FkYzQxNg0KNTY1MDViYzQzZjg2MjhkNTZhZmQxNDAwOTRiNDUxNDAw NTE0NTE0MDA1MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1 MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQwMDUxNDUxNDANCjA1MTQ1MTQwMDUxNDUxNDAw NTE0NTE0MDA1MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQwMDUxNTliZjY5YjZiY2JkN2Iz NDk2NGYzNmRmNmNiMjJhMzMwYzY3ZWU4NmZmZTI2YjRhODAwYTI4YTI4MDBhMjkyYjIzNTZmDQox MWU5M2EyYWZmMDBhNzVlYTQ3MmI3ZGQ4OTdlNjkxZmZkZDU1ZTY4MDM2MmFhZGRkZTViNThjMjY1 YmJiODhhMDg4N2YxNGIyMDUxZmFkNzJiZmRhZmUyOGQ3NzcyZTkxYTVhNjk3NmRmZjNmM2E5N2Rm NmZmMDA3NjI1ZmYwMA0KZDlhOTZkYmMwMzY5MzRjYjczZTIwYmRiOWQ2YWU1NWI3N2ZhNGI2MjI0 M2ZlY2M3Zjc2ODAxYjcxZjEwYWRhZTY3ZmIzNzg3NzRmYmJkNjY3ZTliYWRkNzZjNDNmZWRhMzdj YjU1ZGY0NGYxYWViYmYzNmE3YWM0NWE2ZGFiZmQNCmViNGIxZmJlYmZlY2Y5OTVkYWRiNWI0MTY5 MGFjMzZmMTI0NTEyZmRkNDQ1ZGEwNTU4YTAwZTZmNGFmMDQ2ODFhNDFmMzIwYjA0OTZlM2VmNzlm M2ZlZjY0Y2ZmMDBiY2Q1ZDFhYWUyOTY4YTAwMjhhMjhhMDAyOGEyOGEwMDI4DQphMjkyODAxNjhh ZTAzYzVkZTM4OWVjZWYzZmIxNzQwODdlZDFhOWJiNzk2Y2ZiNzc3OTRkZmVlZmYxMzU3Njc2MDkz YTY5ZjA0Nzc3MjA5NmUxNjM1NTk1ZjZlMzczNjM5YTAwYjk0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUw MDE0NQ0KMTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1 MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUw MDE0NTE0NTAwMTUxY2IyYWMzMTMNCmM4ZWQ4NTQxOTZhOTJiMjc1NjY1NzEwNThhYmVkOTJlYTRk YmQ3Zjg1N2U2NmZmM2VmNDAxNWZjMzU2NDZkMmM2NTllNThkOTJlNmZhNTZiYTk5NThmY2MxOWJm ODdmMDVkYjViZDQ5ZDJiMDM1NGYxNWQ4ZDhkYzdkOGEwNTkyDQpmNmZmMDA2ZWU1YjZiNjFiZGJm ZTA1ZmRkYTAwZGZhZTZiNTZmMWE2OTdhNmM5ZjY0ODFhNGJmYmRlZDZkNjYzY2M2ZmY4MTYzZWVk NTYzYTVmODg3NWM2NjFhYzVlYWQ4NTliN2ZjYmE1ODlmOWQ5N2ZkYTkzZWYyZmZjMDZiNw0KMzRh ZDEzNGZkMWEyZjI2YzJkMjM4NDFmYmNjYWJmMzM3ZmJjZGRlODAzOWE5MmNmYzVkZTI0MjdlZDU3 NmJhMTU4MzdmY2JiZGJmY2YzYjJmZjAwYjRkZmMzZmYwMDAxYWQ4ZDFiYzIxYTJlODQ3Y2NiNWI0 ZGY3M2RlZTY3M2UNCjY0YWRmZjAwMDI2YWRmYTVhMDA0YTVhMjhhMDAyOGEyOGEwMDI4YTI4YTAw MjhhMjhhMDAyOGEyOGEwMDRhZTEzYzZiZTMyM2EzOTkzNGRiMjkwMmRkNzk3ZTY0YjI3ZmNmMjVm ZTE1NWZlZjNiNTc0YmUyMmQ2NjJmMGZlODM3DQo5YTk0YWRmZWEyMzY2NTVmZWYzN2YwOGFmMmJm ODc3YTBkYzc4OWY1MTZkNzM1NjU2OTZkYTI5M2NjZjMxY2ZmMDBjN2NjZmYwMGRlZmYwMDc1Njgw M2FmZjAyNzg1ZTRiNTU2ZDY3NTQ4OTU2ZjJlM2U2OGExZGJmZWExN2ZmOA0KYWFlZWU4YTVhMDAy OGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4 YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhh MjgNCmEwMDI4YTI4YTAwMjhhMjhhMDAyOGE0YWNhZDYzYzQzYTZlODUxYWI1ZWNmYjY0N2ZmMDA1 NzEyN2NjZWZmMDBlZWFkMDA2YWQ3MGRhYmY4YWVjYjRiZjE2YzgyNzY5MmUxZTI4MTYyODJkYWQ4 MDc5MTlkOWJlNmY5N2ZlMDJiDQo0ZDlhNGYxMzc4OTZkOGNjOTIzNzg3ZjRhMmJiYjc3ZGViOTkx N2ZmMDA0MTRhYmRlMDZmMGY1YWU5MWE0N2RhYzQ0ZGY2YWJjM2U3MzNjYmZlYjM2YjdkZDU2MzQw MTBhNTlmODk3YzRkY2VhMzJiNjhkYTczN2ZjYmI0MGQ5OQ0KZTQ1ZmY2OWJmODZiYTBkMjc0MmQz NzQzODVhMmQzZWQyMzg0MzdkZTY1MWYzMzdkNGQ2OWQyZDAwMjUyZDE0NTAwMTQ1MTQ1MDAxNDUx NDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0OTRiNTk5YWRlYWY2ZGExNjk1NzENCmE4ZGUz ZWQ4NjE1ZGRmNWY2YTAwZjNlZjhhMTJjZmFmNmI3YTJmODQ3NGU2ZGQzY2IyNzlmNzFmZGQ0NWZi YWFjZGZmMDA4ZjU3YTM2OTNhNWRiNjhiYTY1YmU5ZjY4YmI2MDgxNzZhZDcwM2YwYzA1Y2ViYjdi YWI3OGJhZmQ0DQo3OWY3OTI3OTEwZmYwMGIxMWFmZjAwMGFkN2E2NTAwMTQ1MTQ1MDAxNDUxNDUw MDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAw MTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMQ0KNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUw MDE0NTE1MWM5MjI0NDhkMjQ4YzE1NTQ2NTk4ZjZhMDA5MmE5ZWEzYTk1YTY5MzYzMjVlNWY0ZWIw YzA5Zjc5ZGFiOThiOWYxNzVkZWE5M2JkOTc4NTJkMTZmNjU0NmQ5MjUNCmRjYTc2YzExN2ZmMTVm ZjAxYTkzNGNmMDVjNGI3YTc1MmQ3NmUxYjU1ZDQ1YmY4YTUxZmJhOGJkOTE2ODAyMTNhYWViYmUy ODhmMWEwNDJkYTY1OGI3ZmNiZmRkYTdjZWZmMDBmNWNlM2ZmZDk5YWI1YjRhZjBiZDhlOTk3MGQ3 DQo2ZWQyNWRkZmJmZGViYWI5M2I5ZmZlMDNmZGRhZGQwYmI0NjA1M2E4MDMxYmM0NzJmZjAwYzRh ZDZkNDQ3YmRlZWU0NTgxNTc2ZWVmYmRmN2JmZjFkZGQ1YWE4YWIxYTJhYWFlZDU1ZTAwYWM2Yjgy ZDM3OGIyY2UxMWY3MjA4MQ0KZTdlM2Q1YmU1ZjlhYjc2ODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEy ODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDEyYmM3ZmM3ZGFhYzllMjBiOWJlOGEy NmNlOGJhMzJiMzVjMzJmZGQ5ZTdkYmYyYTdmYjViNzcNCjU3NjllMzVkNzY2YjBiMjg3NGNkM2I3 M2VhZGE5Mzc5MTZjYWJmYzFmZGU5MGZmYmI1Y2I3OGI3NDA4YjQ1ZjA3ZTg1ZTE0YjM2ZGM2ZmI1 MDhkMjU2NmZiZDI3ZjEzMzdmZGY1YjY4MDNhZmYwMGU5YmZkOTVlMDhkMzIwNjVjDQozYjQ1ZTZi ZmZiY2RmMzU3NGY1MWM3MWFjNzFhYTIwZGFhYTMwMDU0OTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1 MTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQwMDUxNDUx NDAwNTE0NQ0KMTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQwMDUxNDUxNDAwNTE1MTRiMmM3MDQ0 ZDJjYWVhODg4Yjk2NjYzYzBhZTMyN2YxNGRlNzg4YWYxYjRmZjBiNDZkZTRlZWRiMzZhOTIyN2Vl OTNmZGNmZWYzNTAwNmNmODg3YzRmNjMNCmUxZThhMzU5ODNjZjc1MzdjYjA1YTQwYmJhNDk0ZmZi YjU4OTE2OGJhZDc4YjY1MTNmODk1YmVjN2E2MGU2M2QyZTA3ZTViZmViYWI3ZmVjYjViN2EyZjg1 ZWNmNDcyZDNiMTZiY2JmN2ZmNTk3OTNmY2QyMzdmZjAwMTNmODU2DQpmZDAwNTdiNmI1ODJkMjA0 ODJkZTE0OGEyNGZiYTg4YmI0MGFiMTQ1MTQwMDUxNDU1NGQ0NmVkNmNiNGZiOGI5NzY1MGIxYzZj ZGYzMzYyODAzM2I0NWZmMDA0OGJlZDRlZjhhYjJmOTkzZjkyYjljZmRkOGZlNWZmZDBiNzU2ZQ0K NTY3NjkxMTM0NWE2NDJhZjlkZWNiYmRiMjE0NjBiN2NkZmMzNWEzNDAwNTE0NTE0MDA1MTQ1MTQw MDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQwMDUxNDUxNDAwNTUzZDRiNTFiNmQyNzRmOWVmYWYxYzI0 MTBhZWU2NmFiNjdlZWQNCjc5ZWRjOTkzYzdiZTI2ZmIxMjM2ZWYwZTY5Y2Q5OWRkN2E1Y2NmZmRk ZmY3NTY4MDJlNzgzNmMyZTc1MGJiOWZjNTVhYjQ3YjZmMmYxNzY1YjQ0YzNmZDQ1YmVlZjk1N2Zl MDVmN2FhYmViNDhiYTk3YzU5ZDAyY2I3NjYzYjBiDQo2OTJmMTk3ZmRhZmJhYmZmMDBiMmQ3N2Ew MDUxODE1YzFlODJjZDdkZjE1ZmM0Yjc3ZmMzNmIwNDU2OGE3ZmVmOTY2ZmZkMDY4MDNiZWEyOGEy ODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOA0KYTI4MDBhMjhh MjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEy ODAwYWNhZDZiNWNiMGQwMmNmZWQzN2QyZWM1NmY5NTExNzk2OTFiZmJhYTJhYTZiZmUyNjg3NDY2 OGVkYTINCjg2NGJiZDQ2N2UyMGI0ODc5NjZmZjY5YmZiYWJmZWQ1NTZkMWJjMzUyN2RiNDZiMWFl NGNiNzdhYTFlNTE3ZmU1OTViMmZmNzYzMWZmYjM1MDA1MThiNDhkNTNjNWVjYjcxZTIwNTZiMmQz M2VmNDVhNzQ0ZmYwMDMzZmYwMGQ3DQo1NmZmMDBkOTZiYWZiNmI2ODJkMmRkMmRlZGUyNDhhMjQx ODU0NDVjMjhhOWU5NjgwMGEyOGEyODAwYTI4YTI4MDBhYzFmMTU5ZjMzNDk1YjU1NzU1OTJlYTc0 ODk0MzM2ZGNmY2Q1YmQ1Y2U2YTZjNmYzYzVkYTU1YTBlNTJkNg0KMzdiYTkzOGZmODBhZmYwMGVj ZDQwMWQwMjJlZDQ1NWY0MTRmYTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAy OGEyOGEwMDI4YTJiOWJmMTU3ODgxZjQ3YjU4YWRiNGY4ZDY3ZDVlZjFiY2FiNDgzZmRhZmUNCmYz N2ZiMmI0MDE5ZGUyZGQ1YWU2ZmVlOTdjMmJhMjQ4MDVmZGNhZTZlNjY1NmZmOGY2OGJiYjdmYmQ1 ZDE2OGJhM2RhZTg3YTU0M2E3NTlhOTExNDQzYWI3NTYzZWI1NDNjMmRlMWI0ZjBmZDkzMTk2NGZi NDZhMzc0ZGU2NWRkDQpjYjdkZTkxZmZjMmJhMmEwMDQzYzU3MDNmMGJlMjEyZTlmYWI2YTlmZjQx MGQ0YTU3NTZmZWYyYWZkZGZmZDlhYmFhZjExZGU3ZjY3Zjg2YjUzYmJmZjAwOWU1NmNlZGZmOGVk NjNmYzM4YjUxNjllMDBkMjIzZGJiNTllMmYzNQ0KYmZlMDRjNWE4MDNhZGEyOGEyODAwYTI4YTI4 MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgw MGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDBhZTUNCmJjNDNlMjE5ZWQ2 NjVkMmI0NTg4NWQ2YjEzYWZjYjFmZjBjNGJmZGY3YTdmODkzNWY5ZWQyNzgzNDhkMjU1NjZkNjJl YmVlMmI3ZGQ4OTNiYzhkZmVjZDRiZTFkZjBkNDFhMGM3MmNjZjIzNWQ2YTM3MmRiZWU2ZWU0ZmJk MjM3DQpmNDE0MDA3ODczYzM3MWU4YzhmNzMzY2M2ZWI1M2I4ZjlhZTZlYTRmYmNjZGU4YmZkZDVm ZjY2YmExYTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwNGFlNjc0NDNmNmJmMTM2Yjc3ZGY3 OTExYTNiNjhkYjc3Zjc1NzJjMw0KZmVmYWFkZWJjOWQ2ZDJjZTZiODZmZjAwOTY0OGNkZDZiMjdj MjM2OGQ2OWUxY2I2MmY5ZjM2N2NjZWZiYmZiY2ZmMDAzNTAwNmY1MmQ1N2ZiNTQwMmU4NWE5OTUz Y2YyYmJmY2JkZGNlZGY1YWIxNDAwNTE0NTE0MDA1MTQ1MTQNCjAwNTE0NTQzZTZjNjY0MzFhYmFl ZjFjYjJlNzlhMDA5YThhYTk3ZmE4NWE2OTU2NzJkZGRlY2U5MGRiYzRiYjlhNDc2ZTk0Y2QzMzUy YjVkNWY0ZjhhZmFjNjUzMmRiY2FiYmEzNmRhNTc3N2U3NDAxN2E5Mjk2YjFmYzQxYWU1DQphNzg3 YjRiN2JkYmEyNWJmODYzODkzZWY0YWZkOTU2ODAyMWYxMzc4OGVkZmMzN2E2YWRjM2M2ZDM1YzRh ZGU1ZGJkYjI3ZGU5NjQzZmMzNTlmZTE2ZjBlNWQ0Mzc3Mjc4ODM1ZDIyNWQ2YWU5N2ZlMDM2ZTlm ZGM1YTgzYzM3ZQ0KMWViZGJiZDQwNzg5M2M0NmExYjUxNzFmZThkNmM0N2NiNjY5ZmRkZmY3YWJi NWEwMDI4YTI4YTAwZTJmZTI5ZGM0OTA3ODAyZmQ2MjZjMzRjNTIyZmYwMGJlOWFiYTdkMzJkNDU4 Njk3NmI2ODNmZTU4NDRiMWZlNDJiODlmOGMNCjZlZGZmMDg3NWI0MmJmN2E2YmY4OTNmNDZhZjQx MWY3NDUwMDNhOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAy OGEyOGEwMDI4YTI4YTAwMjhhMjhhMDAyOGEyOGEwMDI4YTI4YTAwMjhhDQoyOGEwMDI4YTI4YTAw MmIxZmM0NWFlMjY4M2EzY2I3YWQxOTk2NWRjMjM4NjI1ZWIyNDhkZjc1NmI2MmI5OWJmYjY2YmFm MWM2OTdlNzMxNWI2YjZiNzkyNThkNzFmMmJjYmY3N2Y0NWEwMDkzYzM1YTFjOWE3MjRiN2RhOGM5 ZQ0KN2VhZjc3ZjM1YzRkZmRkZmY2MTdmZDk1YWU4YTkyOTY4MDBhMjhhMjgwMGEyOGEyODAwYTI4 YTI4MDBhMjhhMjgwMzk5ZjE4YzhlZmE0NDc2MTFiMTU5NmZlNzRiNjFiNTgyYjZkNmViNWQwYzUx YWMzMTJjNmJmNzUwNmQxNWMNCmM1ZGY5ZDdmZjEwZWM2MTAxNGRiNTg1YjM0ZWRjN2YxYjdjYjVk MzRmMmFjMTA0OTJiN2RkNDUyYzY4MDM4ZWYwZmRiYzVhYzc4YmY1N2Q2ZGU0MzMzNWJjYWQ2OTA3 Y2RmMmE2ZGZmMDAzZmY4ZjM1NzYzMmNiMWMxMTM0YjJiDQphYTIyMmU1OTk5YjBhMmI5MmY4NjA4 N2ZlMTA2YjRiYTc2ZGQzNWU0OTM0ZjIxZmYwMDY5OWRiZmMyYjIzZTIzNmExNzFhODY4OTc3Njk2 NzI3OTc2NjkzYzc2ZDM0YWJiOWJjZDkxYmY4M2U1ZmUxNWZlMmEwMGY0NTQ5MTY1NA0KNTkxMTgz MjExOTU2NTNjMWE5MmI4OWYxOGY4OTA3ODZmNDQ5MzRkZDJhMzMyZGZhNWIzMzIyNDZiYmJjODg5 NTdlZmI1NTY1ZjE0NDU3NzY3NjdhMDc4NWVlOTZmZWY1YTA0NTdiYmRkYjkyMDhmNmZjY2VjZGZk ZWZmNjY4MDMNCmE0ZDM3YzQxMGVhYmFkNmEzNjMwNDdiOTJjYjZhYjRiYmZhYjM3NmM1NjljNzc3 NmYzNWNjOTZlOTMyMTllMjAwYmM2MWJlNjVjZmE4YWYzNGQyNzQ2ZjEzNjk3N2RhYjY4OWE0ZGEz NWFkOWNmNzdlNjdmNmE0ZWRiOTg0NWI1DQo1N2U1NWZlMjZmYmQ1NmQ3YzFmZTI0ZjBmZWJiNzU3 M2UxOGJiYjY2ODJmYTM4YzRmMjZhMGVkMjRhYWViYmIyZGZlZDdkZWEwMGU4ZmM0MWUyMzE2NTJh ZTk1YTYyYWRjNmIxNzBiODhlMTVmZjAwOTY0YmZmMDAzZDFmZmJhYQ0KMmJjOWVjYjVlYjhkMjEz YzQ5NzU2MTcxMjZhNWFiNGNjYzhkNzZhYmZlYWEyOGZlZjRiZmYwMjZmYmJmZWVkN2FlZTgxZTE5 ODM0NjEzZGM0ZjIzNWRlYTM3NWNkY2RkNDgzZTY3ZmYwMDY1N2ZiYWJmZWNkNGRhMzc4Njc0YWQN CjAyMDlhM2QzYWQxMjI1OTk4YjQ5OWY5OGI3ZmIzOTNkYTgwM2NmYmMyOWUxZGJjZjE0Nzg0ZTI2 ZDZhNGJiNTgyMzhkZDZkMTY3NmRkYmRkYjc3ZWY5YmZiZGYzMzdjYWI1YWZlMDJiYmQ1MzQ5ZDU2 ZWJjMWRhOWFkYjRiZmQ5DQpkMDJjYjA1Y2MxZjJlZThkYmZiY2JmZGVhZjQzNTUwYmQyYjhiZjEz Nzg0MzUwYmJkNzIwZjEwZjg3NzUwNGIwZDVhMzVkOTJmOThiYmEyOWUzZmVlYjUwMDZmZWJiYWY1 OTc4N2Y0ZjdiYmJlOTMwYWJmNzIzNWZiZjJiN2Y3NQ0KNTdiZDczZmEwZTg1N2ZhYzZhY2JlMjRm MTFjN2I2NjFjZDhkOGIxZGNiNmFiZmRlM2ZlZGQ0OWExZjgyYWU2MmQ0ZDc1YWYxMWVhNGRhYTZh NmJmZWFmZTVkYjE0M2ZlZWFkNzY1NDAwNTJkMTQ1MDAxNDUyNTY2NmExYWI0MWENCjcyN2NkYmU2 OWRiZWU0MTEwZGQyM2ZmYzA0N2YzYTAwZTNmZTJiNGIxYWQ4ZTgxMGJiMmFjNmZhYjQ0Y2RmMzdm MGFhYjU3NWI2NWUyNGQxNzUxYmE2YjRiM2Q0YWRhNzlkNzg2OGUzOTM3NTc5OGZjNDZkM2Y1NmQ1 NjFkMGNlDQpiN2IyZGUzYjhiZmYwMDI1NmNlMDZkZGIxNWJmODk5ZmY4OWFiNDM1OWYwOWU5ZGEw N2Y2MGI2OTUwNzkxMmM1N2IxNDZhY2FkZjMzN2ZiY2Q0MDFlYTk0YjQ5NGI0MDA1MTQ1MTQwMDUx NDUxNDAwNTE0NTE0MDA1MTQ1MTQwMA0KNTE0NTE0MDA1MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1 MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQwMDUzNzY4Y2QzYThhMDAyOGEyOGEwMDI4YTI4 YTAwMjhhMjhhMDAyOGEyOGEwMDI5MGZkZGE1YWM0ZjE1NmE3ZmQNCjkzZTE5ZDQ2ZjU1OTQzYzcw YjJhNjdmYmNkZjJhZmViNDAxOTllMTA1MTdkN2RhZDZiODE0N2ZhNjVjZjk3MWI3ZmQzMzhmZTVm ZjFhZTkyZjIwMzc1NjczYzAxYjY5OTYzNjhmM2Y1MTU0M2MzMTYxZmQ5OWUxYmQzZWQzZjg5DQoy MTUyYzdmZGE2Zjk4ZDZjZDAwNzhlNjgzYWE2YjJkYTE1OGY4MmI0ZWIyYmNiMWQ0ZTA5MTkyZWVl ZGEyZmRkYzExNmY2NmRjYWRmZWQ1N2EwZGU3ODRiNGZiZGYwYzdmNjE2NjU4ZWRjNmQ2NTkyMzZm ZGUyYzhhZGJiN2VlZg0KZWY2ZWFlOGE4YTAwYzBkMTNjMmRhN2U4NTZkM2E0N2U2ZGQ0YjcxZmVi ZWUyZTliY2M5MjVmZjc5YmQyYWZlOTlhMzY5ZGEyZGJiNDFhNjU5YzM2YjEzMWRjY2IxMmVkYzlh ZDBhMjgwMTM2ZDJkMTQ1MDAxNDUxNDUwMDE0NTENCjQ1MDAxNDUxNDUwMDE0NTE0NTAwMjU0Mjkw NDQ4YzU5NTE3NzMwYzE2ZmUyM2Y4ZDRmNDUwMDc5Y2ZjNTMwNTFiYzM3NzI3ZmQ1NDVhOTJlZTNm ZTdmZGRhYjllMjZiYWYzYmM1NWUxOWQzZDFiMmM2ZWZjZTZkYmZkZDVmZjAwDQpmNjZhYmZjNjI1 NjVmMDVjNTNhZWRmZGM1ZWM0ZmYwMDM3ZmMwOTdmZjY2YTg3YzM3MjM3ODhmZTIzNWVlYWNiMjJi ZDllOWQ2ZWIwNDBjYWJjNmY2ZmJkZmYwMGIzNTAwN2EzZDJkMTQ1MDAxNDUxNDUwMDE0NTE0NTAw MTQ1MQ0KNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUw MDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAw MTQ1MTQ1MDAxNWM3NzhlMWQ2ZmENCjZkMWY0MWRjMzdkZjVlYWI0OGJmZjRjYTNmOTlhYmIxYWUy YWNkNGVhYmYxNDJmYWU0YWZlZTM0YmI0NTgyMzZmZjAwNmU0Zjk5YTgwM2IzNTFiNTQyZDNhOTI5 NjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwDQphMjhhMjgwMGEyOGEyODAwYTI4 YTI4MDBhMjhhMjgwMzg1ZjhiMTI0MmJlMDBiYjg5ZTM3NzkyNjkxMTIyNThkNzc3Y2ZiYjc3ZmVj YTZhYzdjMzhmMGM0OWUxN2YwYTQzNmY3MWI4ZGU1YzM3OWYzZmYwMGIyY2RmYzNmZjAxYQ0KZWMx OTQzMGMzMGNkMmQwMDJkMjUyZDE0MDA5NGI0NTE0MDA1MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1 MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQwMDUx NDUxNDAwNTE0NTENCjQwMDUxNDUxNDAwNTE0NTE0MDA1MTQ1MTQwMDUxNDUxNDAxMDVkNWNjNTY3 NmQyNWM0ZWRiNjI0NWRjY2Q1Yzg3YzM3MDZlMzQ1YmVkNWU0ZGRiYjUyYmY5Njc1ZGRmZGRkZGI1 NmFiN2M0ZGQ1NGRhNjhmMjVhNDRlZGU3Y2YxDQpmOTQ5MWFiN2RlNjkxYjZhZmYwMGVjZDVkNjY4 N2E3MmU5NWExZDhkODAxZmVhMjA1NGZmMDA4MTYzOWEwMGQzYTI4YTI4MDBhMjhhMjgwMGEyOGEy ODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMA0KYTI4YTI4MDBhMjhh MjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEy ODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGEyOGEyODAwYTI4YTI4 MDANCmEyOGEyODAwYTI4YTI4MDBhMjhhMjgwMGE0YTVhNDNmNzY4MDNjYzc1ZmQ5YWNmYzUyZDFl YzEwMmM4YjZmMjc5ZjI3N2RiYjE3ZmYwMDhhYWY0ZmFmMjlmMDRlOWQ4ZjhiN2UyYjlmZTVkYjAx MmFiZjJmZjdkYjc1N2FiNTAwDQoxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0 NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1 MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMA0KMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0 NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1 MDAxNDUxNDUwMDE0OTQ1MTQwMTlmNjVhNDU4ZTlmNzc3OTc1NmIwMmE0ZDc5Mjc5OTMNCmJlN2Vm YjU2OGQxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUw MDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAw MTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAxNDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDAx NDUxNDUwMDE0NTE0NTAwMTQ1MTQ1MDA3ZmZkOX0NCn19e1xzcHtcc24gZlByZWZlclJlbGF0aXZl UmVzaXplfXtcc3YgMX19e1xzcHtcc24gZkxheW91dEluQ2VsbH17XHN2IDB9fXtcc3B7XHNuIGZC ZWhpbmREb2N1bWVudH17XHN2IDF9fXtcc3B7XHNuIGZMYXlvdXRJbkNlbGx9e1xzdiAwfX19e1xz aHByc2x0XHBhclxwYXJkDQpccWwgXGxpMFxyaTBcd2lkY3RscGFyXHB2cGFyYVxwb3N4MTYzMFxw b3NuZWd5LTMwM1xkeGZydGV4dDE4MFxkZnJtdHh0eDE4MFxkZnJtdHh0eTBcYXNwYWxwaGFcYXNw bnVtXGZhYXV0b1xhZGp1c3RyaWdodFxyaW4wXGxpbjBcaXRhcDAge1xwaWN0XHBpY3NjYWxleDQ0 XHBpY3NjYWxleTQ0XHBpY2Nyb3BsMFxwaWNjcm9wcjBccGljY3JvcHQwXHBpY2Nyb3BiMA0KXHBp Y3cxMjI1MFxwaWNoNzQwOFxwaWN3Z29hbDY5NDVccGljaGdvYWw0MjAwXHdtZXRhZmlsZThcYmxp cHRhZzEzNjg0NTg0ODFcYmxpcHVwaS05NntcKlxibGlwdWlkIDUxOTEwNGYxOTYzOTAzNjllNWIy NjZmNzQyZmNmMDM5fQ0KMDEwMDA5MDAwMDAzMDYwMDAxMDAwMDAwZTFmZjAwMDAwMDAwMDQwMDAw MDAwMzAxMDgwMDA1MDAwMDAwMGIwMjAwMDAwMDAwMDUwMDAwMDAwYzAyMTkwMWQwMDEwMzAwMDAw MDFlMDAwNDAwMDAwMDA3MDEwNDAwZTFmZjAwMDANCjQxMGIyMDAwY2MwMDE4MDFjZjAxMDAwMDAw MDAxODAxY2YwMTAwMDAwMDAwMjgwMDAwMDBjZjAxMDAwMDE4MDEwMDAwMDEwMDA4MDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwDQowMDAwZmZmZmZm MDBmZWZlZmUwMGY3ZjdmNzAwZjhmOGY4MDBmOWY5ZjkwMGZhZmFmYTAwZmNmY2ZjMDBmZGZkZmQw MGZiZmJmYjAwZjVmNWY1MDBmM2YzZjMwMGY0ZjRmNDAwZjZmNmY2MDBmMmYyZjIwMGVhZWFlYTAw ZTNlMw0KZTMwMGVmZWZlZjAwZTdlN2U3MDBkMmQyZDIwMGI3YjdiNzAwOWI5YjliMDA4MzgzODMw MDcwNzA3MDAwNjc2NzY3MDA1MDUwNTAwMDRmNGY0ZjAwNGU0ZTRlMDA0YzRjNGMwMDRiNGI0YjAw NDk0OTQ5MDA0ODQ4NDgwMDQ3NDcNCjQ3MDA5YzljOWMwMGI4YjhiODAwZGVkZWRlMDBmMWYxZjEw MGQ3ZDdkNzAwYzJjMmMyMDBhYmFiYWIwMDk2OTY5NjAwOGE4YThhMDA2ZTZlNmUwMDYwNjA2MDAw M2EzYTNhMDAzMTMxMzEwMDMzMzMzMzAwNDA0MDQwMDA0NTQ1DQo0NTAwNDM0MzQzMDA0MTQxNDEw MGEwYTBhMDAwZDZkNmQ2MDBmMGYwZjAwMGU0ZTRlNDAwYThhOGE4MDA3YzdjN2MwMDY0NjQ2NDAw NTI1MjUyMDA0ZDRkNGQwMDMyMzIzMjAwNDI0MjQyMDA1ODU4NTgwMDc3Nzc3NzAwOTU5NQ0KOTUw MGE5YTlhOTAwYjBiMGIwMDBhZWFlYWUwMGFhYWFhYTAwYzVjNWM1MDBjN2M3YzcwMGI5YjliOTAw YjJiMmIyMDBjNGM0YzQwMGU2ZTZlNjAwZWVlZWVlMDBlY2VjZWMwMGQwZDBkMDAwYWNhY2FjMDA2 ZjZmNmYwMDViNWINCjViMDA1YTVhNWEwMDU1NTU1NTAwNjE2MTYxMDA3ZTdlN2UwMGE1YTVhNTAw YmFiYWJhMDBkMWQxZDEwMGRmZGZkZjAwZWJlYmViMDBlOWU5ZTkwMGI0YjRiNDAwOGQ4ZDhkMDA3 MzczNzMwMDM3MzczNzAwM2QzZDNkMDA1NjU2DQo1NjAwNzI3MjcyMDA4Njg2ODYwMGQ5ZDlkOTAw ZDVkNWQ1MDBkY2RjZGMwMGVkZWRlZDAwZTBlMGUwMDAyZDJkMmQwMDM4MzgzODAwNDQ0NDQ0MDA1 ZjVmNWYwMDg1ODU4NTAwYjNiM2IzMDBjY2NjY2MwMGU1ZTVlNTAwYjZiNg0KYjYwMDkxOTE5MTAw NTE1MTUxMDA0NjQ2NDYwMDZkNmQ2ZDAwOTc5Nzk3MDBkNGQ0ZDQwMGRhZGFkYTAwYTdhN2E3MDA4 YzhjOGMwMDYzNjM2MzAwNjI2MjYyMDA0YTRhNGEwMDM5MzkzOTAwYzBjMGMwMDA5MjkyOTIwMDM1 MzUNCjM1MDAyYjJiMmIwMDdkN2Q3ZDAwZThlOGU4MDBjYmNiY2IwMDc4Nzg3ODAwNWU1ZTVlMDAz ZTNlM2UwMDM0MzQzNDAwM2YzZjNmMDA3ZjdmN2YwMDI2MjYyNjAwM2MzYzNjMDA1ZDVkNWQwMDhm OGY4ZjAwYmZiZmJmMDBlMWUxDQplMTAwZDNkM2QzMDA1YzVjNWMwMGNhY2FjYTAwNjg2ODY4MDAy NzI3MjcwMGEyYTJhMjAwODI4MjgyMDAyZjJmMmYwMDM2MzYzNjAwNTc1NzU3MDA2YjZiNmIwMDlh OWE5YTAwODQ4NDg0MDAyZTJlMmUwMDJhMmEyYTAwMjkyOQ0KMjkwMDMwMzAzMDAwNTk1OTU5MDBh MWExYTEwMGIxYjFiMTAwOTA5MDkwMDA2YTZhNmEwMGJjYmNiYzAwNjk2OTY5MDA3Njc2NzYwMGRi ZGJkYjAwYTRhNGE0MDA5MzkzOTMwMDNiM2IzYjAwOWU5ZTllMDA4MTgxODEwMGUyZTINCmUyMDA5 ODk4OTgwMGI1YjViNTAwY2RjZGNkMDBjOWM5YzkwMDcxNzE3MTAwMjMyMzIzMDAyMjIyMjIwMDg3 ODc4NzAwYmViZWJlMDBhM2EzYTMwMDY1NjU2NTAwMjAyMDIwMDBjNmM2YzYwMDFkMWQxZDAwYzFj MWMxMDA4OTg5DQo4OTAwMTkxOTE5MDA5NDk0OTQwMGMzYzNjMzAwY2VjZWNlMDA5ZDlkOWQwMGFk YWRhZDAwZDhkOGQ4MDBjOGM4YzgwMGFmYWZhZjAwNjY2NjY2MDAxZjFmMWYwMDFjMWMxYzAwZGRk ZGRkMDAyNTI1MjUwMDdhN2E3YTAwN2I3Yg0KN2IwMDlmOWY5ZjAwYTZhNmE2MDA4YjhiOGIwMDJj MmMyYzAwOGU4ZThlMDBiYmJiYmIwMDc5Nzk3OTAwMjEyMTIxMDA5OTk5OTkwMGJkYmRiZDAwNTM1 MzUzMDAxZTFlMWUwMDc1NzU3NTAwMjgyODI4MDAyNDI0MjQwMDgwODANCjgwMDA3NDc0NzQwMDZj NmM2YzAwODg4ODg4MDBjZmNmY2YwMDU0NTQ1NDAwMTgxODE4MDAwYjBiMGIwMDBmMGYwZjAwMDkw OTA5MDAxNDE0MTQwMDExMTExMTAwMWIxYjFiMDAxMzEzMTMwMDBlMGUwZTAwMGQwZDBkMDAwMDAw DQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAyMDIwMjAyMDIw MjAyMDIwMzBhMDUwMTAxMGEwYTA4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDAwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMTA3MDUwNzAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxZmYwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAy MDIwMjAyMDIwMTAyMDUwYTA0MDEwMTA5MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDAwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwNTAxDQowMTA2MGQwNDA1MGQw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxZmYwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDIw MjAyMDIwMjAyMDIwMjA3MDgwMTAxMDEwNjA2MDgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMDAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAxMjM1NzBmMDEwODA5 MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDIwMjAyMDIwMjAyMDIwMjAxNTVhOTQ0NGIwMTA1MDgwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDFmZjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAxY2YNCjY4ZGQ1 ODAxMDUwNDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMDAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwODAyMDEwMTAxMDIwNzA5MGQzNzY4MzBiNDAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAwMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwODAyMDEwMTAxMDIwNzA5MDMzMzlm ODdkYTA4MDgwNzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMWZmMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwODAyMDEwMTAxMDIwNzA5MDFkOTllMmNjOTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAwMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwODAyMDEwMTAxMDIwNzA5MDFj MA0KOWVhMTQwMGQwMTA3MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMWZmMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTA4MDIwMTAxMDEwMjA3MDkwYWI1NjhkZjVkNmYwNTBhMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDAwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA4MDIwMTAxMDEwMjA3 MDkwY2E4ODc4MTdhOTAwODA3MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDAwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTA4MDIwMTAxMDEwMjA3MDkzNTdiM2IzYzUyNjUwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDAwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA4MDIwMTAxMDEw MjA3MDk1ODcyDQoxZWEwMzI4NDBlMDMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDkwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjA0NDNkNWU1YWRhMzA0MDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwOTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAy MDIwMjAyMDIwMjAxNzY3ODc0OGM4MjgzMDYwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMDAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjA5MGJiMjZjM2RlNTYzMDcw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIw MjAyMDIwMjAyMDIwMjI0MDENCjcwNDAxYTY5NDUwNTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMDAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMGQwMTU2YTNiYjJl NDQzNTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA0MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMjAyMDIwMjAyMDIwMjAyMDYwMTI2NDQzODg5YTUzNTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAw MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDUwNzRkYzYx NjMyYTY1YTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAwMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIwNg0KNThjNjgyODgzMjY0MDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAzMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNTA3 MDNlMzQxNmJjYjU1MDcwMTAzMDEwMTBiMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDAwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIyNzcwZTA5Zjg1ODMwMTA5MDkwMjAzMDgw MjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDAwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MjA1MDZlNDE0Nzg4NzMyYzgwMTAxMGIwNzA4MDgwNjAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNTBiDQowNTBmNDg0NWNhOThiYTA3MDExMTA3 MDEwMTA0MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDAwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDYwMTA0NDNjNDVjN2Q4YTRjMDEyNDA3MDEwMTA0MDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMDAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDUwMTM1Yzk3ZWM1NWY1MzkxMDEw NDA2MDEwMTA1MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAyMjQwMTU5YjMyNjQyMjAxYzIyMDUwMTAzMGQwMTA0MDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMGINCjAxMGQwNWFhYzQyYjJm ZDIwZTAxMGExMTAxMDQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwNjAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDUwMTAxMDIwMTBkN2U2Yzg3N2I2NjAxMGQwMTY3MDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDkwMTAxMDYwMjA5MjU0 NDZhMWY0ZDA4MGEwMTVhMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDgwMTAxMGQwNjAxMGU3N2JiODg0MzAxMDQwMTBhMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDcwMQ0KMDEwMzA1 MDEwMTA1YjEyZTcxMDEwMTAxMDgwNjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwNjAxMDEwNzA5MDEwMTAxYjk2OWI1MjQwMTA4MDEwNTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwOTA4MDEw MTAyMDgwODA3ZTQzMTcyNzYwMTA1MDEwODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA3MDcwMjAxMDIwOTA2MTA4NjZhYTcwMTAzMDcwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA3 DQowNDA3MDEwMTA4MDgwNTM4MWY2ZDAxMGEwYTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxNDgwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEzNTkzNjBlMDBkMDIw OTA5MDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAxMDEwMjAyMDIwMjAyMDIwMjAyMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEyYTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwYTYzYTIzOWNkMDgwNzAyMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDIwODA4MDgw ODAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNjM1Y2EzZDIy MDYwMTAxMDIwMg0KMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwODA4MDcwNzAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDExMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTA3MDE5ZDg4NDAwYTAxMDIwMjAyMDIwMjAyMDIwMjAyMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDgwODAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA3MDE0 MzZhODU0YTAxMDYwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDcwNzAyMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTYzMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA4MDFjN2NhNTA4NDAyMDMwMjAyMDIwMjAyMDIwMjAy MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDcwOA0KMDIw MTAxMDIwODA3MDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAwMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MzUwM2I4ODkyNzA2MDMwMjAyDQowMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDEwMjA3MDUwZDBiMDIwMjAyMDIwMjAyMDIwMjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTI3MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEzNjAxOWNkNGMyMDMwNTAyMDIwMjAyMDIw MjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwODA1MGMxMTRjMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMzBjNGQxZjFkNmYwZTAxMDEwMTA4MDcwNzAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNzU5MDEwNDAxZTI4NjVkMDMwZTA3MDEwNzA3MDEw MTAxMDENCjAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNjA1MTIxNzFhOTMwNTAyMDEwMTAy MDcwNzAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTA5DQowMTBiMjQ5NDg4OWU0NDBhMDE0YjA4MDkxMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwOTA5MDFkMmRiMTUwODA3MDINCjAxMDIwODA3MDIwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA5MDIwMTA2MDkzMzZhYmMxOTkwMDE2ZjAx MDgzNjAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwOTA1MGQwMTEzYTJlMjBhMDYw NzAyMDEwMjA4MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTExMDkwNzAxMDEzNjliNjliNzMzNTkwYTAxMDIyNDAxMDEwMTAxMDEwMTAxMDEwMTAyMDIw MjAyMDIwMjAyMDIwMjAyDQowMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDIwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwODA2MGIwMTY2ZTIxYmNkMDMwNjAyMDEwMTAyMDIwMjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA5MDEwNzA4MDEwZTdhYTFiNzIwNWIw MTAyMDQwMTA1MDEwMQ0KMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDMwODA3ZDUxZjcw MGMwNDA4MDEwMTAxMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDINCjAxMDkwYTgzMWE5ZTJkZWY4NTA0MGQyNDAxMjQwMTAxMDEwMTAxMDEwMTAx MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwZDAxNmQxYmUzMGUwMw0KMDgwMTAxMDEwMjA4MDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMTAxMDEwYWFhM2QyY2Fk ZWVlNTU3MDQwZDA4MDQwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwYzAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTBlMDE5 M2RiOTQyNDBkMDgwMTAxMDEwMjA4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDE2ZjAxMDEzNTQ1ZDQzYzg3OWY3YzQyMDEwMTBlMDEwMTAxMDEwMTAxMDEw MTAxMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMjAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAyMjQwMTM2MDEzNjNhM2FjMzAxMzUwNDAxMGUwMjAyMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNTAxMDEwNDQ0ZGY4 OGRkMzAxYjYyMDEwODAyMDIwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA0MDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMGMwMTM1 MDEwYmQ3NjA2ZDAxMGQwYjAxMGMwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwNA0KMDEwMTA4Mzc5ODMyYmE4NTFiYThhYTA5MDMwODAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTNkMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMGQwMTA3MDEwNzM3MTliMTA3DQowMjExMDEwNTA3MDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA1MDEwODA3 Mjg5ODMxNTcyMmU1MWNhNDAxMDYwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw NDA2MDEwYzA1NmU3Y2NmODMwMTM1MDcwMTA0MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA3MDEwNDBkM2Y5NTVmMzQyNTNlOTllMzAxMDQwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMWZmMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNjAzMDE2NjA0NWE4NjdiYjQwMTAzMDYwMTBk MDcwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA4MDEw ZDAzN2I5ZTIwZTQyMzk0Njg4NmIwMTEwZDAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxZmYwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMjA1MDEzNTA4MDFkNWEyZDIwMjAyMDMwMTBkMDcwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwOTA3DQowMTA0MDFhMjMyNmIzNjExYzU3MzFkNDcwZTA5 MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxZmYwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDgwMTA3MDEwYzAyMDFiOTkyYjgNCjBlMDEw ZTAxMDQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA1 MDcwMTAzMDEzYjdjOWIwYTBhYzcyYTFlN2YwNjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxZmYwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwOTAxMDkwODBiMDYwMTI1N2JkZDVhMDE0YjAxMDYwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA5MDIwMTBhMDE4OTZhY2EwZjM2MzVhZjZhNjEw ZDAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxZmYwMTAxDQowMTAxMDEwMTAxMDEwMTAyMDIwODA4MDIw MjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwODAyMDEwMTAxMDIwNzA5OWQzYWIz MDEwMzAxMDEwYTA3MDIwZDAxMDIyNDA3MDE4M2M4ZTM5YTIyNGMwMTRiMDEyMzA3MDEwODAxMDQw MTBiMDkNCjA4MDkwMTAxMDEzNTAxMDIwMjAyMDgwODA3MDcwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMGQwNTA3MDgwNTAzMDkw MTAyMGYwMTAxNjUxZDMxOGE1YTY1NjZjMjlhOWE1NzAxMDIwMg0KMDIwMjAyMDIwMjAyMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDFm ZjAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwODA4MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwODAyMDEwMTAxMDIwNzA5ZDE1MTZkMDMwMzAxMDEwODA3MDgwZDAxMDIwZDAxMDI1 NjlhDQphMWVkN2Q0ZmFhMDEwMTA3MDEwNDY2MDIwMTA1MDEwMTAyMDEwMzRjMGUwMTA0MDUwOTA3 MDEwMTAxMDgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MjAyMDIwMjAyMDIwMjAyMDIwODA4MDgwNzA3MDIwMTAxMTENCjAxMDViMzZhMzA4ZTAzMTIwMzQx N2ExYWRhMDUwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDFmZjAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAy MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwODAyMDEwMTAxMDIwNzA5NDU5 NA0KNzk2ZjA0MDIwYzAxMDcwODAzMDEwODA2MDEwZTRmZWE2MDk0MmNkNDM3MDY0YjAxMDIwMTA5 MGEwMTI0MDMwZTBkMDEwMTAzMGQwMjAxMDEwMTAyMDIwMTAyMGQwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyDQowMjAyMDIwMjAyMDIwNjA3MDIwMTAx MDEwOTAzMDEwYzAxMGUxNDJjMWZhYjA4NjYwOTQ1YTk3Y2QyMDkwMjAyMDIwMjAyMDIwMjAyMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDFmZjAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTA4MDIwMTAxMDEwMjA3MDkzNjU0YTZlNDA3MDE1YTAxMDkwNzA1MDIwNjA5 MDkyNTJjODgxMzA2NzgzMmE4ZDYwYjAxNGMwMjAxMGQwMTA4MDEwMTA4MDMwMjAxMDE0YjA4MDEw MTA2MDMwOTA3MDUwMjAyDQowMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAyMDIwMjAyMDIwMjAyMDIwNzA4MDcwNTA0MDkwNzA2MDEwNTAxMjRhYjJlMWY3MDBhODMw YTIzNzkzYjI4MDEwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDFmZjAxMDENCjAxMDEwMTAxMDEwMTAxMDIw ODA4MDgwODAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA4MDIwMTAxMDEwMjA3 MDkwNGM1OTI3MDAxMDE1YTAyMDkwODA5MDIwZDA2MjQ3MDgwMzkwNDAxNmZlMTgwY2ExMjAxMDMz NjA1MDg0YWM4NjUxMQ0KMDYwYTBlMDQwOTAzMDQwNzAyMDUwZDA0MDIwMTAyMDIwMjAyMDIwMjAy MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMTAxMDgw YzI0MDUwMTAxMDgwODAyMGFkOTNjNzM3ZTExNWExMTExMjFkYjlkMDEwMjAyDQowMjAyMDIwMjAy MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMWZmMDEwMTAxMDEwMTAxMDEwMTA4MDgwNzA5MDkwNzA4MDgwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTA4MDIwMTAxMDEwMjA3MDkwMTI2ODZhYzA0MDEwYzA3MDcwODA4MDgw YjA4NGIzMzJmMTcNCjBmMTAwMWM4MWEyMDVjMzYwMTRhMDQwNjYyMzIyZjJhNzAwZTAxMDYwOTAx MDcwNTA4MDEwMTA5MDQwOTA4MDgwODA4MDgwODA4MDgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAyMDIwMjAyMDIwMjAyMDI2NjA0MDEwMTAxMDEwMTBkMDUwMQ0KMDkwN2MyOTk2YTI2 MGUwYTExMDYzNzhkYTkwNTAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMWZmMDEwMTAxMDEwMTAxMDEwMTA3 MDkwNjA2MDYwNjA5MDcwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA4MDIwMTAxMDEw MjA3MDkwMjU4DQozOWE4YjAwODAxMDYwODA4MDgwNjI0MDEwYTE1OGM4NjA1MGUwMTAxYzY3OTg2 YzIwMTA0MDEzNDY4ZDRhMTY5Mzk2ZDBhMDEwZDEwNDIyNzdlNTkwMTAxMGEwYTA3MDcwNzA3MDcw NzA3MDcwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDINCjAyMDIwMjAyMDIwMjM2 NTkxMTBlMDcwMTA5MGYwNTAxMDQwMWFjOGMzZGJmMGIwMTRiMDE0ODJhZGQwMzAyMDIwMjAyMDIw MjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMWZmMDEwMTAxMDEwMTAxMDEwMTA5MDYwNTA1MDUwNTA2MDkwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDgwMjAxMDEwMTAyMDcwOTA1NGJiYjFlYzQwYzAxMDMwMTA4 MDcwNTI0MDEwOGQxMmU3MzAxMDg2NTA5MDQ0Y2FjY2ExMzBjMDE0ZWVjOTY1YTI4MWY5YWIyMDkz Njc4ZDQ2ODUwNmQwYTAxMDEwMTA3MDcNCjA3MDcwNzA3MDcwNzAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjA0MTJjNGMzNjQwZTAyMDUwOTAxMGEwMTdmODkz MjdlNGIwMTU5MDE0NzhhODIwNzAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMWZmMDEwMQ0KMDEwMTAxMDEw MTAxMDEwYjAxMTJjNTIyMDIwYTAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAyNTk0NmQwNTUwMTA4MDcwODA4MDgwNTA4MDExMmIyODg2YjA0MGIwMTI0MDgw MTgzZGQ5ZDAyMDE0MGE4ZTMwNDA3DQo1NjZiNzJjMzEwNmFkZjJjODEzZDhhZTQwMTRhMDEwZDAx MGIwZDA4MDkwMTAyMDYwODAxNTkwNTAxMDEwMTA2MDUwMTAxMGQwZDAxMDcwZDAyMDEwODA0MDkw NDA4MDgwODAyMDIwMjAxMDEwYjA1MDIwMTAxMDEwNjM1MDEwMQ0KMDEwMTAxMDEwODA3MDIwMjAy MDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIw MjBkMDViMDQyNzFiYTY0MDkwNjAyMDEwMjIyODczZGJmMzU0YzEwMGU2M2E5MmE2NTAyMDINCjAy MDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxZmYwMTAxMDEwMTAxMDEwMTAxMDEwMzBiNmRhNWU0MDEwNzAyMDIwMjAy MDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMGFjNGRkOGUwYjA3MDkw ODA4MDIwNjA3MDE0Y2JmODg3Yg0KMDIwNDAxMGUwMTAyMDEyM2FmNDQwMTlkZWIzZjA4MDE0YzRl OGQxOGFmODEyOTY1YzY3YzY5NWMwZTA3MDM4NDI4NzUyNjAxMDY2NzA3MGEwYTAxMDEwMTA2MGU1 OTAxMDEwYjRiMDIwMTBlMDEwZDA0MDIwOTA3MDEwMjAyMDINCjAyMDIwMjAyMDEwMTAxMDEwODEx MTEwMjAxMDEwNzA5MDcwMTAxMDEwNzA0MDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjA2MDMwMjAxNjc3ODE2NTQwZDAxDQowMTBj NDQ1ZjczMjIwYzA0MzUyNDg0YTg0ZjVhMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxZmYwMTAxMDEwMTAx MDEwMTAxMDEwNzM1ZDVlMzM1MDEwMTAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTA4MDENCjc3NjFiNTM0MDgwNzAyMDIwMTA5MDYwMTBjNzYzYzZiMDEwMTA4 MGMwMTA2MTEwMTQwZDAwYzcwM2JhYjA3MDcwMTA4ZDFlNTUyM2NjNzAxODM0OGQ3MjAyOTM1MTEz MzNjNmE3Y2M1YzgwMTU5MDEwOGM3OTM3MGI0MGIwMTAzDQoyNDA0MDEwMTA5MGIwNTA5MDEwODA1 MDEwMjVhMDEwMTAxMDEwMTAxMDIwMjA5MDgwOTA0MDYwNjRjYWExMTA1MDEwMTA5MDMwOTAxMDIw MjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMg0KMDIwMjAy MDIwMjAyMTEwYjA5MDEwMjkwYzk2Mjg1MjE5MDAxNTYzYzJjNDc2NzRjNGMwYzc2MTcyYjQ5MDIw MjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxZmYwMTAxMDEwMTAxMDEwMTAxMDUwNTAxNWM4NTExMDEwNjAyMDIN CjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDMwMWIwM2YzZTQ4 MDUwNzAyMDgwMTA3MDQwMTA3MTIyZDcyMGIwMTA2MDQwMTAzMGIwMTEzNzE4ZWMyYjU3MjAxNGM2 NjAxNGNjNTYxNWVjZDBjOTAwMTM1MmIzMWEzMDFjMg0KZWNhODY5YWQxODRiNjYwMTU3NjAzMjll MWFhZmU0MTIwODAxMDcwNjA3MDIwZjA0MDEwNDBlMDEwMTBlMDEwMTAxMDEwMTAxMDIwMjBjMjQw NzAxNGI0Mjg1NmIxNjQ0YWEwNjAxMDkwOTAxMDIwMjAyMDIwMjAyMDIwMjAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDEwMTBiNWEwYzAxMGU2NDkyMWVi ODkwNmQzYzhjZDY0YTVhMjM0YTI1ODIyYjI3MDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxZmYwMTAxDQow MTAxMDEwMTAxMDEwMzBjMDFjNTlhYTcwODA0MDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMGUwMTVhOGVlNWFjMGUwODAxMDcwMTAyMDQwMjAxMGM4Nzg3Yzcw MTA1MDkwMTBhMDEwNDAxNjU4YWNhNmI4YjA4MDMNCjM2MDIwMTIzMTU4ODI3MDEwNTM1MDFiZDgy NTE1YWQzYTE5MzIyY2Y1ZjUzMjQwNGM1ZWEyMDFkMzI4MTE5NWIwMTA5NmYwYjAxMDEwMTAzMDUw MjBlNTkwYTAxMDgwODA4MDIwMjAyMDEwMTAyMDUwODEyN2Y5ZWViZDRlNjgwDQo5YmM5NWEwMTAx MGMwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIw MjAyMDIwMjAyMDEwYjBlMDEwMTBkMjQwNDgzZDVhODE2NzQ3ZDFhMjg0YTBjNmYyNTQ3ZTIxOGMz MDIwMg0KMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDFmZjAxMDEwMTAxMDEwMTAxMDEwMTA3MDEyMjE5OGEwZTAx MDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDYwMTAzOGY3 NDE2NGIwMTAxMDYwMjAxMDUwODAxMDY3YTJkDQoxNDA3MDUwODAxMGQwNTBhMDEwMTc3ZDA3YzUx NjQwMTA2MGQwMTA3NGQ0ZmJiMjQwMTZmMDgwMWIzZGQ5N2E2ODdjZDAxYWFiODIwM2Y3ZjVkNjhh NDkzYjljMjg2OWFiODkwMDEwMjI0MDE5MDU2YjQwMTAxMGY1YTAxMDUwNg0KMDkwNzA4MDIwMTAx MDEwMTRhMTU4MGU5MzBkMTliNmFkZTZhZDUyNTA5MDEwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyODMxMTA1MDEwODA0MDYwMTAx NjYNCmU0N2YzZDgxMzExOWUzYjQ0YTM0ZDExZTUyYzMwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDFmZjAx MDEwMTAxMDEwMTAxMDEwOTAxMGNiMDU0NmJjZDAxMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDI1OTI5M2YzNjAxMDEwNDA3MDEwOTA3MDEwNjQw OTgxNTBkMDUwODAxMDUwNTAxNGIwYTA2YTMyZjVlYWUwMzAxMDgwMTAxMDk0Njk0YzQwYTAxMDEw ODI0YmYxOTlhOGMyMjA2MTExMjQzMmYzZDg3OWVjNzY2MDEwOTZlNTENCjNjMjgwNTAxNTk0YmI1 ZGIxNzQ1MDIwMTAyMDYwZDBkMDQwNjA3MDIwMTAxMDEwM2IyMTlhMDk0YjQwMTI0NTY0Zjg5MjAx NjRkMDEwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAy DQowMjAyMDIwMjAyMDIwNjAxMDE0YjU5MDkwMTAzYWEwMzAxNmZhODk1ZGVjZWI2ZGRkMjU1ZTA4 OWEyODQwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDFmZjAxMDEwMTAxMDEwMTAxMDExMjAxODMwMTZkOWE0 NTM1MDIwMg0KMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNzBh MDQwMjQwY2ExMzAzMDEwMzA5MDEwNzA5MDgwNWQ2MmU3OTBlMDUwNzAxMDcwMzAxMDU0YjAxMDI1 NTJkOWQzNjAyMDgwOTBhMDg4M2M2MjQwMTA0NWEwYTAxMTI5NzdiDQo2OWM5MDE2NjAxNmZiMDE2 NWY5ZTU5MGUwMTAxNGJjM2UyNjlkMDExMDEzNDFkN2QyZjVkYmYwNzBjYmQwYjBjMGQwNDA5MDgw MTAxMDE1OTI5ZGYyMDZlMDEzNTAxMDE5MGMyMWQxZGQ5NWEwMjAyMDIwMjAyMDIwMjAyMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMTBkMGUwODAxMDEw NjA3MDFiMDI0MDYzMzMyOTU4YmMxMzAxYjNiNTIxYzYyMDEwMjAyMDIwMjAyMDIwMjAyMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDE4 MDAxMDENCjAxMDEwMTAxMDEwMTA3MDE1YTAyMDIzODczNDcwMTU5MDEwMTEyMGQwMTBlMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwODAxMGE1OTQ1YjU5NzAxMDEwNDA0MDEwMTA5MDQw N2MzNzM1MTI1MDEwZDAyMDUwNTA5MDYwNjAxMDM0NmMyNWI3Nw0KMDgwMTA4MDkwOTA0MDIwMjAy MDIwMjAyMDIwMmU0NWM4N2UyMGYwMTRhMDEwMTU4N2Y1NGJmMDMwODAxMDgyNDI3ODc4OGM5MDFi MDUzMmU3MmI3ZDczNDZkMzExYjViMDEwZDAxMDFiNDAxMDQwMzhhZGYzODRjMDgwYzAxMDkNCjAx MzU0NDNlMWM1ZDEyMGQwMTA3MDcwMTAxMDkwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMGIwYTAyNjZjNmQ4ODdkZGUyMWMzYzJm NGY0NGNkMDkwMjAyDQowMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTgwMDEwMTAxMDEwMTAxMDEwMTA0MDEwYjA4 MDE3ODUyZTIwYzAzMGIwMzAxMDcwYTA4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw YjAxMDIwMTRjOGVjMDA2MDEwNjA1MDIwMTA3MDYwNzRhNWQNCjM5Y2QwZjA3MDIwMTAxMDEwOTBk MDEwMTA0NTgzNjBkMDEwMjA1MDcwMjA3MDIwMjAyMDIwMjAyMDIwMjEwYTQ1M2RkMzYwMTBlMDEy NDBkNjU3NjAzMDEwOTA3NGMwNTBlZGEyYTFiYzIwNDI2OGIxYTYyODc1ZDc5YjczMTlhDQoxNDM2 OTAwMTAxNzc0YzAxZDkyZDM4MGMwMTY2MDcwZTBlMDEwOGI0YjVkNDYyMjUwMTAxNGMwOTAxMDUw MjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwODI2YTExYWIxNThiZDQyYTQ0OTY1MjQwMjAyMDIwMjAyMDIwMjAyMDIw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTgwMDEwMTAxMDEwMTAxMDEwMTAzMDEwNTA0MDE5MDZjOGM0ZTA0MDg1OTAxMDE1OTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExMTA1DQoyNDAxMGI1Y2UyYzgwMTA4MDYwNzAx MDIwNzA3MDljMGQ3YmY4MzM1MDEwNjA3MDEwODBiMGEwMTAxMDIwMTAxMDgwYzBhMDgwMjA1MDIw MjAyMDIwMjAyMDIwMjA5MzRlMGUyYmYwNjAzMDU1OTAxMDEwOTAxMDEwNDAxMDIwNQ0KMDgwMWIz OTI3MjQyMDgxOTcyMjVhMjVmM2U5ZjJjZTg1MWFhMGM1ODAxMGExMTY0N2FiZTVkYjAwMjA0MDEw MTBjMjQwMTAxZDYyYjJkY2ZjNDA0MDkwMzA4MDEwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA1MDIwMTZlNjgxYTQyMDEw MjA0MDYwODA4MDgwMjAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTgwMDEwMTAxMDEwMTAxMDEwMTA5MDUw NjBkMDgwMTkzOTRkYmI0DQowMTBjMDMwMTA3MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDE0YjA5MDYzMzVkNWIwMjA4MDcwOTA4MDEwMTA3MDI3OTI5NzUwNTRjMDExMDBlMDIw MTA3MDMwNTAzMjQwNzA5MGQwYzA1MDEwMjAzMDIwMjAyMDIwMjAyMDIwMjAxMzUNCmM5ZDViZjBj MDYwNTA0MDEwNDExMDUwODA2MDEwMTA1NGMwNTAxNDZjZjYwNzA2YzczNTY4NDJhNWYyMDIwNzIx Yzk2MDEzNjY2MjMzN2EyZTc5ZWQxNTgxMTAxMDkwMTAyNmY4MzAxMDMyNTJiOGMyYmU0MDEwNTY2 MDEwMjAyDQowMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwODBiMGIwODU3Y2UzZDIyNjYwZTA2MDEwMTA4MDkwOTAyMDIwMjAyMDIwMjAy MDIwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTgwMDEwMQ0KMDEwMTAxMDEwMTAxMDEyNDA3MDEwMzAxMDViOTNiYjVjODAxMDkwMjAx MDMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA3MDk0YjAyMDE0OTc5YTMwZTA2MDIw OTA5MDEwMTA3MDE0MWE5OWQ5MTAxMDE0YzBlMDgwMTAxMDEwMTAyMDMwMzA2DQowOTA3MDEwMTAx MDcwMjAyMDIwMjAyMDIwMjAyMDEwMTRjNjcwYzAxMDEwOTA4MDEwNjA1MDEwMTAyMDYwYjAyMDEw YTBiMDk0NTk0MWZkZDg4OTQwMWMzY2EyZjMyZDljMDNlYTcwNjAxYTg2OGMxMmQ3ZjRiMDEwYzA3 MjQwNA0KMDcwOTA2MDgwMjA3NjQxNzY5ZTE5MTA5MDQwYzAyMDIwMjAyMDIwMjAyMDIwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDMwMTEwNjg1ZjQ3 MDYwMTAxMDEwODA2MDkwODAyMDINCjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxODAwMTAxMDEwMTAxMDEwMTAx MDEwYjAxMDEwMzA0MDEwYTMzMjAxNzZmMDEwNzAxMGIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTBjMDMwYTAyMDE0ZGMwN2I5MDBjMDEwNzA1MDEwMTA3MDc3Ng0KNTBhOTNmMDkwZTAx MDgwMTA3MDMwNDAxMDEwMTAyMDEwMTA4MDUwNDA5MDIwMjAyMDIwMjAyMDIwMjAyMDYwNzAxMDEw MTAxMDEwNzA5MDEwMTAxMDgwOTA2MDYwMjA3MDEwMjBiMDEwZTQyMjAxOTY5NmE4MzA2OGY3Y2Mx ZTUNCmQ2ZDdhMmFjNTkxYmNjYThiOTVhMDMwMTAxMGEwODBjMDUwMTAxMGMwZTAxMDI0NmNhNjg5 YjY3MDEwZDAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowNDAxMTE1ZTgwNDQwMTAxMDEwODA1MDcwMTAxMDIwMjAyMDIw MjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxODAwMTAxMDEwMTAxMDEwMTAxMDEwOTAxMDEwNzAzMDgwMTU5YzA5MmMyNjMw NDA3MDUwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwNTVhZDI3MmU0 NjYwMTAyMDQwODAxMDcwOTM1ZTM4NmRiOGY2NzAxMDEwMjA1MGIyNDBkMDkwNzAxMDEwMTA3MGQw YzA0MDIwMjAyMDIwMjAyMDIwMjAyMDIwZDA1MDQ2NjBlMDcwNDAyMDcwMjA3MjQyNDA2MDIwMTA5 DQowYTAzMDEwMTA5OTA0ZWUyMWY3MzQxMDExMTk2MjA5OTIzODQ1ZDJjZDNlMjIwMzcwMTAxYjAx MTAxMDUwMTAyMDcwMjAzNjYwYzAxMGIwZTQ3ODYzMGMwYWEwMTAyMDIwMjAyMDIwMjAyMDIwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTBlMDEwYjA1MGEz MjllNDAwYjAzMDMwYTA0MDIwMTA5MDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxODAwMTAxMDEwMTAxMDEw MTAxMDEwMTA2MDMwMTAxMDgwMjAxNGMNCjk3MjAyMTBlMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDYwNTA5MzUzNTAxNzdhOTQ5ODMwMTAxMDQwNzAxMDcwMTA4NjcxYmE5OWQw ZjA2MGQwNzAxMDEwMjA4MDgwNzA5MDgwMTAxMDgwOTA4MDEwMjAyMDIwMjAyMDIwMjAyMDEwOQ0K MDEwMTBjMDkwMTBiMDEwNTA3MDEwOTA3MDEwODZmMDEwODRiMDYwMjAzMDEwMTc4MWQyZjlkMDFi MDAxN2U5YzAxMjM3NmNhNmEyMDhjZTAyMzAxMGEwZTAxMDkwNDA3MDEwMTAxMDEwOTBjMDEwMTA4 OTM3YTlmODUwYzAyMDINCjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTRjMDEwYTA1MDExYTNjOGUwNjAyMDEwMTAxMDEwNzM1MDIwMjAy MDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxODAwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMjQwMTYz NmI4YzM3MDgzNTA3MDgwNzA1MDkwODA2MGEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwOTA3MDUwNDAxYWE3 NTc1MDEwNDA1MDExMTA5MDIwYTAxNjdkOWFjNjQwMjBhMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTRiMzQ5MzI1NGIwNjA1MDcwMjA2MGEwYjEzMzg4YjgxZDM1YTAx MDkwNDAyMDEwMTAxDQowMTAxMDEwMTAxMDEwNDBkMDEwMTkzMmIxZjYyMDEwMzBkMDEwMTA4MDQw NzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDcwMjAx NGMxYzNjYTkwNTA3MDIwMTAyMDgwODAyMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDE4MDAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNDRhNWJlMjZiYzkwMTA1MDMwNzAxMDkzNTBhMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwODAxMDIwNzAxMzY1NWUwNWEwYzA0MDEwYzAxMDEwODAxDQowNjM0 NTcyNDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA1MzU1OTBi MDIwMTA2MDEwMQ0KMDEwODAxMDRiZDVjNzJjMjM0MTEwYTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTA2MDMwMTI0NDIxODZhYWM1ODAxMDk4MzA5MDEwNjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDcNCjAyMDE0YjFhOTg3NDA1MDcwMjAxMDIwODA4MDIw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEy NDAzMDJhNDFlNTM0ZDA4MDYwNTA2MDYwNTA0MDUwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNg0KMDIwMjA5 MDE1OWIyMmExMzBjMDkwMTA0MDEwOTA2MDgwMTAxMDgwNjA3MDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTA2MDIwMTAxMDEwMTA4MDQwODAxMDgwZDA4MDEwNzZmNjQ2 NjA4MDIwMTAxMDc0YzAxMDEwMTAxMDEwMTAxMDEwMTAxMDYwNjAxMDU3ODNkODhhMzA2MDE0YjA0 MDEwNzAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDgw NzAxMDEwZWU1ZDQ2YjA1MDcwMjAxMDIwODA4MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDkwMg0KMDEwMTgzYzI1MDJiODQ0YjAxMDQwYzAx MDExMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwODAzMDgwMjA2MDEwYzkzNGZkYTBkMDEwNjA2MDEwYjA0MGIw MzAxMDEwYTBjMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA2MDIw MTA4MDQwZDA0MDYwMjAxMDYzNTBlMDEwMTA3MDEwMTAxMDYwMjAxMDIxMTAxMDEwMTAxMDEwMTAx MDEwYTAxMDEwNDBhMDEwZmFiMmY1Mg0KYjEwZjAxMDYzNTA4MDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDkwODAxMDEwNDhkZDQxOTA1MDcwMjAxMDIwODA4 MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMDAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEyNDAxMDEwZDAxNGFhYzFiN2E0ZTBlMDEwNjAzMDcwODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA1MDEw MTA5MDEwMWIwM2ZhZTEyMDEwMzA4MDIwYzAxMDkwOTAyMDIwOTAyMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA4MGQwYzA1MDEwMTAxMDEwOTA3MDEwMTA3 MGIwYTBiMGUwMzAxMDEwMjAxMDENCjAxMDEwMTAxMDEwMTBhMDYwMTA3NTkwNTAxMGQ5YzIwNjlk OTBhMDEwYzA5MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDkwMjAxMDEwODk0YTE3MzA1MDcwMjAxMDIwODA4MDIwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAy MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNDAxMDUwZDAxMDc3NmM2MmY4NmEzMGYw MTA5MGQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAzMDEwMTAzMDgwMTM1NjJkNzZlMDIwZDAxMDEwODA4 MDENCjAyMDcwODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAy MDIwMTAxMDgwNDA1MDgwNDA2DQowODAxMDEwMTAxMDkwODAxMDEwMjA2MDQwNjA3MDEwMTAxMDEw MTAxMDEwMTAxMDMwNDAyMDUwZDA2MDk1OWQ1ODczYmFiMzUwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDcwMQ0KMDIwMjAxZTE5OTNkMDUwNzAyMDEw MjA4MDgwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAwMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTA1MDkwMTA2MDUwNTBjMjE5MjFiOWM4MzA3MDMwNzAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNzBj DQowODAxMjQwZDAxMDM1NWJiMTQwNzAzMDEwNzAxMDQwNjA5MDkwNzA4MDkwNDAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDcwNDA0MDIwMTA3MDUwNjBjMGEwNDA4MDEw ODA3MDIwZDA0MDkwODA2MDQwNTAyMDEwMTAxMDEwMTAxMDEwMTAxMDkwYzA1MDEwNzI0MjQwMmIw MTVlNWEyZDIwZjAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMjAxMDgwNzAxNTQ4NzNkMDUwNzAyMDEwMjA4MDgwMjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA2DQowMTAxMGEwMjAxMGMwMWE1 NWU1MmM2MTIwNTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDMwMTAxMjQwZDAxMDJjMzdhNDIwMjA0MDIw ZDAxMDIwNzA3MDEwMTAyMDcwODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMzBjMDYwMTAyMDcwODAxMDEwMTAxMDcwNTA4MDEwMjA5MDkwMTAxMDIwMjAxMDEwMTAx MDEwMTAxMDEwMTBlMDEwNzBlMDgwODBkMDgwZjAxDQo0YzZjNWUxOWM5MDUwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDgwNjAxOWQzMTZhMDUwNzAy MDEwMjA4MDgwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwYTRjMzdlNTg2YjkwMTAxMDEwYzBlMDgwMTBkMGEw MjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAyMDIwMjAyMDIwMjAyMDIzNjgyOGE1ODAxMGMwZDA2MDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIw MjAxMGIwYzBkMzc4MDFlYmQwNTAxMDEwMTAyMDcwOTA2MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwOTAxMDkwYTAxNGUyYzlhMDEwMjBlMDcwMTA0MDEwNTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEy NDA2OTBkMTE4MTc0ODY2ODMwMTAxMDUwYzAxMDEwNzAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIyNDc4NTQ2ZTAx MDUwMTA3MDIwMg0KMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjBkMDUwMTAxNGQ1ZDIwMmI4NDBlMDEwNTBl MDEwMTA2MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwOTAxDQowMjA0MDFhNDVmMTkw YTA4MGEwNzAxMDQwMTA2MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDAwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNDA3MDE2NjIxZGI1M2M1MGMyNA0KMGEwMTAx MDEwMjA5MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAyMDINCjAyMDIwMjAyMDIwMjBlNGQ3NGFiMDUwZTAxMGIwMjAyMDIwMjAyMDIwMjAyMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAy MDIwMjY2MDEwMTAxMDNjODRmZGU2MWJmMDIwODM1MDcwMTA3MDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTA4MDEwMTA2MDEyMjMxM2RiMDA2MDUwODAxMDUwMjA2MDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMzcwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMGUwNDAxMTJkOTUxMjBiMjY3MDEwMTBhMDQwODA2MDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjI0NjY3 YjI5MDMzNTAxMjQwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjBjMDENCjAxMGIwMTAxZGE5YjNjODVj NDA4MDEwMzAzMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMTA2MDE3ZTFl YTE0NjBkMDIwODAxMDYwMjA5MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMGQyNDA1MDEwZjIxNzI3ZDcwMDEw YTY1MDMwMTA1MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjBhMDgxN2I4MDYwNTAxMDIwMjAyMDIwMjAyMDIwMjAy MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMjAyMDIw MjAyMDIwMjAyMDIwMTA3MGMwNTAxMGM5MWEyMWM1ZGM0MDEwMTBkMDIwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDYwMTA1MDk4NDYwY2UzNzExMDEwNzAxMDkwMjA3MDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTI0MDEwMTRjMjQwMTZmYTQxYjUxNzE1ODAxMDEwZDA3MDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjBi MDVjMGUwYjAwNjA1MDEwMjAyDQowMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDEwNjAxMDEwYzBiMDIwMWMz Y2E3ZDM4Y2QwMTAxMDcwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDMNCjAxMDQw OTY1OWI4YmQzODMwMTA2MDIwNzAyMDgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMDAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTI0MDEwMTM1NjYwMjAxMGI0Njlh DQo5OWFlMDYwMzBmMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDIwMg0KMDIwMjAyMDIwMjAyMGIwYzI3ZTFkNjA2MzUwNzAyMDIwMjAyMDIw MjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAy MDIwMjAyMDIwMjAyMDgwYzAxMDEwYTBlMDgwMjAxMjIyYjFlNmM2MzAxMDIwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwYTAxMDYwMTM1NjIzYzVkOTAwMTA0MDgwODAyMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDE1ZjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDIwYjExMDUwMTAxMDkwZDBjZGE0ZjFhNjI1ODAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIw MjAyMDEwOGIzNWRkMjAxMGEwMTAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDgyNA0KMDUwMTAzMDIw MTBhMDEwODQzMzIyY2EzMGEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwYzAx MDcwMTAyYjE4N2NhY2QwMTBkMDcwODAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTI0MDEyM2I1MzA2Mjc2NGI1YTAxMDEwZTExMDEwMTBjMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDcwNTBkYTkxNTRiMDEwZTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDE0YjBjYjk3MjFhMjIwODA3MDIwMjA1 MGMwZDA3MDEwMTAxMDEwMTAxMDEwMTAxMDYwMTA0MDIwMTA4NDk5OTMwNDYwMTY2MDEwNDAxMDQw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAwMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxNGIwYTRiYzI4ODNhNDcwMTI0NGMwMTAx MDcwNDAxMDIwMg0KMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDcwNDBhZDM2MjY1MDIyNDAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDIwYTA5MGViYTIwOTQ3NzA3MDQwOTAxMDEwMzA0MDEwMTAxMDEwMTAxMDEwMTAxMDYw MQ0KMDQwMjAxMDJiNDMyMmMxNDAyMTEwMjAzMDEwNzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTE2MDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMTENCjA0MDEyMzZjZGI5YWRhNWEwMTA1MGIwMTAxMDkwMjAyMDIwMjAyMDIwMjAyMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTA3MDk1YjVkNDYwNDA1MDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMGQwMTA4MDEwYjNmN2Q4YWIwMGMN CjAxMDEwNjA0MDkwODAxMDEwMTAxMDEwMTAxMDEwOTAxMDQwMjAxMDIxM2U1OWUzMzA5MGEwODAz MDgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDkwMTM1NmYwODAxN2UyYjE5NDQw NDAxMGEwNTAyMDMwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAyMDJhYWE2NDMzNTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwYTAxMDYwYTAxNjRlMmQ0ZDk2NTAxMDk1OTA0MDEwNTAxMDEwMTAxMDEwMTAx MDEwOTAxMDQwMTAyMDEyMzc0ZDRkMzA5MDgwMjA0MDQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA5 MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwODA1MDYwMTAxNjZjNzliNTI5ZDVhMDExMTRhMDEwMjAyMDIwMjAyMDIwMjAy MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNjA5MDcyNDVkYzI5MDAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA5MDgwYjBhMDFjODcz NmExNTRjMDEwMzA1MDIwOTAxMDEwMTAxMDEwMTAxMDEwNzAxMDQwMTA4MDE1OWUzMmUzZjA1MDEw MjA5MGIwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDAwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDcwMTAxMDEwYzExMGQwMTYz ZTE4YzNmNTcwNDAyMDEwMjAyDQowMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwNjAyMDEwOTQwOWQ2NDAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTY2MDEwMTY2MDgwOTViODg1MWQyMGUwMTA5MGMwMTAxMDEwMTAxMDEw MTAxMDEwNzAxDQowNDAxMDcwMTAzMzMyYzUzMTEwMTA4MDEzNTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDMwMQ0KMDE0YjBiMDEwMTY2MDEyNTYyMWQ5YjI2MGEwYjAyMDIwMjAyMDIw MjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTA3MDEwMTA4Yjlj ZjkzMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjBkMDEwMTA1MGIw OTAxNzk1Mg0KNTE0ODA1MDcwYzAxMDEwMTAxMDEwMTAxMDEwMTA3MDEwNDAxMDkwMTAxNWI3ZDFl NjcwOTA2MDEzNTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDAwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA0MDYwMTAxMDUw NTAxODMwMTExZDEzYTlhNDEwMzAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTA2MDEwMTBkNjQxN2I5MGEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTY2MDEwYzM2MDEwMTRiMDEwYjNmZDRhODRkMDcwNzA5MDEwMTAx MDEwMTAxMDEwMTA4MDEwNDAxMDYwMTAxYjk5OTY5OTEwYzAzMDEzNTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDIwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwYTAxMDk0MzcyMWU1NDVhMGYwYzAx MDEwOTAzMDcwOTA2MDcwMTAxMDIwOTA5MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDMwMTA0 ZTQ3OTE2NGMwODAxMDEwNzA3MDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTEzYWZhZDlhNmUwMTI0MDkwMTAxMDYwMzA5MDEwMTAxMDEwMTAyMDIwODA3MDcz MTJmNDcwMTAxNjUwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMDAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwOTAxMDE4M2M2ZTE1MjhhMjUNCjAxMDU0YTA3MDEwMjA4MDYwMzBhMGMwMzA4MDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA5NGIwMTAxMzUyMjU1MDIwOTAxDQowMTA3MDcwMTAxMDIw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxYjMxNzNhZDkxMjA3MDUw YTBjMDUwMTAxMDEwODAxMDENCjAxMDIwMjA4MDcwNzdiYWQxNTA3MDE4MzAxMDgwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwODAxMDUwYzAxMDI0NjlkODkx NzZkMTIwNzA3MDQwMzAxMDEwMTA3MDYwOTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw ZTAxMDEwOGJkMTUzNDA0MDgwMTA4MDcwMjAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMzAxDQowMjIyY2ExYmMyMzUwMTAzMGUwNDAxMDEwODA5MDEwMTAxMDIwMjA4 MDcwNzc5ODA2MTA5MGMwZDAxMDkwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMDAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwYzAxMDE2NjBiMDEwMTZmOWQxYTczOGUzNjAxMDEwNzBhMDkwMTAxMDEwMTAy MDQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNDAxMDEwOTQ1NmM1NTBhMDkwMTAyMDcwMjAx MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA2MGEwOTBkNDE4OTFj NzAwNzAxMDEwNjAzMDkwNzA2MDEwMTAxMDIwMjA4MDgwODQxMmVlNTA1NjYwODAxMDkwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMjAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwYTAxMDEwMTBhMDMwMTAx NGNhNzRmMzBlMTEzMDEwMTBjMDQwNTA1MDcwMTAyMDMwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMzAxMDgwMWM3YWNiYTI0MDUwMTAyMDcwODAyMDgwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDMwNjAxNjY3OTFiNTE5MzI0MDEwMTBjMDUwMjA1MDEwMTAyMDIw MjAyMDgwODcwNjk3MzBmMTEwNzA5MDcwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAwMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTA5MDUwMTAxMDMwYTA2MDEwOA0KMzQ3MWEyOGQxNWM3MDEwMTAxMDUw YTA5MDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNjAxMDQwMTkwYjExNTY2MDMNCjAxMDEw NzA4MDIwODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA0MDEwMTAzMDI2 ZjE2YmNkMGE3MDMwMTA5MDcwMjA1MDIwMg0KMDIwMjAyMDIwMjAyOGY2YTg3YmQwNDA2MGMwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDQyNDBjMDgw MTA4MDQwMzM1MDgwNGM2ZGIxY2FmOTMxMjAxMDEwOTA5MDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwZTAxNmY0MGQzMGYwZDAxMDEwNzA3MDgwODAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTBiMDENCjAyMTEwNjAxYTczYTFmNmM1NzA3MDEwOTA1MDkwMjAy MDIwMjAyMDIwMjAyNmUzYTgwMjgwMTA2MGIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMWExMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTM1MDIwMTA0MDQwMTAxMGQwODAyMDkwZDBmYzM4MjJmMThiYTM2 MDEwMTA5MDUwMzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA3MDIwYjAxMDM3ODI4ODMwYTAx MDEwNzA3MDgwODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEzNTAz MDEwMTA4YjA3MDhjYTg2ZDBiMDEwZDBlMDgwMjAyMDIwMjAyMDIwMjAyYzc5MjY4NjEwMTA4MGMw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwNzA4MDUwNTAxMDViMzIxNmEzMmUxYzQwOTExNTkwMTAxMDkNCjBkMDMwMjAxMDEw MjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwODA3MDEwNDM1NGI4ZjE3YzgwMTBmMTEwMTBkMDEwNjAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDgwMjAxMDEwMTAyMDcwOTVjMmM4NjU3MDkwMjAxMDQw MjA4MDgwNzA3MDcwODA4MDFhZWExNzRjZDBiMDEwYzAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDAw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMjA1MDEwMTBlMzRj NmRkODk3Mzc5MjUwNDAzMDUwMjAxMDEwMjA0MGQwYTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwOTA5MDEwMTAxMDExMGM1OTMw MQ0KMDgwOTAxMGMwMTA1MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDgw MjAxMDEwMTAyMDcwOTc2ODIxZGI4MjMwZDBiMDEwMTAyDQowMjA4MDgwODA4MDgwMWM2MmQ4ZDc2 MGQwMTA1MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTA2MDEwMTAzMDYwMTAxMDIwNmIzOTc2YTMyODJiMzAxMDkwMTAxMDIwMzBh MDYwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTA4MDYwMTAyMDgwMTU5YzljMjY1ODM2NjAzMGMwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDgwMg0KMDEwMTAxMDIwNzA5MDEzNDZiMmVkOTVh MGIwMTAxMDEwMTAyMDIwODA4MDgwMTQ1OTk3M2MzMDkwMzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx NWMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTBjMDEwMTA5MDMwNzAx MDkwMTAyMjQ0NTVkM2RlMTkzMDEwYTU5MTEwMjAxMDIwYzAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDkwODA0MGUwNjEy NzAxNDRiMDEwMTA3MDUwNzBkMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwODAyMDEwMTAxMDIwNzA5MjQwMWQyOTU3MzhmMDcwNzAxMDEwMTAxMDEwMjA4MDgwMmNkMzA5 OWM2MDE0YzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMzcwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTA0MDEwMTAxMDcwODA5MGQwMTA1MDEwMTEzYjg4ZDhkMjE0NQ0KMGMw MTA4MzUwZTA3MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDkwMTA4MDMwMTA5MzQ2ZDRkMDYwMTA1MDEwODBkMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwODAyMDEwMTAxMDIwNzA5ODMwMTU5ZDc5 NTJhYWEwYTA4MDgwMjAxMDEwMjAyMDgwNjM1OGQyZTcxMDExMjAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDFlNDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA3MDENCjAxMDkw NzAxMDEwMjA5MDIwNDBlMDQ1OTI3YmI2OTVkOGYwZTAxMDcwODAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDQwMjAxMDUw MTAxMGZhMzk2DQo2NTM1MzUwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwODAyMDEwMTAxMDIwNzA5MDExMjAxNTg1MDgwN2Y2MzA1MDYNCjA3MDIwMTAxMDIwODA1 MDdkNzJjYjUwMTU5MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwOTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDkwNzA5MDQwNTA4MDEwMTA2MDEwMTBjMDYwMTI0ODQ5ZDk0 MmI1Y2M3MDEwMTBmMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwNDAxMDEwYTA3MDE1OTEyYzgwMTAxMDkwMTBlMGUwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwODAyDQowMTAxMDEwMjA3MDkwMTRj MDcwMTQ3OWE5YTdmMGEwMzA2MDgwMTAxMDIwMjA3MDE3ZjMwM2EwMTBjMDIwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDkwMTAx MDIwOTA5MDcwNzAxMGU0YjAyMDEwMzBhMDEyNDQ3ZTE1MmUyNTVjZDA4MDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwOTAx MDEwNjAxMDEwYmIzYWI2ZjA4MjQwMTAzMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTA4MDIwMTAxMDEwMjA3MDkwNTAxMGQwMjAyMzMzMDdjMGIwYTA1MDcwMjAxMDIw MjAxMDFhMzFkODkwMTA5MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMDAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTA4DQo0YWQyMTk4MGFmMTAwMTRiNWEwNjAxMDgwZDA0MDEwMTAxMDEwMjAyMDgwNzAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA0YTk0YzA0MDkwMTBkMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw NzAxMDgwODAxMTBkMzg4YTkwNjA0YjAwMTA4MGYwMTA1MDE4ZjdjOWUxMzBiMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTM1MDcwMTRiNGUzOTMxMjBkOTZmMDEwNzgz MDcwMTAyMGEwZDAzMDQwNTA3MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTM2ZGQNCmJmNGIyNDA5MGIwNjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDgwOTAxMGU0ODJhMTkyOA0KMDQwYTY2 MDEzNTAxMDcwODM0YTIzY2JmMDkwOTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMWU0MDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTA4MDcwMTAxMGVkNjYxMmYzMGRkNTY0YjAxMDYwZDA0MDgwMTAxMDIwNzA5MDkwODAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMGZiMTMzMGEwNjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwOTA0MDEwMTkwNDcxZTk5MjMwMTY3MDEwMzAxMDEwNjBjZTI4OGEzMDEwZDAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDY0YjI0MDEwMmNkMTRhNjhjOGNk MzY3MDEwODA5MDgwMg0KMDEwMTAxMDIwOTA0MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMGU4ZjYyNGIwNjA1MDgwODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA4MDIwNjBkMDgwMTA4NGNkMGRmYTUx MjM1MDEwYTA5MDEwZDAxOGEyZTg1MDEwMzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAwMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTBkMDYNCjA1MGQwNzAxMDkwZjEzYmE5YTk4MzliNDAxMDEwMzBhMGMwZDA5MDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDhiMDlkYWEw NjA0MDkwOTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTA2MDgwNzA2MDcwMTAxMDJiZjUxMmM5NjA5MDcwYjA3MDEwYTAxYzI4MGRiMTEwODAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMGIwMTAxMDcwZTBhMDYwNTAx MGE0OTg1MzFkYjE1NzcwMTAxMDEwMjA2MDYwODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwZA0KMjhkNjA2MDIwODAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA4MDEwMTAxMDEwMTAxMDEyNDM3 DQo4MDdhYzcwZTA2MDEwNTA2MDY0ODNkN2RiNDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDcwMTAxMDMwZTA0MDEwMTAyMGQwNzExYWIxOTFjNTQ0ZDEyMDEwMTAyMGMw YTA5MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwYjBl YWJkNTY2MDUwYjA0MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMjAyMDEwMTA4MDcwMjA4OTBkNTMwOGEzNjA3MDEyNDAxNGIzNGEyOWVk MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMGMwZDA0MDgwMTAxMDMw ZjAzMDEwMTAxMjRjOGQwOTk5YmM1DQo3NzA5MDcwYzAzMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNjA3N2VlMDBlMDEwNjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNzA2MDcwODA5MDkw MjBjMGQ1YThjYTAxMzBiMTEwZjAxODMxMTliZDQ5ZDAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDAw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMjA0MDQwMTAyY2QxNDUzMWMyYmQy MTAwMzA1MDEwNzA0MDkwMTAxMGQwMzAxMDEwMTAxMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw ODA3MGY0MDM3MDEwMTA0MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxYjAwOWI0ODczMGMzMDQwOTAxMDEwNmRk YWRhODA1MDEwMg0KMDIwMTAyMDcwODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDgwMTA3MDYwMTAxMjRhYWM3OGE1ZjNlYmE2MzI0MDUwMTA2MjQyNDA2MDEwNzBlMDEw MTAxMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEyNDAxDQowMWJhNzU0YTA1MDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTA2MGQNCjA4OTA1NDg4NzRhYTA1MDEwYzAxMzdhZDhkMTAwOTA5MDcwMjAxMDEwMjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDYwMTAxMDkwNjAxMDEwNzM1MjNh NzZjMWQzZGMwNjUwYzAxMDEyNDRjMDMwMTAxMDEwMQ0KMDEwMjAyMDgwODA4MDEwMTAxMDEwMTAx MDEwMTBiMDEwMTQ0YTUzNDA2MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMGEwMTAzMDUyNTE5OWY5NjBjMDE2 NjAxMjVhMTNiNDUwNTA2MDkwODAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDYwMTAxMDkwNDA3MDEwMTAxMDENCjA0NzZhYzNlMjAzYTE1YjMwMTAxMDYzNTBk MDEwMjAyMDIwMjAyMDgwNzA3MDEwMTAxMDEwMTAxMDEwMTAxMDIwZjRlZDk2MzAxMGIwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDQwMTExMDgwMWFiMzE4ZDEzMDEwYTA0NmY5NTJmNTUwNzAyMDgwNzA4MDEwMTA3 MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDE3MjAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwNjAyMDEwODA5MDcwODA3 MDEwZTI0MDIwODU3NjIxYzdjZTIzNzEwMDEwMTA0MGIwOTA3MDgwMjAyMDgwNzA5MDEwMTAxMDEw MTAxMDEwMTAxMDkwZjI2MjE0NTAxMGIwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDYwMjAzMGEwMTExYWMzY2Uw MjMwODA0NWEyZmFkZTAwODAxDQowMTA3MDYwODAyMDkwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwNzA3MDgwMTAxMDEwODA2NGIwNTAxMDEwNzRiNTgzNDk3ZTU4OTc0ZGEw YzAxMDEwNDA1MDkwODAyMDIwODA3MDEwMTAxMDEwMTAxMDEwMTA0MDcNCjAxODM5Y2QxMDQwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDMwNw0KMDEwZTEyMDE1NzFmODBhYzBmMDEwY2NmNWU5MjI0MDgwMTA3MDQw OTA4MDkwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA4MDkwODAxMDEw MjAyMDEwMTI0NGMwNDAxMDEwNjEyYWI1MTMxY2E5NjkxMGYwYTAzDQowNjA4MDIwMTAyMDgwMTAx MDEwMTAxMDEwMTAxMDQwZDAxMDFkMmFjMGQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNTA4MDEwMzY2MDEx MjIxYTEzYmQ2MDEwNDZkOTg3Mzc3MzUwMTAyMDUwOTAyMDcwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDYwNTA1MDUwODAxNGMwMg0KMDEwMTA1MDcwMjA5MDEwM2Iz OWQxYzNiZGRiMTBiMGEwNTA3MDIwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDE1OTU5MDE0Nzk2MDkw ZDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAyMDMwODAxMDc1YTBmNjA5ZjcxMGUyNDRkOGI4OTQ2MzYwODAx MDkwODAxMDgwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAwMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNzA4MDEwYzdlMTc4ODE3NzAwYzAxMDMwNjAxMDEw MTAyMDkwNDA0MDQwNjA5MDUwMTA1MDEwYTZjYzgwMTAxMDgwODAxMDEwNDA0MDcwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAy MDIwMjAyOGY1MTlmYmY2NzQ1YTk4MDYyMGENCjA5MDIwMTBjMDEwMzAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIw NjA3MDEwMWIwNDJlMzg5MWRlMzU4MDEwZTExMDEwYjA5MDEwMTA1MGEwNTAxMDkwMQ0KMDkwNzRj NzliMTY1MDkwNDA2MDEwMTA5MDUwNzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyDQowMjAyMDIwMjAyMDIwNGJhY2UzOTQ3MTA3OWI3NGYz NjA5MDgwMTBhMDEwZDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwOTA5MDEwMTAyNGI1ODRlZTENCjMyZGJkMjBi MDExMTAxMDQzNTBjMDEwMTAxMDUwZTAxMDkwMTBhYjk2MjEzMDQwZDAzMDgwMTA4MDkwNzAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIw MjAyMDIwMjAyMDIwODI0YmI4OGUyNDUzMzJjNzI4NDA3MDgwNjA0MDEwZDAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTA4MDkwNzAxMDEwMTAxMGQwZGJmMTg4OTliYzk5MTAxMDEwMjA3MDkwNjA5MDcyNDAxMDkw MTA3NGJjMGU0MDcwOTA2MDcwODA4MDgwODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDI0YzAxNmQ1Mjk5NmMyN2Ey YWQ0MzA5MDEwZDA3MDEwNDAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNzA4MDIwODA5MDkwNzA4MDkwODAxMTEz MzFkOGM2YmM5MjUwMTAxMDQ1YTI0MDEwMjAxMDgwOTAzMDY3MWIyMDEwMTAxMDgwOTA3MDIwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAy MDIwMjAyMDIwMjAyMDIwMTBmYzcyODgwNzI1NTZiMmVhNQ0KMGIwMTBkMDEwMTA2MDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwYjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwNDA5MDIwMTAxMDgwOTA2MDExMTEyMDYwMTEzNTQ1ZjE4ODVjNWU0MDkwMTAxMjQwMTAx DQowMjAyMDIwMTdlYzYwMzAxMDEwMTA2MDkwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDINCjAyMDIwMjAyMDIwMjAxNWEwMWM3NTJi Y2UwNGY1ZTRmNjcwMTA0MDEwODA4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwODA3MDgwMTAxMDEwMTA3NGIwMQ0K MDEwZjZmMDQ2NjkzMjhiNTUxY2ZiZjBkMDc0YzA2MDMwMTAxMDEwNDY2MjFiMDBiMDEwMTA2MDYw MjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDIwMjAyMDIwMjAyMDIwMjA0MDgwMTBhNDEyZGU1Y2E4YzE5YzgwMTA2MDEwZDAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwNjA2MDIwMTAxMDcwMjRjNjYwMTAxMDQwYTAxMDVjNDhlNmI4ZGQzNTcw MTAxMDQwMTAxMDgzNDVhOWJlNDEyMDgwMTA5MDYwODAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjA0MDE2NjRh MDE5ZDg5M2M4OThjMTQwNzA2MDEyNDAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MjAyMDIwMjAyMDIwMjAyMGEwMTBhNzBhODdjYTZiMTIyNWEwMTAxMDIwMTRhYjI3ODAxMDFiMDAx MDE2ZjAxMDIwMg0KMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA3MDIwMTAxMGNjM2E2YmU4ODJjDQpjNTAxMDE1OTA2MDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTBiMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDkwMTAxMGVlNDMz NWQzZTg2ZDINCjZmMGU2NjM1NGMyM2E2NjUwMTBlMDkwNzBiMDEwMjAyMDIwMjAyMDIwMjAyMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDkw MTAyMDUwNDIzYWMzMDVlMmQ1NDM2MDEwMTAxMGQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMjAyDQowMjAyMDIwMjAyMDIwMTA1MGQwMTAxNjZkYWMyOGMzYTM4MTQyNDAxMDMzNDJiNTYw MTAxMDYwMTAyMGEwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDkwMTA3MGIwMjA4Yzg2YzVlOGI4NmJmMDUwMTAx MGMwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjA2MGQw MzA3MDEwMTAyYjRiODFmMzAzZmIyOTAwYWEzNDE2MzAxMDgwMTAxNTkwMjAyMDIwMjAyMDIwMjAy MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDgwMjA0MGIwMTAxNTk0OTFjOGIzZDU1MGYwYTAzMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMzAxMDEwMTAxMDkwODAxMDE0YzU2Y2YzZDdkMmE0ZTZk MTZjNjA5MDEwNTAxMDIwMjAyDQowMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNTBhMDQwMjAyMGQxMTcxODkNCmNlOGFi MDAzMGIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMTAy MDcwMjAxMDEwNDM1MGYwOQ0KMDEwZTViOWJhZDlmNzQxZDVjMGEwMTBiMDkwMTAyMDIwMjAyMDIw MjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTA0MGQwNzA5MGMwZDAxYjBkN2JjMTk2ZTAxMDYwZDAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAyMDINCjAyMDIwMjAyMDIwMjAxMDkzNTExMDQwMTAxMDEwMTBkNWE1OTM1YWFi YTJhYTI4NzdiNWIxMDM1MDMwNTAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjA3MDcwODA2MGQwNTAxMDE0OTE5 ZDRhYzBkMDEwYjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDAwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIw MjBkMDIwMTAxMDcwNDA3MDExMTA5MDEwOTAyMDEwNjgzZDk4Njg4M2FhYjU5MDEwZDAyMDIwMjAy MDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwOTAxMDEwOTA2MDIwODA1MGQwNjc5ZGMzZTc2MDEwMjAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAy MDIwMjAyMDUyMjM4M2Q4N2RiODJjZDA1MDENCjAxMGUwYzAxMDEwNTA4MDcwNjA3MDIwMTA4MDkw MjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDcx MQ0KYTdlNmFkYWM1NzAxMDIwNzA4MDEwMTA4MDkwNzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyDQowMjAyMDIwMjAyMDIwMTkwMjY2MjcxMmE4NzE5NzU2 ZTAxMDEwNjM1MDMwMTAyMDEwMTA5MDQwMzA2MDIwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjA1Njc5YWNlMWJhYjAxMDEwMjA3MDgwMjA4 MDgwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIw MjAyMDIwMjAyMDIwODRiYjM4MmRhNDRlMmEyMTkxOGQ5MzQwMjAxMDgwYTA5MDcwMjAxMDIwODA2 MDQwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAy MDIwMTA3MDY0MzlmY2MxODZmMDEwMTAyMDYwOTA4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMTA0NDYyYmI0MGMxMjY3 ZTNhMjMxMmE1YjM2MDkwMTAxMDkwYTBkMDcwMTAyMDUwMjAyDQowMjAyMDIwMjAyMDIwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMTAzMDk1OTNhY2U4Y2UzMDkwMTAxMDcw NTA4MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAy MDIwMjAyMDIwMjAyMDIwNTAxNzc1ZGRhMDIwMTA3MGZkYQ0KYjg3YTYwMTdiMjA1MDcwOTA1MDMw MzA1MDIwMTAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIw MjAyMDIwNTA5DQowOTAyZTE2OTNjN2M3NzBlMDEwMTA2MDgwMTAyMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMWQzMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDINCjAyMDIwMjAyMDIwMjBiMDE0YTc1NzU2 ZjRjMTEwMjA3MGZhNzhhYTI3YjgyNDYyMzA2MDEwMTA4MDYwOTAyMDIwMjAyMDIwMjAyMDIwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjI0MDEwMTA3YTU1ZjJjMjBjNWU0 MDcwMTA5MDcwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDIwMjAyMDIwMjAyMDIwMjAxMDEwZTkzNjI4MzA1MDExMTA2MDEwOTZmZDY4YTFhODJhYzE0 MjMwNjAxMDcwYjAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAy MDIwMjAyMDIwMjBhMDEwODA3YjQxZDJmMWQ2MGJhNjYwMTA5MDkwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMWY3MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjA1MDgwNDBh OWQ1YTY2MDQwMTAxMDkwNDAxMDExMGIyZTUxZDUyNjI5MzA2MDEwNjAyMDINCjAyMDIwMjAyMDIw MjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAxMDc2NjAxMDEzOTJmODc4 YjE2NjcwMTA2MDYwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAyMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMGEzNTAxOWM3NTBkMGQwMTAxDQowMTAyMDIwODA4MDg1 YTdlY2YxZTJiNDEzNjA0MDcwMTA5MGY2NjAxMDEwNjA4MDcwNzAxMDEwMTAxMDIwMjAyMDIwMjAy MDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAyMDENCjBkMDMwMzhmMzk2ODY4MzA0ZTA4MGQwNDAxNjYwMjAyMDIwMjAy MDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw NDA2MDE4ZmEzMGMwMTAxMDEwMTAyMDIwODA4MDgwZjA3NTk0NDRmY2EzODhlNWEwNjAxMDEwMjA2 MGI0YzAxMDEwZDExMTEwYTAyMDEwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjA5MDUwNjIz YzA5ZTdjN2Q1MWE3MDEwNzExMDEwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwNTA4MDg0YWM2NTgwNzAxMDEwMjAyMDIwMjA4 MDgwMzAxMDE4M2MzYmE1NDZiNzU1YjY1MjQ0YzRhMGQwMTBiMDcwMTAxMDUwYTA2MDEwMjAyDQow MjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwNTAxMDIwNjAxZGEzMmRiNmFkZjUzOTAwMTgzMDEwMjAyMDIw MjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDYwODA1MDgwODhmYmYxMTAyMDIwMjAyMDIwMjAyMDIwMTBjNWEyNDAxMDFjNzk2NWRlNQ0KNTFk MTY2MDEwNzVhMDQwNDA2MDcwMTAxMDcwNjAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEyNDAxMDEw YjAxMTIxNzY5NmI3Mzg4NzkyNDAxMzUwMjAyDQowMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDkwMTBkMDEwMTYzNGVjZDAyMDINCjAyMDIw MjAyMDIwMjA4MDEwMTAyMDIwMTA0NGI4ZjhlN2E5MjE3Mjg0ZDAxMDEwNTRjMGYwYjA3MDEwMjAy MDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDE0Yw0KMDEwMTRjMDEwOTQzOGI1MDg1MWIxZGQ2MDEwYTAy MDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwNjAyMGEwOTA5NGMzN2M4MDgwODAyMDIwMjAyMDEwMTA1MDEwMTAxMGExMTBkMDEwMTA1 NjM5YzNlMWZkN2IyYmQxMDAxMDEwMTBjMDMwMTAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTEx MDgwMTRiMGQwMTEwMWQ2YTE3YTk2YTJhMzQwODAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDFjMDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNjM1MDc0YjAzMDQ1NmQ2MDgwODA4 MDIwMjAxMDEwMTA3MDQwNDA4MDEwMTA4MDkwMTA1MGEwMjAxOTFhOWRmNWRhZTc2MGQwNzAzMDMw OTAyMDINCjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwODA0MDkwMjA2MDQwNzAyNDE4NjFhZTEzOTZhODI2 NTAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTVhMDE4MzAyMDExM2E3MDgwODA4MDIwMjAxMDEwMTA4MDEwMTAxMDgwZDAzMDgw NDAxDQowMTBhMGUyNDc3ZDZiYjUyM2U2MjZlMDgwMTAzMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw NTAxMDYwNjAxMDEwNTAxMDEyMTMxODY5ZDIwMzFjOTAyMDINCjAyMDIwMjAyMDIwMjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA4MGQwZDAxMDE5MGRhMzYw MQ0KNTgwMTZmNTkwMTAyMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDJjOGFjNTI4NzUx N2Y0NTY3MDYwMTA4NjY0YjAxMDEwOTA4MDEwMTAxMDYwMzA0MDYwMjAyMDIwMjAyMDIwMjAyMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyDQowMjAyMDIwMjAyMDIwYzBhOGUxYWQ3 YTgzZDliNjM0YjAyMDEwNTA2MDIwMTAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA5MDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDIwNTA1MDEwMTRjZTQyMTBmMGMwNzAzMDEwODBkMDEwMTAxMDEwMTAx MDEwMTAyMDIwMjAyMDIwMjAyMDIwYzA0MzZjNmE4MzAzYjM5YTdjNzBhMDEwMTA3MGIwZjA5MDMw YzBhMDkwMTAxMDEwMjAyDQowMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAyMDIwMjAyMDIwMjAyMDIwMTAxNWJlNThkYTM3OTVlOGFiMzAxMDY2NjA4MDEwZTAyMDIw MjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTFhMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA4MDEwMjA4MDEwMTA0 MTI5YjQ1MDE0YTA5MDEwYzBiMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwNzAxMDEx MWJkMjg3NDlhNzNhOQ0KNDcxMjM1NGMwNTAxMDEwODA2MDcwMTA3MjQxMjAyMDIwMjAyMDIwMjAy MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwYTA3MDJk MjFjMTY3ODFjMmZjMjZmMDEwOTAyMDEwNzAyMDIwMjAyMDIwMjAyMDIwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAy MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTA5MDEwMTAyMDIwMTAyMDVkMzQxMDE1ODA0MDIwZDA4MDEwMTAxMDEw MTAxMDEwMTAyMDINCjAyMDIwMjAyMDIwMjAxMGU1YTA1MDEwMTY0NDQ2YzE5OTk3YjI3NjU2NjI0 MDYwNTA0MDYwODAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwZDM2MDEwMWUzYTI1NDhhMWIzZQ0KYzI4MzAxMDUwYTAx MDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMWEyMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA2MDEwMTA4MDYw OTAyMDFiZDI5DQo2ZjM1MDEwNDAyMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjA4 MDEwMTAxMDIwNjBkMGMwYmIyMTcxZDNkNTI5ZDQ4MDMwMjAxMDEwNDBhMDkwMTAyMDIwMjAyMDIw MjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDINCjAyMDIwMjAyMDIwMjAx MTAxMDAxNGMyMTRmZTE1NDFkMWFiYTM1MDIwNDAyMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDcwMjAxMDgwNjA2MDcwMTU4ZTJhYjA2MDEwYTAxMDYwMTAx MDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjM1MDcwMTAxMGI0YjA0MDEwOTAxMDQ4ZmUyNWU4 OTUzOWQ0MTY1MDIwMTAyMGU0YzAyMDINCjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjA5MDE2ZjRhMDEwZWFlODUzM2UxMTlhNmQ2MDEw MTBlMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDAwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjA4 MDIwMTAyMDgwMjBmZTFiYjBmMDEwZDAxMGUwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIw MjA4MDYwNTA4MDEwMTAzMzUwMTA1DQoxMTBjMDZhYThlMWZiNjJmNjE3ODY0MGIwMTAxMDIwMjAy MDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIw MjRhMDEwMTRjMDEwMWNkZGFhMzc5YTYyYjVjOTEwNTA1MDIwMjAyMDIwMjAyMDIwMjAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjA4MDEwMTAxMDEwMjA4NDAxZjY0MDMwNjAxMDYw MTAxMDEwMTAxMDEwMTAxMDIwMg0KMDIwMjAyMDIwMjAyMGEwNjAxMDEwMTAxMDIwODBjMDEwMTAy MDEwMTI0MzRjNWE5MjA1ZTUyYTU2ZTM1MDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjA3MzUwZDAxMDgwMTAxMDVkNWQwDQo3NDli NGZjMDQ2MDEwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDAwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMTINCjZjZDcxMjAxNGIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwYzExNGRhNTcyMmYzOThlY2Q0 YTI0MGQwZDBkMDkwMTAxMDkwOTAyMDIwNDBjMGMwMjAyDQowMjAyMDgwOTA2MDYwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAxOWM3MjUxMmI2Yjk2MDEwMTA2MTEwMTAxMGEwOTAyMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxNTcwMTg0YzBiOTAx MDc1OTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIw MjAyMDIwMjAyMDIwMTAxMDEwYWM3NTVlMjZhMWNhOQ0KNDgzNjA4MDEwNTBjMDEwZDU5MTEwOTAx MDEwMTBiMGEwMzA0MDUwOTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjA4NDZk Mzk0OTI4ZDRmMTY2NjA0NGMwYzAxMDQwNzA4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMDAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMGIwMTA1Y2QxMDAzMDgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDINCjAyMDIwMjAyMDIwMjA3MzU0YzA5MDEwMTY3 YjkyYTZhYTAxOWFiNTkwMjBjMDQwODAxMDEwMjA2MGEzNTAyMDEwMTAxMDgwNzA3MDgwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjBkMDU2NTc1M2E4YzE5YTgzNDAxMDcwYTAxMDEwNzA5 MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwZjBmMDcw NTBlMDMwOTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDIwMjAyMDIwMjAyMDIwMjAxMDIwOTA5MDgwMTAxMDE1OTkzYTU2MDVlMWVkMGQyYWEwZTAxMDc0 YzBmMDYwMTAxMDIwMjAxMDEwMTA3MDUwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAx MDENCjA4Yzc3OTFjMWZjYWEzMGQwMTAzMDEwMjA2MDcwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDQwNQ0KMDEwNDY2MDEwMTM1MDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjBkMDEwMTAxMDUx MTI0MDMwNjAxMDFjZDE1NTMzMDJmM2VhZmQ2NGMwMTAxMDEwMjA1MGMNCjI0MGIwNjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDEwMzBjMDc0YjViYmI5ZTk0NjQwNjBiMDcw NTA1MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA4 MDEwMTY2NTcyMzA5MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDIwMjAyMDIwMjAyMDIwMjBkMGIyNDBhMDgwMTAxMDEwZDU5DQo1YTA5MDEwZGE3YzAzMjY5 MWZkMDViMjUxMjExMDEwMTA4MDYwNjA5MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIw MjAyMzUwMTAxMDMwMTAxMjZlMThhNjUwMTA3MDEwNjA4MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTBhMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwOTEwMTAwMTM1NDQ0MTI0MDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMg0KMDIwMjAyMDIwMjAyMDEwMTA2 MDcwMTAxMGUzNjAxMDEwMTA0NTk1YTBhMDEyNWFjM2IzYzJjOGRjNTYzMzQxMjA5MDEwMjA0MDQw OTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyNjYwMTAxMGU0YjAxMDEwZTZlMDkwMTAx MDEwMjAxMGEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTQwMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw ZDAxMDkwYjAxMDEwZjA0MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDcwOTA1MDMwMzA3MDEwMTBjMjQwYjA3MDEwMTA1NjYw OTBlNWE4NGUwODBkZTIwNWQzM2M3MDUwMjA1MDkwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAy MDIwMjAyMDEzNQ0KNTkwMTAxMGQyNDA4MDcwMTBhMGIwNDA5MDI1OTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMWQ0MDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwYzYzYzYzODUwYTA1ZQ0KNTBkNWRh NjUyNDAyMDEyNDM1MDEwMTA5MDMwMTA0MDcwMjA4MDgwMTAxMDcwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTA1MDkwMTAxMDEwMjM1NmY1YjlkMWZkZmQ0NmI0NDkwMDQwMTAxMDIwNTA5MDEwMTA4MDEw NzBhMGQwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDcwNDA0MDkwMjA4MDcwOTEyNDU5 Y2E2MzE2OGRlZGQ0ODgzMGQwNDAxMDUxMjA5MDEwMTAxMDkwNzBhODMwMjAyMDIwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAyMDYwMzBhMGQwMzBkMGMwNDAxMDEwOTc3Mjc4MjdhZGU3MmQwN2Y3ODQ5YWExMDRj MDQNCjA3MDUwNzAxMDEwMjA4MDgwODAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxYjYwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA4MDgwMjAxMDEwMTAxMDEwMjA5 DQowMzBjMGMwYTBlMTFiMTliNWY5ZjJlOWFhY2JkMDcwMTA4MGQwYTA2MDkwMzA5MDcwNzA4MDIw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMjA5MDUwNDAzMDMwMzAxMDEwMTAxMDEwODM1MTAwMWM4YTVkZDJiMjA2 YWRiOWNjOTEzMGMwMTAxMGE2NjA2MDYwOTA3MDgwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDMwNDA1MDYwOTA3MDIw MTA2MDkwNDBjMDMwMTAxMDEwMTA2MGQwZWFhNDE3NDMwNjg1Zjk0YWJjNDkwMjQwMTA1MDUwNjA3 MDgwMjAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDkwMjAxMDEwMTA3MDQwZDA0MDEwMTAyMDkwMjAxMDEwYTAxMDEwOTA3 MDE0YzZlNzFiYg0KODk1ZTMyNTBhNTQ5MDQwNTA2MDkwODAyMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDFlNzAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMjU4NDM4MjNlMzA4NzVmNGYx NTkxMDMwMjAzMGMwZDBlMDUwMTAxMDEwNzA4MDIwMTAxMDkwMzBkMGQwNDA2MDEwMTA3MDgwMTAx MDcwNDAyMDIwMjAyMDIwMjAyMDIwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMWU2MDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIw MjAyMDIwMjAyMDIwNDAyMDEwM2M3NTUxNzFiNjk4ODg3YmIzMzY0MGUwNjAxMDEwMTA2MGEwYTA5 MDEwZTBkMDcwMTAxMDEwMTA4MDEwOA0KMDYwOTAyMDEwMjA5MDIwMjAyMDIwMjAyMDIwMjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwNjA4MDEwMTA4MGUzNjc3 Mzc1NDZhY2NkYzdjNjI0MjRkY2QNCjM1MDEwMTAxMDQwYjAxMDEwMTAxMDcwNDBhMGIwMTA3MDYw NjA3MDIwMTAxMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAy MDIwMjAyMDIwMjAyMDIwMjA2DQowYTBjMDQwMjAxMDEwODI0MzQ0NGE5MWVkNGNiODZiNTcxYjI2 NDBmMGEwNTA3MDUwZDBhMDUwMTAxMDEwMTAxMDEwODA4MDgwMjAxMDIwMjAyMDIwMjAyMDIwMjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEw OTBiNjYwMTA0MGIwNjA1NjRhYzhkMWY4YzNjN2RhMmMwNDcyNTM1MGEwODAxMDEwMTA1MGMwODAx MDEwMTAyMDcwNzAyMDIwMjAyMDIwMjAyMDIwMjAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDAwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDIwMjAyMDIwMjAyMDIwMjA3MDYwNTA1MDkwODA4MDgwMTAzMGY1OTBkMDIwNzBkNWJjMmNh MzE1ZTJmMTk1MGM1YTQ0ZDRjMDkwOTBlMGY0YjBkDQowMTAxMDEwOTA5MDgwMjAyMDIwMjAyMDIw MjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjA5MDkwOTA4 MDgwOTBkMGU1OTA4MDEwMTA5MTEyNDA1MDEwYQ0KNjNkNjE1M2ZkYjhjNjk3MzUzMTYzNzkzMzYw ZTY0MTAwYzA4MDgwOTA5MDgwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDAw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAxMDENCjA3MDkwOTA3MDcwOTAxMDM2NjExMDkwMTAxMDIw NzA4MDEwMTA2MTAyNjQ0MmEzZTJjOTU2ODFjNWRkNTI2NzYwZjA1MDcwOTA3MDEwMjAyMDIwMjAy MDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDIxMDcwYjg1MzFj MzEzZDg5ZGJjZmM5NjcwNzAxMDcwMTAxMDIwNTBkMDMwODAxMDEwMQ0KMDEwNjA5MDEwMTAxMDEw ODA3MDkwOTA5MDYwNDAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMjAyMDIwMjAyMDIwMjAyMGQwNDA0MzU2NThmOTY4ZWRiODkNCmQ0YTFkYjYyYjI0ZDkwNTkw NTAxMDEwMTA2MDMxMTBhMDkwMjAyMDkwYzRiMDIwMjAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAy MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDE4ZTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyDQowMjAyMDIwMjAyMDIwNzAxMDEw MTAxMDYzNTVhNjU0NzYyNTAzMWFkMmMyY2FmMTUyNjRhMDkwMTA5MGEwMTAxMDIwNzA4MDEwMTAx MDUwNjA2MDUwMzBjMjQzNTAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMTA5MGU2NjRiMGQwMTAxMDEwMTBkYjBjMzljMmEzYTlm ODA3Y2E2N2ZkYWIwMDMyNDExMGUwNTA3MDYwOTAxMDEwMTAxMDEwMjAyMDEwMTAyMDINCjAyMDIw MjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwNjA4 MDEwMTAxMDEwNzA1MjQwZDAyMDEwMTAzMTJhYWQ5ZDAxOTllOTVhZDkyNWQxNTQ0DQpjNDA0MDEw MTA5MDYwNTA2MDYwNTA0MDYwMjAxMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwOTAyMDEwMTAxMDEwODA2MDEwMQ0KMDEwNzA2MDYw OTA3MDEwMzRkYmFhOTFiMmRkODJmNzMzOWMyNTZjNDM2MDkwNjAyMDEwMTA2MGIxMTRiMDIwMjAy MDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTI4MDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDINCjAyMDIwMjAyMDIw MjAxMDcwYzExMzUwZDAyMDEwNzAyMDEwMTAxMDEwMTAxNjYwZDAxMDEwNjY1MTRhZTkyMzIyZDY5 MzA1MjNmMTVjODYzMjQwMTAxMDEwNDBjMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjA4MDIwMTAxMDEwMTAxMDEwMjAxMDEwODA2 MDYwODAxMDEwOTAzMDMwNTA2MDUwMzBjYjQxNWQ3M2FkNGI3OTgzYzUyYzA0NzI1MTA2ZjM2MDIw Mg0KMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA2MDQN CjBjNTk2NGM5OTczOTFiNjlkNDk5MWY2YmI4YzY2NjI0MGQwOTA4MDkwYTI0MDEwMTAxMGEwYTAx MDEwODAxMDgwNjA3MDEwMTAyMDcwMTAxMDEwMTA4MDYwNDA0MDEwMTAxMDIwMjA4MDgwNzAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA4MTExMGI0NTUzODhkODc4YmNl MmUxOWE4N2ZkNmFhMjQwMTAxNGMzNTAzMDEwMTAxMDYwMzA4MDYwMzBkMDQwNjA5MDkwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDIwMjA4MDgwODA3MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMTQwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDUwYzM1MGUwNTAxMDEwMTAxMDkxMTkwYmZjMjYxMTg5YTMwOWZjMWI2M2JiODQyMTM1NzkwMDgw MTA2MGUwMzAxMDENCjAxMDEwMjAxMDEwMTA4MDkwNTA0MDUwNjA1MDQwMTAxMDIwMjAyMDgwODA4 MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA3MDYwNjA2MGQwZTA0MGQwOTAxMDEw NDM1MTE3ZTQzDQpkNWE2MWM4YzdkOGNiN2ExMTgxNDZmNWE0YzA5NjYwYjA2MDcwNTBhMGUwZTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMg0KMDIwMTAxMDEwMjA5MDUwZDBhMDMwNjA5MDYwNjAzMDYwMjA1NmZjMzIxOTcyYTcz ZDQyZDdkODc1MTU0NzA0OTYzNTkwMzA4MDEwMTM1MGIwMzA5MDgwMjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEyNDM1MzUwZTBkMDUwNTA1MDEwMTAx MDEwMTA4MGQ2NjAxMDgwYjM1MGMwMzAzMGM0OWIxYTgxYjVmMmVhZDFiMzA1MjYxYzI3MDY0NjYw NjBlMDYwMTAxMDIwMzBhMGQwODA4DQowMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDcwMzU5MTA1YTA1MDEwMTA3MDcwMjAxMDEwMTA5MGEw YTA3MDEwMTkwZDI3YjgwODhhMQ0KOTg5OTFlN2EzOGQzOTNhYTM1MDYwNTBkMDUwMjA1MDYwNjA2 MDkwOTA3MDcwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNjA5MDIwMTAxMDgwNjAzMDgw MTAxMDgwMTAxMDc0YjAyMDENCjAxMDEwMTAxMDIwMTAxMDIwZTgzNGIwMjAxMDdiMzRlZDAxOTk5 YTE4ODdkNWU2MDhhZDE0OGJmNzZiMDBkMGQwMzAzMDQwNDA1MDUwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDE0MjAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAyMDIwMjAyMDIwMjAyMDIwMjA4MGRiMDhmN2YxODNiY2U2ODNjM2M4YzlhY2Y3ZjViYjJi MzI0MDEwYzBjMDEwOTAxMDIwZDAzMDEwMTAyMDcwOQ0KMDcwMjAxMDEwMTA4MDEwODA5MDIwMTAx MDkwYzAxMDEwMjAyMDIwODA4MDgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwNDA3MDEw MTA2NGNjZDkxNTYyMWE4NjliYzk1NWYzYjllM2QNCjYxNDE0NTg0MjMwNDBhMDUwMTAxMDIwOTA2 MDcwMTAxMDcwNTA0MGEyNDExMDkwMzBkMDYwMTAxMDEwODA4MDgwODA4MDgwMjAyMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwYjBkDQowNTAyMDEwMTAxMDEwYTBjNGI2N2I0NTUzZjUy NmFhMWNiY2M5NTNiNzU2MzAzMjQwYjA2MGI0YTY2MDEwNzA4MDIwMTAxMDEwMTAxMDIwNzA2MDkw ODA3MDUwYTA4MDgwNzA4MDgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTJiMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAx MDEwMjA2MDQwMzA0MDQwMTAxMDEwMTAxMDE1YTc2YzhjOTVjY2E4Y2NiY2I5ODMxNTFjMjI1NGJi MDM2MDUwYzA1MDIwMTAxMDgwOTA5MDEwMTAxMDEwMTAxMDIwOTAxMDINCjAyMDIwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAyMDIwMjA4MDgwMTA4MTE0YTU5MDYw MTAxMDgwNjAzNjZjNGM1NzQzYTVlMmQzZDdiNGYyYWI4YzZjN2IwDQo0YjBkMDQwNDA2MDgwZDAz MDQwNDA1MDcwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxYzQwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIw MjI0MGMwMzA5MDgwMjAyMDgwZDAxMDEwMTAxMDEwNTI0MDEwMw0KMjQwYTAyMDEwODA0NGJiZmMw NTEyZGMxYjZhZDNhN2EzOGMyMjdjMzY1NjYwMTAxMDEwMTA5MDYwODAxMDYwNzAxMDEwMTAxMDIw NzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDAwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAyMDINCjAyMDIwMjA4MDgwNzA1MDcwNTI0 NGIwYzA5MDEwMTAxMDEwMTAxMDgwZTgzMDgwNjI0NThiOWFjYTgxYmJlYjY5ZmExYWQ3MjRmNmM0 OTY0NGMwNzAxMDIwNjA0MjQwYzA2MDEwMTAxMDcwNjAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxZDgwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMjAyMDIwMjAy MDIwMjAyMDEwMjA5MDUwNTA5MDgwMTA1MDEwMTAxMDIwODA3MDUwZDA4MDEwNjAzMDcwMTAxMDEw MTAxMDUwOTAyMGJiMDQ3NzgxNjUyOThiYzhiM2MyZDNlYWNiZDkwMTJiMDIzNWE0Yg0KMGQwNzAx MDEwNzA1MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAzMGENCjExOTA0NmJh ODJiYjJjYTE4MTgwN2MzOWFmYjE1NjI1MGMwNDVhMTAzNTAxMDIwMTAxMDEwMTAyMDkwNTBiMDQw MjAxMDEwMjA0MGEwNzA4MDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwYTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTA1NGMxMDZlOTZhOGFkYjZiNzg4MjAyYzUwYjg0 MWI5NGQzNjBjMGEwZDAzMGEwYzBhMDkwMTAxMDkwYjY2NjYwYzAxMDEwNzA3MDgwODA3MDYwNTAz MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMzUzNTI0MGMw NTA4MDIwMjA0MGQwZTEyYjQyMWI1M2U4ODg4OTk4NzFhMThhZjcxYTRiNDVhMDEwMTAxMDIwODBl MGENCjA2MDgwODA4MDIwMTRiMjQwZDA5MDIwMTAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTA5MDQwZDAzMDQwNDAzMDkwMTAxMDEwNTVhMjM0Mjc1 DQo2MTNhNWYyZTY4OWYzMjUzOGViMmIzMjM0YjA2MDEwMTAxMDYwYTBiMGQwNjAxMDEwMTAxMDEw MTAxMDgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwNzExMTI1YTBiMDIwMTA0MGU0YTc2MjI3ZmE2MTk5ZjllM2M1ZTFmOWJi MTIyMjU2NzRjMGEwNTA5MDEwMTAxMDkwZDBiMGIwMzA3MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTk0MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDE0YzM1MGEwNDA1MDYwOTA3MDkwMTAxMDEwMTAxMDM0 YzA3MDEwMTAxMDEyNGFhNmUzMzhlMTcxYjgwNjgyZThjMWQzOTc5NDg1NzgzMDUwMTAxMDEwOTBh MGMwMzA4MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDcwNzAyMDgwOTBhMTEwZTA3MDEwMTAyMDMzNTM1MDMwMTAxMDEwMTA1NGE4NDM3 YWY4ZDFmOTk2OQ0KNWYyMDkyNTQ1NTdlYjAwZjBhMDEwMTAxMDYwYTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTJhMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDIwNzA0MDQwOTAxMDcwMTAxMDkwNzAx MDEwNDAxMDcNCjA0MDYwMTAyMGQ2NjAyMDgwMjAxMDEwNjVhYWFhYmFjNWQxOTk5YTFhZDIwMWZh OGFlOTEwYTAxMDgwZDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTUwMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwYzBkMDYwMjAxMDEwMTAyMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIw MjAyMDIwMjAyMDIwNjA1MjQyM2E3NzFhODE5N2QyZTdkMWM4ZGE5Mzc2MzkwNTkwMzAxMDEwOTBk MGMwMjA5MDkwMTAxMDEwODA4MDEwMQ0KMDEwMTAxMDEwMjAyMDEwMTAxMDkwMzAzMDcwMTAyMDIw MjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAy MDIwYTAzMDkwMjAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwNzAxMDEwMTA1NGMyMzY0 YTRhNWE2M2I1ZTJlMWIxNzg1MjkNCjU1N2U5MTIzMzYxMjBkMDQwMjAxMDEwYTY2NGMwYzBjMGEw MzA5MDIwMTAxMGMwNDA3MDgwOTA3MDEwMTAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMzA1MDcwMTAxMDEwMTAyMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAy MDIwMjAyMDIwMjAyMDIwZDAzDQowNTA3MDEwMTAxMDE1YTBmMGUwYjc2OWM5NDcyOTVhMGExODlh MjgyYTMyMjRiMGUwMzA5MDUwMzAyMDEwMTAxMDEwMTAxMDEwMTA4MGEwNTA4MDgwNTBhMGMwYTAy MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxZWIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDINCjAyMDIw MjAyMDIwMjA1MDkwODAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAxMDEwNzA0MGQw YTBkMDMwMTA4MDEwMTAxMTEzNDQ2OWM5ZDdiM2Q5ZTlmMmQ3ZDg2OGE2ZDU4MGUwYjBlMGEwZDBk MDMwNjAxMDEwMTA3MDYwMjAxMDEwMjA3MDcwODAyMDINCjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIw MjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjA3MDgwMjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTBhMTA1ODgzMGQwMTAxMDIwZDRh NmU0MTk3MmIxYzk4OTk2YTlhOWI2MjM3NDkwMTAxDQowODA4MDIwNzBkMzUxMTBiMDUwOTA5MDcw MTAxMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAy MDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjBjMDMwNjA4 MDEwMjA3MDkwNTA5MDIwMTAxMDEwNzExMGQwNg0KMDEwMTAxMDM1YTU4N2UyMTk0NWY5NTY4MWU3 YTMzOTY0MTU2NGQzNjExMGI2NjBjMDcwMTA4MDYwNDA1MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAy MDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDIwMjAyMDIwMjAyMDIwMjA4MDINCjAxMDEwMjA3MDYwNTAxMDEwNjBlMGIwOTAyMDkw MTAxMDQwYzBkMDkwMTAxMDEwZDEyOTE0ODZjOTIzMDNjM2MyYzE5NWQ0MDQzNTY0NzkzMTAwMzAx MDEwNzA2MDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIw Mg0KMDIwMjAyMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDgw NzA3MDgwMjAxMDEwMTA4MDEwMTA4MDkwMTAxMDYwODA3MDgwMTAxMDEwNzA0MDYwYjM1MDMwMjA5 MGU1OTQ1MjcxNjJiMWY2OTY4OGI4YzhkOGU4ZjkwMjQwMzA0MDIwMg0KMDIwMjAyMDIwMjAyMDIw MjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDExYjAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAyMDIwMjAxMDUNCjBlMzU4Mzg0MjE4NTg2NzI4 Nzg4ODk1MTVkOGExNDU3MzUwMTA4MDMwNTAxMDEwOTBjMGQwODAxMDIwNTA0MDQwNjAxMDEwMTAx MDkwMTAxMDEwOTA2MDEwMTA3MDEwMTAyMDcwOTA5MDkwNzAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMjA4MDcwMTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMjAyMDIw MjAyMDIwMjAyMDQwYTBhMDgwMTA2NmYxMzY1N2U3ZjE4M2IyZjgwODE2ODZhN2E4MjQwNmQyNTI0 MDQwNzAxMDEwNjA0MDkwMTAxMDEwMTA3MDcwODAxMDE0YjBiMGMyNDBjMDgwMTAyMDUwOQ0KMDIw MTAxMDEwMTAxMDkwOTA5MDkwOTA5MDkwOTA0MDMwNDA5MDIwMTAxMDgwMTAxMDEwMTAxMDEwMTAw MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDEwODA3MDEwMTAxMDEwODAz MGI0YzM2Nzc0Njc4Nzk3YTdiNTA3YzVlMmQ3ZDZhNWQyMTEzMGMwNzA0MDUwODU5MjQNCjAzMDUw MzBhMDMwNjAxMDEwMTAxMDEwMTAyMDkwOTA4MDIwMTA4MDUwYTBiMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTA5MDQwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAy MDIwMjAyMDIwMjAyMDEwMTAxMDcwMzBkMDQwOTAyMDEwMTAxMDEwMTAzMGY2NzIzDQo1NzcwNzE0 ZjUxNzI3MzFiM2E3MjUyNzQ3NTQ3NzYzNjA0MDEwMTAyMDcwNzRjNGIwYjA1MDcwODA4MDIwMTAx MDEwMTAxMDEwMjA4MDIwMjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwNzA3MDcwMTAxMDEwMTAxMDEw MTQ4MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDkwMg0KMDEwMTA4MDcw MTAxMDUwODA4MDMwYzBhMGQwYzBiMDkwMTAxMDc2NjY3NjMyNzI4NWQxYzJlNjg2OTZhNmIyYTZj MjE2ZDZlNmYwZDAxMDcwMTAxMDEwNzA0MDYzNTM1MzUyNDBjMDQwNzAxMDYwNjA2MDYwNjA2MDYw NjRiMGMNCjA1MDkwNjA3MDEwMTAxMDEwMTAxMDEwMTAxMDAwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAyMDIwMjAyMDIwMjAyMDIwMzA3MDEwMTAxMDgwODAyNWEwZDAxMDEwMTAxMDEwMTBkMDQwNjA3 MDkwNTBkMGIwYTBhMGI1OTM0NWI1YzVkMWQzZDVlMmU1ZjYwNjE2MjYzNjQ2NTY2MGEwYzA1MDEw MTAxDQowMTAxMDIwODA3MDcwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDgwOTA5MDcwODAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMTAyMDgwODA5 MDQwYzI0MDEwMTA3NGIxMjRjMGEwOTAxMDIwOTA3MDEwMTAxMDEwMTAyMDkwOTAxMDEwMTAyMTI0 ZA0KNGUyOTRmNTAxZDMyNTE1MjUzNTQyODU1NTY1NzU4MTIwZTA5MDIwOTBjMzUzNTM1MzUzNTM1 MzUzNTM1MDEwYjBmNTkwYTA3MDUwYjAxMDEwMTAxMDEwMTAxMDkwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAyMDIwMjAyMDIwMjAyMDIwMTA3MDYwNzAxMDEwMTAyMGQwODAxMDEwMTAxMDIwNDAxMDgN CjA5MDcwMTAyMDYwYTM1MGEwODAxMDEwMTA3MDYwNDA0MDYwMjA1MzYyNjM3MzgzOTNhM2IzMjNj MmUzZDMwM2UzZjQwNDE0MjQzNDQ0NTQ1NDU0NTQ1NDU0NTQ1NDY0NzQ4NDk0YTAxMDEwNjAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMjAyMDIwMjAyMDIwMjAyMGEyNDEyMjUyNjI3MjgyOTJhMmIxYzJjMmQyZTJjMmYxZDFkMWUy MDMwMzEzMjJmMmUyYg0KMzMzNDBlMDYwNjA1MDEwMTAxMDEwMTAxMDEwMjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAyMDIwMjAyMDIwMjAyMDgwMTAxMDEw MTA4MDMwYjBlMTINCjEzMTQxNTE2MTcxODE5MWExYjFjMWQxZTFmMjAyMTIyMjMwNTAxMDEwMTAx MDEwMTAxMDEwMTAxMDFjNDAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMjAyDQowMjAyMDIwMjAyMDIwZTBjMDUwODAxMDEwMTAxMDYwODAxMDEwNzBiMGYxMDA0 MDQwMzAzMGQwYTBhMGMxMTA1MDEwMTAxMDYwNjA3MDEwMTAxMDEwMTAxMDFmMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMTAx MDEwMjA5MDUwZDBhMGQwNTA4MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwNTBiMGUw ZDA3MDEwMTAxMDEwMTAxMDEwMjAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDkwNDBhMGMw YjA1MDUwNjA2MDkwOTA5MDcwODA4DQowNzA2MDQwOTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDIwMjAyMDIwMjAyMDIw YjBiMGMwYTAzMDYwNzA4MGEwMw0KMDYwMjAxMDEwMTAxMDIwMjAyMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAyMDINCjAyMDIwMjAyMDIwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAy MDkwMzBhMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAxMDEwODA2MDMwMTAxMDEwMTAxMDEwMTA5MDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMjAyMDIwMjAy MDIwMjAzMDQwNTA2MDcwODAyMDIwMzAzMDMwNTA5MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAyMDgw ODAyMDEwMTA4MDYwMTAxMDEwMTAxMDEwMTAyMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMjgwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDFiYzAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEyYzAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMjAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQow MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAyMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx DQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAwMDEwMQ0K MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMWUw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDIwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDENCjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEN CjAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxDQowMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMQ0KMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDENCjAxMDEwMTAx MDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEw MTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAx MDIwNDAwMDAwMDI3MDFmZmZmMDMwMDAwMDAwMDAwfVxwYXJ9fX17XGluc3JzaWQ3NzU3NTQwIA0K XHBhciB9XHBhcmQgXHFsIFxsaTBccmkwXG5vd2lkY3RscGFyXHR4NDIyMFxmYWF1dG9ccmluMFxs aW4wXGl0YXAwXHBhcmFyc2lkNzc1NzU0MCB7XGJcaW5zcnNpZDc3NTc1NDAgXCdkMFwnZjNcJ2Vh XCdlZVwnZTJcJ2VlXCdlNFwnZThcJ2YyXCdlNVwnZWJcJ2ZjfXtcaW5zcnNpZDc3NTc1NDAgXHRh YiB9e1xiXGluc3JzaWQ3NzU3NTQwIFwnZDJcJ2U4XCdlY1wnZWVcJ2Y0XCdlNVwnZTVcJ2UyXCdl MCBcJ2NlfXtcYlxmMzlcaW5zcnNpZDc3NTc1NDAgLn0NCntcYlxpbnNyc2lkNzc1NzU0MCBcJ2Mz DQpccGFyIH1ccGFyZCBccWwgXGxpMFxyaTBcc2wtM1xzbG11bHQwXG5vd2lkY3RscGFyXGZhYXV0 b1xyaW4wXGxpbjBcaXRhcDBccGFyYXJzaWQ3NzU3NTQwIHtcaW5zcnNpZDc3NTc1NDAgDQpccGFy IH1ccGFyZCBccWwgXGxpMFxyaTBcbm93aWRjdGxwYXJcZmFhdXRvXHJpbjBcbGluMFxpdGFwMFxw YXJhcnNpZDc3NTc1NDAge1xiXGluc3JzaWQ3NzU3NTQwIFwnZWVcJ2YwXCdlM1wnZWFcJ2VlXCdl Y1wnZThcJ2YyXCdlNVwnZjJcJ2UwfXtcaW5zcnNpZDc3NTc1NDAgDQpccGFyIH1ccGFyZCBccWwg XGxpMFxyaTBcd2lkY3RscGFyXGFzcGFscGhhXGFzcG51bVxmYWF1dG9cYWRqdXN0cmlnaHRccmlu MFxsaW4wXGl0YXAwIHtcaW5zcnNpZDc3NTc1NDAgDQpccGFyIH19 ------=_NextPart_000_0AE8_01CFDC97.48577FA0-- From conference.b40@gmail.com Tue Sep 30 04:31:58 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.3 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,HTML_MESSAGE,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 343957F4E for ; Tue, 30 Sep 2014 04:31:58 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1F746304051 for ; Tue, 30 Sep 2014 02:31:55 -0700 (PDT) X-ASG-Debug-ID: 1412069508-04cbb0730167c9f0001-NocioJ Received: from mail-wg0-f66.google.com (mail-wg0-f66.google.com [74.125.82.66]) by cuda.sgi.com with ESMTP id BbtEmsjiVzRoAG6D (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Tue, 30 Sep 2014 02:31:49 -0700 (PDT) X-Barracuda-Envelope-From: conference.b40@gmail.com X-Barracuda-Apparent-Source-IP: 74.125.82.66 Received: by mail-wg0-f66.google.com with SMTP id k14so3009057wgh.9 for ; Tue, 30 Sep 2014 02:31:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:cc:content-type; bh=6VxhhnwIAdde+etlvfeS1p0R0ZCaxXf1cjTrwLzenE4=; b=yYpmMdfjr2iyhavTBGfd/FgjXLWz0qP9tJ/MNkcePDgEPMqkpgrITi/SroyjAoWUC1 8WtmWpiVN79QRDhV45fWxPvhlt40dngxeXahSHCCfNrqMqc0ggTOyaAMP0Om6c/ygxvO GVomk24MZWle5VY0IF31hQyHHLiFfBm++yct19J2CtyTsvjAQe5AYHOGtgyNNFJKlz88 ZicnQYJWJ+hnFt18ESQgzoP6p+ZxOVmkqsNBRJkJ+BuvOB9HCGRVa9DiZw4Y3OEiqbJE 1ZFR5n6bi04ImPOYbQwW1er/hX/z/imgMYGa+iIfY4W7Vm01EsWW6vE8FjchRNqit8pY aIMw== MIME-Version: 1.0 X-Received: by 10.194.78.101 with SMTP id a5mr10680125wjx.118.1412069507770; Tue, 30 Sep 2014 02:31:47 -0700 (PDT) Received: by 10.66.150.38 with HTTP; Tue, 30 Sep 2014 02:31:47 -0700 (PDT) Date: Tue, 30 Sep 2014 02:31:47 -0700 Message-ID: Subject: Call for paper- International Conference on Economics, Energy, Environment and Agricultural Sciences From: "conference.b40" X-ASG-Orig-Subj: Call for paper- International Conference on Economics, Energy, Environment and Agricultural Sciences To: PP Group Cc: info@pakinsight.com Content-Type: multipart/alternative; boundary=047d7bf0c29868bb2f0504450d1b X-Barracuda-Connect: mail-wg0-f66.google.com[74.125.82.66] X-Barracuda-Start-Time: 1412069509 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.50 X-Barracuda-Spam-Status: No, SCORE=0.50 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA_TO_FROM_ADDR_MATCH, DKIM_SIGNED, DKIM_VERIFIED, HTML_MESSAGE, MAILTO_TO_SPAM_ADDR X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10059 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 MAILTO_TO_SPAM_ADDR URI: Includes a link to a likely spammer email 0.00 HTML_MESSAGE BODY: HTML included in message 0.50 BSF_SC0_SA_TO_FROM_ADDR_MATCH Sender Address Matches Recipient Address --047d7bf0c29868bb2f0504450d1b Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Dear Colleagues, *Call for papers* International Conference on Economics, Energy, Environment and Agricultural Sciences * (ICEEEAS)* *(**1-2 November, 2014**=E2=80=93 Kuala Lumpur, Malaysia)* *Pearl International Hotel**, Kuala Lumpur, Malaysia* http://www.pakrdw.com/?ic=3Ddetails&id=3D7 The aim of *ICEEEAS 2014* is to provide productive opportunities for academics and practitioners from interdisciplinary fields of Business, Economics, Energy, Environmental and Agricultural Sciences to meet share and take away expertise and ideas in related disciplines. The conference will bring together leading researchers in the domain of interest from around the world. The *ICEEEAS 2014* offers interdisciplinary themes of quality R&D topical developments from potential contributors and experts and provides an opportunity in bring in the new techniques or policies. *Paper Submission: For online submission, follow the link* http://www.pakrdw.com/?ic=3Ddetails&id=3D7&info=3Dsubmission *Those who wish to submit paper as an email attachment should send their papers at* *conference@pakinisght.com;* editor@aessweb.com ; conference@pakrdw.com *Publication Opportunities* To see the full list of Journals for special issues of ICEEEAS, 2014, click http://www.pakrdw.com/?ic=3Ddetails&id=3D7&info=3Dbook_proceed *Journal Publication* After presentation in ICEEEAS 2014, few selected papers will be published in special issues of the following journals. *Asian Economic and Financial Review * (*Online ISSN:* 2222-6737 - *Print ISSN:* 2305-2147) URL: http://www.aessweb.com/journals/5002 *International journal of Asian Social Science * (*Online ISSN: *2224-4441*- Print ISSN: *2226-5139) URL : http://www.aessweb.com/journals/5007 *International Journal of Management and Sustainability * (*Online ISSN:* 2306-0662* - Print ISSN:* 2306-9856) URL: http://www.pakinsight.com/?ic=3Djournal&journal=3D11 *International Journal of Sustainable Development & World Policy * (*Online ISSN: *2305-705X* - Print ISSN: *2306-9929) URL: http://www.pakinsight.com/?ic=3Djournal&journal=3D26 *International Journal of Sustainable Energy and Environmental Research* (*Online ISSN: *2306-6253* - Print ISSN: *2312-5764) URL: http://www.pakinsight.com/?ic=3Djournal&journal=3D13 Asian Journal of Agriculture and Rural Development *(Online ISSN: 2224-4433**- **Print ISSN: 2304-1455)* *URL: *http://www.aessweb.com/journals/5005 Other journals: http://www.pakrdw.com/?ic=3Ddetails&id=3D7&info=3Dpublicati= on *IMPORTANT DATES* Abstract Submission Date: 1st October, 2014 15th October, 2014 *(Extende= d deadline)* Decision of Acceptance/Rejection: Within 15 days of submission Full Paper Submission Date:20thOctober, 2014 Early Bird Discount Date: 15th October, 2014 *(Extended deadline)* Conference date: *1-2 November, 2014* Warmly Regards, *Conference Co-chair,* *(ICEEEAS) 2014 Secretariat* International Conference on Economics, Energy, Environment and Agricultural Sciences * (ICEEEAS)* http://www.pakrdw.com/?ic=3Ddetails&id=3D7 *Email: **conference@pakinisght.com;* editor@aessweb.com --047d7bf0c29868bb2f0504450d1b Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable

= =C2=A0

=C2=A0

=C2=A0

Dear Colleagues,<= /span>

=C2=A0

Call for paper= s

=C2=A0<= /b>

International Conference on Economics, Energy, Environment and Agricultural Sciences

=C2=A0(ICEEEAS)

(1-2 November, 2014=E2=80=93 Kuala Lum= pur, Malaysia)

=C2=A0Pearl International Hotel, Kuala Lumpur, M= alaysia

http://www.pakrdw.com/?ic=3Ddetails&id=3D7<= b>

=C2=A0

= The aim of=C2=A0ICEEEAS 2014=C2=A0is to provide productive opportunities for academics and practitioners from interdisciplinary fields of Business, Economics, Energy, Environmental and Agricultural Sciences to meet share and take away expertise and ideas in related disciplines. The conference will bring together leading researchers= in the domain of interest from around the world.=C2=A0The ICEEEAS 2014= =C2=A0offers interdisciplinary themes of quality R&D topical developments from poten= tial contributors and experts and provides an opportunity in bring in the new techniques or policies.

=C2=A0

Paper Submissi= on:=C2=A0=C2=A0For online submission, follow the link

=C2=A0http://www.pakrdw.com/?ic=3Ddetails&= ;id=3D7&info=3Dsubmission

Those who wish= to submit paper as an email attachment should send their papers at

conference@pakinisght.co= m; editor@aessweb.com ; conference@pakrdw.com

=C2=A0

Publ= ication Opportunities

To see the full l= ist of Journals for special issues of ICEEEAS, 2014, click=C2=A0http://www.pakrdw.com/?= ic=3Ddetails&id=3D7&info=3Dbook_proceed = =C2=A0

Jour= nal Publication

= After presentation in ICEEEAS 2014, few selected papers will be published in special issues of the following journals.

=C2=A0

Asian Economic and Financial Review=C2=A0=C2=A0 =C2=A0
(Online ISSN:=C2=A02222-6737 -=C2=A0Print ISSN:=C2=A02305-214= 7)

URL:=C2=A0http://www.ae= ssweb.com/journals/5002

International journal of Asian Social Science=C2=A0
(Online ISSN:=C2=A02224-4441- Print ISSN:=C2=A02226-5139)
URL : http://www.aessweb= .com/journals/5007 =C2=A0

International Journal of Management and Sustainability=C2=A0
(Online ISSN:=C2=A02306-0662=C2=A0- Print ISSN:=C2=A02306-985= 6)
URL:=C2=A0
h= ttp://www.pakinsight.com/?ic=3Djournal&journal=3D11

International Journal of Sustainable Development & World Policy=C2=A0
(Online ISSN:=C2=A02305-705X=C2=A0- Print ISSN:=C2=A02306-992= 9)=C2=A0

URL:=C2=A0http://www.pakinsight.com/?ic=3Djournal&journal=3D26

International Journal of Sustainable Energy and Environmental Research=C2=A0=
(Online ISSN:=C2=A02306-6253=C2=A0- Print ISSN:=C2=A02312-576= 4)
URL:=C2=A0
h= ttp://www.pakinsight.com/?ic=3Djournal&journal=3D13

Asian Journal of Agriculture and Rural Development

(Online ISSN: 2224-= 4433= - Print ISSN: 2304-1455)

URL: htt= p://www.aessweb.com/journals/5005 =C2=A0

Other = journals: http://www.pakrdw.com/?ic=3Ddetails&id=3D= 7&info=3Dpublication

=C2=A0= =C2=A0

IMPO= RTANT DATES

Abstract Submi= ssion Date:=C2=A01st=C2=A0October, 20= 14=C2=A0=C2=A0=C2=A015<= sup>th=C2=A0October, 2014=C2=A0 (Extended deadline)
Decision of Acceptance/Re= jection: Within 15 days of submission=C2=A0
Full Paper Submission Dat= e:20thOctober, 2014=C2=A0
Early Bird Discount Date:= 15th=C2=A0October, 2014 =C2=A0
(Extended deadline)
Conference date:=C2=A01-2 November, 2014
=C2=A0<= /b>

=C2= =A0

=C2=A0

Warm= ly Regards,

=C2= =A0

C= onference Co-chair,

(ICEEEAS) 2014 Secretariat

International Conference on Economics, Energy, Environment and Agricultural Sciences

=C2=A0(ICEEEAS)

http://www.pak= rdw.com/?ic=3Ddetails&id=3D7

Email:=C2=A0con= ference@pakinisght.com; editor@aessweb.com

=C2=A0

=C2=A0


=C2=A0

--047d7bf0c29868bb2f0504450d1b-- From cmaiolino@redhat.com Tue Sep 30 09:19:06 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 19EC97F72 for ; Tue, 30 Sep 2014 09:19:06 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id EE2CE8F8037 for ; Tue, 30 Sep 2014 07:19:02 -0700 (PDT) X-ASG-Debug-ID: 1412086741-04cb6c50e55f8c40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id RYKTbSYpInfWH7k1 (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 30 Sep 2014 07:19:02 -0700 (PDT) X-Barracuda-Envelope-From: cmaiolino@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8UEJ1x8005086 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 30 Sep 2014 10:19:01 -0400 Received: from localhost.localdomain (ovpn-113-132.phx2.redhat.com [10.3.113.132]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8UEIwlX030998 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO) for ; Tue, 30 Sep 2014 10:19:00 -0400 Date: Tue, 30 Sep 2014 11:18:57 -0300 From: Carlos Maiolino To: xfs@oss.sgi.com Subject: Why not move xfs infra-structure to "public" services Message-ID: <20140930141857.GA2053@localhost.localdomain> X-ASG-Orig-Subj: Why not move xfs infra-structure to "public" services Mail-Followup-To: xfs@oss.sgi.com MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1412086742 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hi guys, I'm sorry for this kind of "fancy" question from my side, but I'm wondering why xfs project infra-structure (mailing list, git trees), does not use the "usual public" services. I mean, does anyone thought about moving xfs mailing list to vger.kernel.org, and the git trees to git.kernel.org? Sorry about been asking it mainly because I'm too lazy to keep deleting spams from my inbox, and also, because having 'everything I need' in a single place (kernel.org) would make my life easier (and probably many other lives :). Anyway, it's just a question/suggestion, please don't get me wrong here. IIRC there were some discussion regarding this some time ago, but, I'm not sure where the discussion stopped and/or if any decision were taken. Cheers o> -- Carlos From sandeen@sandeen.net Tue Sep 30 09:46:36 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id DC3107F73 for ; Tue, 30 Sep 2014 09:46:36 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id B92C78F8039 for ; Tue, 30 Sep 2014 07:46:36 -0700 (PDT) X-ASG-Debug-ID: 1412088395-04cbb07301688240001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id RswvJ71wrVQK8i9I for ; Tue, 30 Sep 2014 07:46:35 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id E044561295A6 for ; Tue, 30 Sep 2014 09:46:34 -0500 (CDT) Message-ID: <542AC24C.8030907@sandeen.net> Date: Tue, 30 Sep 2014 09:46:36 -0500 From: Eric Sandeen MIME-Version: 1.0 To: xfs@oss.sgi.com Subject: Re: Why not move xfs infra-structure to "public" services References: <20140930141857.GA2053@localhost.localdomain> X-ASG-Orig-Subj: Re: Why not move xfs infra-structure to "public" services In-Reply-To: <20140930141857.GA2053@localhost.localdomain> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1412088395 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10066 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/30/14 9:18 AM, Carlos Maiolino wrote: > Hi guys, > > I'm sorry for this kind of "fancy" question from my side, but I'm wondering why > xfs project infra-structure (mailing list, git trees), does not use the "usual > public" services. I mean, does anyone thought about moving xfs mailing list to > vger.kernel.org, and the git trees to git.kernel.org? Please see the prior thread on 8/6/14: [DISCUSS] Moving from oss.sgi.com to kernel.org :) > Sorry about been asking it mainly because I'm too lazy to keep deleting spams > from my inbox, and also, because having 'everything I need' in a single place > (kernel.org) would make my life easier (and probably many other lives :). > > Anyway, it's just a question/suggestion, please don't get me wrong here. > IIRC there were some discussion regarding this some time ago, but, I'm not > sure where the discussion stopped and/or if any decision were taken. I think it's still the plan, but takes some time & effort & coordination. -Eric From cmaiolino@redhat.com Tue Sep 30 10:02:21 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id CC8F57F74 for ; Tue, 30 Sep 2014 10:02:21 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id ACFA7304048 for ; Tue, 30 Sep 2014 08:02:18 -0700 (PDT) X-ASG-Debug-ID: 1412089337-04bdf003a267e860001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id jeEaASQlA3SJtYMK (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 30 Sep 2014 08:02:17 -0700 (PDT) X-Barracuda-Envelope-From: cmaiolino@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8UF2Feu025389 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 30 Sep 2014 11:02:16 -0400 Received: from localhost.localdomain (ovpn-113-132.phx2.redhat.com [10.3.113.132]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8UF2CJT027159 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO); Tue, 30 Sep 2014 11:02:14 -0400 Date: Tue, 30 Sep 2014 12:02:12 -0300 From: Carlos Maiolino To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: Why not move xfs infra-structure to "public" services Message-ID: <20140930150211.GB2053@localhost.localdomain> X-ASG-Orig-Subj: Re: Why not move xfs infra-structure to "public" services Mail-Followup-To: Eric Sandeen , xfs@oss.sgi.com References: <20140930141857.GA2053@localhost.localdomain> <542AC24C.8030907@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <542AC24C.8030907@sandeen.net> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1412089337 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 > Please see the prior thread on 8/6/14: > [DISCUSS] Moving from oss.sgi.com to kernel.org > I will :) > :) > > > Sorry about been asking it mainly because I'm too lazy to keep deleting spams > > from my inbox, and also, because having 'everything I need' in a single place > > (kernel.org) would make my life easier (and probably many other lives :). > > > > Anyway, it's just a question/suggestion, please don't get me wrong here. > > IIRC there were some discussion regarding this some time ago, but, I'm not > > sure where the discussion stopped and/or if any decision were taken. > > I think it's still the plan, but takes some time & effort & coordination. > Thanks for the answer. And, if people need help to move it, let me know, I'm willing to spend time helping the move. cheers > -Eric > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs -- Carlos From arekm@maven.pl Tue Sep 30 12:56:04 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 1C5987F76 for ; Tue, 30 Sep 2014 12:56:04 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 09B9A304048 for ; Tue, 30 Sep 2014 10:56:03 -0700 (PDT) X-ASG-Debug-ID: 1412099757-04cbb07304692270001-NocioJ Received: from mail-wg0-f44.google.com (mail-wg0-f44.google.com [74.125.82.44]) by cuda.sgi.com with ESMTP id 20dNo40ZBkAxpf1g (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Tue, 30 Sep 2014 10:55:58 -0700 (PDT) X-Barracuda-Envelope-From: arekm@maven.pl X-Barracuda-Apparent-Source-IP: 74.125.82.44 Received: by mail-wg0-f44.google.com with SMTP id y10so3343816wgg.27 for ; Tue, 30 Sep 2014 10:55:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=maven.pl; s=maven; h=from:to:subject:date:user-agent:references:in-reply-to:mime-version :content-type:content-transfer-encoding:message-id; bh=oFWJ7tHslQQPKLP7euIfkb2YZEvsobWTf6HS/eQJfKg=; b=mYfc7yYcSj5OfSSeVzVPLRmEzMBDCBfcVeODLVUQLTT3NSTyh9X85vV+pPqLSHskhZ T6FW/s1texDIFLwmkW7kf9FapHMe5ifRbhcAol3dIFsFtGZdiHtiJcTSGZVx5FtTUfbt owtG5LuovyFakBsCB629uaLuJg4vaWsHucy0k= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:user-agent:references :in-reply-to:mime-version:content-type:content-transfer-encoding :message-id; bh=oFWJ7tHslQQPKLP7euIfkb2YZEvsobWTf6HS/eQJfKg=; b=ZGUgrX9uVE6KWRFt2KG0m0CtQxoQidQ9/ps3vY6G7nAjqcBeAjV23X8eLD746PlcZ/ R/ogA0R1nPw7cNcensplM9NSGuYuJHrNTLiISsfd54dIcbuhOG4Ig7y9vcySvHvKySMH hYMRQpL/yjbxWfSeDlsUfOMcp/zhxo+/LqtLfmaDA5I9TIPfNWvbgmgWW4vftimDmqBA 1gUJa4uUXaWXYIW+aaR4IWRYzz5r32jPcFdz2FqJ+mhDx2q9LVpZb1ykaJaCEClMl6Wm eTcycDJfQpvEqOpPzM1ac+z0vUEhXUK4cnIoD4xH7QMCJnDSYoaSn8SILlJPhh9spWm0 m+MQ== X-Gm-Message-State: ALoCoQmNIc+H/WoJLIPfIW3kTWB/vAUJI0VNPnKVYhzsIeAKO9Rbrk1E8qU0uHgO9AT8HrGhIjNJ X-Received: by 10.180.101.129 with SMTP id fg1mr7660811wib.20.1412099757105; Tue, 30 Sep 2014 10:55:57 -0700 (PDT) Received: from t400.localnet (85-222-71-204.home.aster.pl. [85.222.71.204]) by mx.google.com with ESMTPSA id g6sm19989737wjf.13.2014.09.30.10.55.56 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 Sep 2014 10:55:56 -0700 (PDT) From: Arkadiusz =?utf-8?q?Mi=C5=9Bkiewicz?= To: xfs@oss.sgi.com Subject: Re: Why not move xfs infra-structure to "public" services Date: Tue, 30 Sep 2014 19:55:55 +0200 X-ASG-Orig-Subj: Re: Why not move xfs infra-structure to "public" services User-Agent: KMail/1.13.7 (Linux/3.17.0-rc7; KDE/4.14.0; x86_64; ; ) References: <20140930141857.GA2053@localhost.localdomain> In-Reply-To: <20140930141857.GA2053@localhost.localdomain> MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <201409301955.55208.arekm@maven.pl> X-Barracuda-Connect: mail-wg0-f44.google.com[74.125.82.44] X-Barracuda-Start-Time: 1412099758 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10070 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Tuesday 30 of September 2014, Carlos Maiolino wrote: > Hi guys, >=20 > I'm sorry for this kind of "fancy" question from my side, but I'm wonderi= ng > why xfs project infra-structure (mailing list, git trees), does not use > the "usual public" services. I mean, does anyone thought about moving xfs > mailing list to vger.kernel.org, and the git trees to git.kernel.org? vger.kernel.org has rude postmasters (at least one of them) that are unwill= ing=20 to help with vger related issues. Personal experience unfortunately. =2D-=20 Arkadiusz Mi=C5=9Bkiewicz, arekm / maven.pl From bfoster@redhat.com Tue Sep 30 13:22:56 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 16E567F81 for ; Tue, 30 Sep 2014 13:22:56 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 061A3304048 for ; Tue, 30 Sep 2014 11:22:52 -0700 (PDT) X-ASG-Debug-ID: 1412101371-04cbb07301693c60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id FmBmjag5kgW7C2KG (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 30 Sep 2014 11:22:52 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8UIMpUr007368 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 30 Sep 2014 14:22:51 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8UIMoMx015218 for ; Tue, 30 Sep 2014 14:22:51 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 8A865120064; Tue, 30 Sep 2014 14:22:49 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH] xfs: fix check for maximum allowable extent record file offset Date: Tue, 30 Sep 2014 14:22:49 -0400 X-ASG-Orig-Subj: [PATCH] xfs: fix check for maximum allowable extent record file offset Message-Id: <1412101369-52751-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1412101372 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The maximum allowable file size on XFS is 2^63-1 (0x7fffffffffffffff). This value is unaligned with respect to typical order of 2 block sizes. Therefore, the maximum allowable block offset in a file is (2^63-1) / blocksize. xfs_repair calculates the max file offset as such in parse_sb_version(). However, if we write to the maximum byte offset of a file: $ xfs_io -fc "pwrite `echo "2^63-1-1" | bc` 1" /mnt/file wrote 1/1 bytes at offset 9223372036854775806 1.000000 bytes, 1 ops; 0.0000 sec (21.230 KiB/sec and 21739.1304 ops/sec) ... xfs_repair complains that the file contains an invalid extent (4k blocks): ... inode 99 - extent offset too large - start 9, count 1, offset 2251799813685247 ... This occurs because xfs_repair uses a >= comparison against the start offset of the record. Byte offset 2251799813685247 is 2^63-4096, and thus is the maximum valid block offset in the file. Fix the comparison to complain only if the start offset of the record is greater than the maximum allowable start offset. Signed-off-by: Brian Foster --- Hi all, This allows xfstests test xfs/071 to pass without a post-test corruption (repair) failure. Brian repair/dinode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/repair/dinode.c b/repair/dinode.c index 38a6562..f734a18 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -667,7 +667,7 @@ _("inode %" PRIu64 " - bad extent overflows - start %" PRIu64 ", " irec.br_startoff); goto done; } - if (irec.br_startoff >= fs_max_file_offset) { + if (irec.br_startoff > fs_max_file_offset) { do_warn( _("inode %" PRIu64 " - extent offset too large - start %" PRIu64 ", " "count %" PRIu64 ", offset %" PRIu64 "\n"), -- 1.8.3.1 From bfoster@redhat.com Tue Sep 30 14:21:31 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id E2D3C7F86 for ; Tue, 30 Sep 2014 14:21:31 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id D1CCF30405F for ; Tue, 30 Sep 2014 12:21:28 -0700 (PDT) X-ASG-Debug-ID: 1412104886-04cbb07304696950001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id LaNvpc6QgLGAZRtE (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 30 Sep 2014 12:21:28 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8UJLPlG011993 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 30 Sep 2014 15:21:26 -0400 Received: from bfoster.bfoster ([10.18.41.237]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8UJLPge008268 for ; Tue, 30 Sep 2014 15:21:25 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id A8F5B120064; Tue, 30 Sep 2014 15:21:23 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH] xfs: check for inode size overflow in xfs_new_eof() Date: Tue, 30 Sep 2014 15:21:23 -0400 X-ASG-Orig-Subj: [PATCH] xfs: check for inode size overflow in xfs_new_eof() Message-Id: <1412104883-6151-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1412104887 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 If we write to the maximum file offset (2^63-2), XFS fails to log the inode size update when the page is flushed. For example: $ xfs_io -fc "pwrite `echo "2^63-1-1" | bc` 1" /mnt/file wrote 1/1 bytes at offset 9223372036854775806 1.000000 bytes, 1 ops; 0.0000 sec (22.711 KiB/sec and 23255.8140 ops/sec) $ stat -c %s /mnt/file 9223372036854775807 $ umount /mnt ; mount /mnt/ $ stat -c %s /mnt/file 0 This occurs because XFS calculates the new file size as io_offset + io_size, I/O occurs in block sized requests, and the maximum supported file size is not block aligned. Therefore, a write to the max allowable offset on a 4k blocksize fs results in a write of size 4k to offset 2^63-4096 (e.g., equivalent to round_down(2^63-1, 4096), or IOW the offset of the block that contains the max file size). The offset plus size calculation (2^63 - 4096 + 4096 == 2^63) overflows the signed 64-bit variable which goes negative and causes the > comparison to the on-disk inode size to fail. This returns 0 from xfs_new_eof() and results in no change to the inode on-disk. Update xfs_new_eof() to explicitly detect overflow of the local calculation and use the VFS inode size in this scenario. The VFS inode size is capped to the maximum and thus XFS writes the correct inode size to disk. Signed-off-by: Brian Foster --- Hi all, This was also discovered while playing around with xfs/071, though it doesn't cause a failure. FWIW, I started off fixing this by converting xfs_new_eof() to use xfs_ufsize_t. That worked, but this seemed more explicit. Brian fs/xfs/xfs_inode.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index c10e3fa..9af2882 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -102,7 +102,7 @@ xfs_new_eof(struct xfs_inode *ip, xfs_fsize_t new_size) { xfs_fsize_t i_size = i_size_read(VFS_I(ip)); - if (new_size > i_size) + if (new_size > i_size || new_size < 0) new_size = i_size; return new_size > ip->i_d.di_size ? new_size : 0; } -- 1.8.3.1 From david@fromorbit.com Tue Sep 30 15:00:59 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A87867F8A for ; Tue, 30 Sep 2014 15:00:59 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 884F830405F for ; Tue, 30 Sep 2014 13:00:58 -0700 (PDT) X-ASG-Debug-ID: 1412107252-04cb6c50e660b260001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id dffXEx3gw4oRZKvN for ; Tue, 30 Sep 2014 13:00:52 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Au8vAJALK1R5LDjwPGdsb2JhbABggw5TV4IyhQeuXAwBAQEBAQEGk3eBZYVqBAICgQ4XAQYBAQEBODmEBAEBBDocGBsIAxgJJQ8FJQMHLYg9vmcYhXqKExaENQWWJYcJgWaYACsvgkoBAQE Received: from ppp121-44-56-240.lns20.syd6.internode.on.net (HELO dastard) ([121.44.56.240]) by ipmail06.adl6.internode.on.net with ESMTP; 01 Oct 2014 05:30:47 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XZ3bK-000763-9N for xfs@oss.sgi.com; Wed, 01 Oct 2014 06:00:46 +1000 Date: Wed, 1 Oct 2014 06:00:46 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: Re: Why not move xfs infra-structure to "public" services Message-ID: <20140930200046.GQ4758@dastard> X-ASG-Orig-Subj: Re: Why not move xfs infra-structure to "public" services References: <20140930141857.GA2053@localhost.localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140930141857.GA2053@localhost.localdomain> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1412107252 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10074 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 30, 2014 at 11:18:57AM -0300, Carlos Maiolino wrote: > Hi guys, > > I'm sorry for this kind of "fancy" question from my side, but I'm wondering why > xfs project infra-structure (mailing list, git trees), does not use the "usual > public" services. I mean, does anyone thought about moving xfs mailing list to > vger.kernel.org, and the git trees to git.kernel.org? I'm already using git.kernel.org for my master XFS trees. The ones on oss.sgi.com are simply now downstream mirrors. There's still a few things I need to organise (e.g. where release tarballs are put) before we make the kernel.org trees the official source of XFS source code. We already have a linux-xfs@vger.kernel.org mailing list - we just don't use it. Again, more organisation stuff to do to switch over (i.e. forwarding from xfs@oss.sgi.com to the vger list) and then updating documentation everywhere and getting people to start using it. Cheers, Dave. -- Dave Chinner david@fromorbit.com From cmaiolino@redhat.com Tue Sep 30 15:13:08 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 5B1B47F90 for ; Tue, 30 Sep 2014 15:13:08 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4975B30405F for ; Tue, 30 Sep 2014 13:13:05 -0700 (PDT) X-ASG-Debug-ID: 1412107980-04cbb07302699580001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id T9ZBNAZmQGP5lLyj (version=TLSv1 cipher=AES256-SHA bits=256 verify=NO) for ; Tue, 30 Sep 2014 13:13:00 -0700 (PDT) X-Barracuda-Envelope-From: cmaiolino@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s8UKCpp4008346 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 30 Sep 2014 16:12:51 -0400 Received: from localhost.localdomain (ovpn-113-60.phx2.redhat.com [10.3.113.60]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s8UKCkmu020616 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO); Tue, 30 Sep 2014 16:12:48 -0400 Date: Tue, 30 Sep 2014 17:12:45 -0300 From: Carlos Maiolino To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: Why not move xfs infra-structure to "public" services Message-ID: <20140930201245.GA3806@localhost.localdomain> X-ASG-Orig-Subj: Re: Why not move xfs infra-structure to "public" services Mail-Followup-To: Dave Chinner , xfs@oss.sgi.com References: <20140930141857.GA2053@localhost.localdomain> <20140930200046.GQ4758@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140930200046.GQ4758@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1412107980 X-Barracuda-Encrypted: AES256-SHA X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Thanks dave. Can I use your kernel.org tree from now then? Regarding the mailing list, let me know if you need some help On Wed, Oct 01, 2014 at 06:00:46AM +1000, Dave Chinner wrote: > On Tue, Sep 30, 2014 at 11:18:57AM -0300, Carlos Maiolino wrote: > > Hi guys, > > > > I'm sorry for this kind of "fancy" question from my side, but I'm wondering why > > xfs project infra-structure (mailing list, git trees), does not use the "usual > > public" services. I mean, does anyone thought about moving xfs mailing list to > > vger.kernel.org, and the git trees to git.kernel.org? > > I'm already using git.kernel.org for my master XFS trees. The ones > on oss.sgi.com are simply now downstream mirrors. There's still a > few things I need to organise (e.g. where release tarballs are put) > before we make the kernel.org trees the official source of XFS > source code. > > We already have a linux-xfs@vger.kernel.org mailing list - we just > don't use it. Again, more organisation stuff to do to switch over > (i.e. forwarding from xfs@oss.sgi.com to the vger list) and then > updating documentation everywhere and getting people to start using > it. > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs -- Carlos From david@fromorbit.com Tue Sep 30 15:42:46 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 2F6247F94 for ; Tue, 30 Sep 2014 15:42:46 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id AEDB0AC009 for ; Tue, 30 Sep 2014 13:42:45 -0700 (PDT) X-ASG-Debug-ID: 1412109763-04cb6c50e560d100001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id yHrqtn4fqAnyZNHr for ; Tue, 30 Sep 2014 13:42:43 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AkYwALsUK1R5LDjwPGdsb2JhbABggw5TV4IyhQeGLKgwDAEBAQEBAQaTd4FlhWoEAgKBDhcBBgEBAQE4OYQEAQEEOhwzCAMYCSUPBSUDBy2IPb5zGIV6ihMWhDUFliWHCYFmmAArL4JKAQEB Received: from ppp121-44-56-240.lns20.syd6.internode.on.net (HELO dastard) ([121.44.56.240]) by ipmail06.adl6.internode.on.net with ESMTP; 01 Oct 2014 06:12:43 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XZ4Ft-0007Dz-D9 for xfs@oss.sgi.com; Wed, 01 Oct 2014 06:42:41 +1000 Date: Wed, 1 Oct 2014 06:42:41 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: Re: Why not move xfs infra-structure to "public" services Message-ID: <20140930204241.GR4758@dastard> X-ASG-Orig-Subj: Re: Why not move xfs infra-structure to "public" services References: <20140930141857.GA2053@localhost.localdomain> <20140930200046.GQ4758@dastard> <20140930201245.GA3806@localhost.localdomain> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140930201245.GA3806@localhost.localdomain> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1412109763 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10074 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 30, 2014 at 05:12:45PM -0300, Carlos Maiolino wrote: > Thanks dave. > > Can I use your kernel.org tree from now then? Sure - it's already the tree that is included into the linux-next builds and the tree I ask linus to pull from... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Tue Sep 30 17:13:58 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CDBF67F86 for ; Tue, 30 Sep 2014 17:13:57 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4DEC4AC006 for ; Tue, 30 Sep 2014 15:13:54 -0700 (PDT) X-ASG-Debug-ID: 1412115228-04cb6c50e66108d0001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id DIraZkiRKGAmTDuQ for ; Tue, 30 Sep 2014 15:13:49 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AjNXAEcqK1R5LDjwPGdsb2JhbABggw6IY65oAQUGlVyFagICAQECgRMXAQYBAQEBODmEAwEBAQMBJxMcKAsIAxUDCSUPBSUDBy2INge+YRiFeooTFoQ1BZ0umWYrL4JKAQEB Received: from ppp121-44-56-240.lns20.syd6.internode.on.net (HELO dastard) ([121.44.56.240]) by ipmail06.adl6.internode.on.net with ESMTP; 01 Oct 2014 07:43:08 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XZ5fN-0007de-HY for xfs@oss.sgi.com; Wed, 01 Oct 2014 08:13:05 +1000 Date: Wed, 1 Oct 2014 08:13:05 +1000 From: Dave Chinner To: xfs@oss.sgi.com Subject: Re: [PATCH 2/2] xfs: only set extent size hint when asked Message-ID: <20140930221305.GS4758@dastard> X-ASG-Orig-Subj: Re: [PATCH 2/2] xfs: only set extent size hint when asked References: <1412041565-18873-1-git-send-email-david@fromorbit.com> <1412041565-18873-3-git-send-email-david@fromorbit.com> <20140930055829.GB15186@teal.hq.k1024.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20140930055829.GB15186@teal.hq.k1024.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1412115228 X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10076 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 30, 2014 at 07:58:29AM +0200, Iustin Pop wrote: > On Tue, Sep 30, 2014 at 11:46:05AM +1000, Dave Chinner wrote: > > From: Dave Chinner > > > > Currently the extent size hint is set unconditionally in > > xfs_ioctl_setattr(), even when the FSX_EXTSIZE flag is not set. This > > means we can set values from uninitialised stack variables. Hence > > only set the extent size hint from userspace when both the mask > > falg is set and the inode has the XFS_DIFLAG_EXTSIZE flag set to > > indicate that we should have an extent size hint set on the inode. > > > > Signed-off-by: Dave Chinner > > --- > > fs/xfs/xfs_ioctl.c | 16 ++++++++++++++-- > > 1 file changed, 14 insertions(+), 2 deletions(-) > > > > diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c > > index 87c3bd1..24c926b 100644 > > --- a/fs/xfs/xfs_ioctl.c > > +++ b/fs/xfs/xfs_ioctl.c > > @@ -1231,13 +1231,25 @@ xfs_ioctl_setattr( > > > > } > > > > - if (mask & FSX_EXTSIZE) > > - ip->i_d.di_extsize = fa->fsx_extsize >> mp->m_sb.sb_blocklog; > > if (mask & FSX_XFLAGS) { > > xfs_set_diflags(ip, fa->fsx_xflags); > > xfs_diflags_to_linux(ip); > > } > > > > + /* > > + * Only set the extent size hint if we've already determined that the > > + * extent size hint should be set on the inode. If no extent size flags > > + * are set on the inode then unconditionally clear the extent size hint. > > + */ > > + if (mask & FSX_EXTSIZE) { > > + int extsize = 0; > > + > > + if (ip->i_d.di_flags & > > + (XFS_DIFLAG_EXTSIZE | XFS_DIFLAG_EXTSZINHERIT)) > > + extsize = fa->fsx_extsize >> mp->m_sb.sb_blocklog; > > + ip->i_d.di_extsize = extsize; > > Quick question: this sounds sane, but it will have the following effect > (if I understand things correctly): updating other flags on the inode > (e.g. XFS_XFLAG_NOATIME) might change the recorded extent size. That's no different to what happens before this patch. As I said in the cover note, I'm not attempting to fix those problem with these patches. Besides, you're still thinking that you can just call XFS_IOC_SETXATTR without a preceeding XFS_IOC_GETXATTR call. That's just broken - if applications use getxattr/setxattr correctly then this isn't an issue. i.e. do this: ioctl(XFS_IOC_GETXATTR, &fsx) fsx.fsx_xflags |= XFS_XFLAG_NOATIME; ioctl(XFS_IOC_SETXATTR, &fsx) and the problem you allude to does not occur because it will set the extent size to the same value as it currently has. > True, it > will correct the size if not appropriate and it will have a noop impact, > but still it will be an unrelated inode change. Would it make sense to > document this in the xfsctl man page then? There's no point in documenting what *might* happen if you abuse the interface in ways it was not intended to be used. Cheers, Dave. -- Dave Chinner david@fromorbit.com From robin.listas@gmail.com Tue Sep 30 17:27:47 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B76637F6F for ; Tue, 30 Sep 2014 17:27:47 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 35546AC00C for ; Tue, 30 Sep 2014 15:27:47 -0700 (PDT) X-ASG-Debug-ID: 1412116055-04cb6c50e6611090001-NocioJ Received: from mail-wi0-f171.google.com (mail-wi0-f171.google.com [209.85.212.171]) by cuda.sgi.com with ESMTP id dgZKAhIiuqmiixZm (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Tue, 30 Sep 2014 15:27:36 -0700 (PDT) X-Barracuda-Envelope-From: robin.listas@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.212.171 X-Barracuda-IPDD: Level1 [gmail.com/209.85.212.171] Received: by mail-wi0-f171.google.com with SMTP id ho1so110586wib.4 for ; Tue, 30 Sep 2014 15:27:35 -0700 (PDT) X-Barracuda-IPDD: Level1 [gmail.com/209.85.212.171] X-Barracuda-IPDD: Level1 [gmail.com/209.85.212.171] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:date:from:to:subject:in-reply-to:message-id:references :user-agent:mime-version:content-type; bh=zauITOLEHszyYZrab+Y8tFiYDNkaXJHLvxckV/Vp0OM=; b=W6M5uNjvnONvv0CNOMf++DvbshrDrsM2I16bQKwKyYVRFEim1snpfljQ07hyK2/wGK tFFse4O59toY0/fRGjoEw0wQhwS0rJBXYM6OiFmEcH7jv208EyScNy+SZJAfI4B2Eidl uI8Jod0as8k3z5jTFw0uaOiu2D3wcvyVlNqVgnCCxsXrV33CeCh8nh3tMZHQd7DFNrPp qZUjEGroqY6Jy67r57uNofTpr+jvJ7r12VfvM1HKNy3MZNgaHL7D4cPpK/cbzYYZ7lXk 23ca43J7t64OyBJOR9AIEQtKFZ7kIVhPHFo68Zp5j+cTajjQrtCeTtqDH5JHiwqJKK3t px8g== X-Received: by 10.180.206.230 with SMTP id lr6mr9246622wic.82.1412116055336; Tue, 30 Sep 2014 15:27:35 -0700 (PDT) Received: from minas-tirith.valinor (177.Red-79-159-63.staticIP.rima-tde.net. [79.159.63.177]) by mx.google.com with ESMTPSA id ll20sm16557825wic.14.2014.09.30.15.27.34 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 Sep 2014 15:27:34 -0700 (PDT) Sender: Carlos Robinson Received: from localhost (localhost [127.0.0.1]) by minas-tirith.valinor (Postfix) with ESMTP id 68289182453 for ; Wed, 1 Oct 2014 00:27:30 +0200 (CEST) Date: Wed, 1 Oct 2014 00:27:20 +0200 (CEST) From: "Carlos E. R." X-X-Sender: cer@minas-tirith.valinor To: XFS mailing list Subject: Happened again, 20140930 -- Got "Internal error XFS_WANT_CORRUPTED_GOTO". Filesystem needs reformatting to correct issue. In-Reply-To: X-ASG-Orig-Subj: Happened again, 20140930 -- Got "Internal error XFS_WANT_CORRUPTED_GOTO". Filesystem needs reformatting to correct issue. Message-ID: References: User-Agent: Alpine 2.11 (LSU 23 2013-08-11) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; format=flowed; charset=US-ASCII X-Barracuda-Connect: mail-wi0-f171.google.com[209.85.212.171] X-Barracuda-Start-Time: 1412116056 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10077 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 > Subject: Subject : Happened again, > 20140811 -- Got "Internal error XFS_WANT_CORRUPTED_GOTO". Filesystem needs > reformatting to correct issue. > Date: Mon, 11 Aug 2014 16:23:01 +0200 (CEST) > Happened again, I'm on middle of recovery procedures, and using my laptop > to post. And again. Well, after I recover the system I'm going to migrate my /home to a small ext4 partition, leaving Documents and the big directories in the current xfs home, renamed to something else. I hope this way to avoid the crashes and corruption on restore from hibernation. SUSE and openSUSE (12 and 13.2) are switching to use, on new installs by default, btrfs for their root filesystem, and xfs for home. I hope that this will cause more crashes on laptops on return from hibernation, producing more reports, and finally solving the root cause of this. Or perhaps it does not happen on 13.2, and I'm the only one left having the issue... Anyway, as I'm using 13.1, and will be for some time, the solution for me is to move the core of /home to ext4, at least temporarily. If someone wants me to get some data from the partition, I'm willing. I made a full 'dd' of it before attempting mount or repair on it (still pending), it will be possible for some days or more. Time permitting. :-) - -- Cheers Carlos E. R. (from 13.1 x86_64 "Bottle" (Minas Tirith)) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iF4EAREIAAYFAlQrLlIACgkQja8UbcUWM1z5nAD8DSoMv0LXUZQSbDcuVpmpH96g zSnNcVKFRuZdBp6WY6gA/j9LzOmEy0a5MD5h++wnkKLk2z9RsnuJVc6PYW4RLyG8 =rZgI -----END PGP SIGNATURE----- From david@fromorbit.com Tue Sep 30 19:45:24 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 4019D7F88 for ; Tue, 30 Sep 2014 19:45:24 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2F128304062 for ; Tue, 30 Sep 2014 17:45:21 -0700 (PDT) X-ASG-Debug-ID: 1412124318-04cbb073016a3180001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id vsZ3MbeenD6TMUsn for ; Tue, 30 Sep 2014 17:45:19 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ar42AGxNK1R5LDjwPGdsb2JhbABggw6IY65rAQuVXIVqBAICgQwXAQYBAQEBODmEAwEBAQQ6HCMQCAMUAwEJGgsPBSUDBwwOE4g9vmQYGIV6hk+DPQcGhEUFnS6MSosTDhAWgVUrL4JKAQEB Received: from ppp121-44-56-240.lns20.syd6.internode.on.net (HELO dastard) ([121.44.56.240]) by ipmail06.adl6.internode.on.net with ESMTP; 01 Oct 2014 10:15:17 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1XZ82c-0007xM-Pi; Wed, 01 Oct 2014 10:45:14 +1000 Date: Wed, 1 Oct 2014 10:45:14 +1000 From: Dave Chinner To: "Carlos E. R." Cc: XFS mailing list Subject: Re: Happened again, 20140930 -- Got "Internal error XFS_WANT_CORRUPTED_GOTO". Filesystem needs reformatting to correct issue. Message-ID: <20141001004514.GH24490@dastard> X-ASG-Orig-Subj: Re: Happened again, 20140930 -- Got "Internal error XFS_WANT_CORRUPTED_GOTO". Filesystem needs reformatting to correct issue. References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1412124318 X-Barracuda-URL: http://192.48.176.25:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10080 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header On Wed, Oct 01, 2014 at 12:27:20AM +0200, Carlos E. R. wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA256 > > > > >Subject: Subject : Happened again, > > 20140811 -- Got "Internal error XFS_WANT_CORRUPTED_GOTO". Filesystem needs > > reformatting to correct issue. > >Date: Mon, 11 Aug 2014 16:23:01 +0200 (CEST) > > >Happened again, I'm on middle of recovery procedures, and using my laptop > >to post. > > And again. We've already got the fix in our upstream repository: 8018ec0 xfs: mark all internal workqueues as freezable It's currently in linux-next, queued for the next merge window. You shoul dprobably talk to your distro about getting it backported. Cheers, Dave. -- Dave Chinner david@fromorbit.com From robin.listas@gmail.com Tue Sep 30 21:48:51 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 7E2F97F7C for ; Tue, 30 Sep 2014 21:48:51 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id F1CE2AC00D for ; Tue, 30 Sep 2014 19:48:50 -0700 (PDT) X-ASG-Debug-ID: 1412131725-04cb6c50e7618cb0001-NocioJ Received: from mail-wi0-f175.google.com (mail-wi0-f175.google.com [209.85.212.175]) by cuda.sgi.com with ESMTP id 51S6Pa4NMwBbenFz (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Tue, 30 Sep 2014 19:48:46 -0700 (PDT) X-Barracuda-Envelope-From: robin.listas@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.212.175 X-Barracuda-IPDD: Level1 [gmail.com/209.85.212.175] Received: by mail-wi0-f175.google.com with SMTP id d1so472859wiv.14 for ; Tue, 30 Sep 2014 19:48:45 -0700 (PDT) X-Barracuda-IPDD: Level1 [gmail.com/209.85.212.175] X-Barracuda-IPDD: Level1 [gmail.com/209.85.212.175] DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:message-id:date:from:user-agent:mime-version:to:subject :references:in-reply-to:content-type:content-transfer-encoding; bh=/VdVxZQapffUKRslKc2VQyG56T+UKWLNzL0TkFj73+8=; b=pZFyhA9nl6mdLwmslcjpun61Vc+5i0nNeSnjthdpUOf8/TrjtcRY6FIHBViS0jZGs9 fyhv53KNKXFspV+O0hRBtRdd5RdFzIwO57VVN16tOrUYkmZ4VBYqIcWwWRyjztNwyIO2 Y7/R1IWfUgm7hfKjhLTr9Q2EiYMAxq6j1mWM+/ZrpGKo/ctzArZRWg/uOkKdLrfS9+e/ xNHBG6B/BHidAOjLUwi7ZwZqR/I5XYaLUTcGh1gTwECyMAGSmSQrP7MsxuvQu62wbv7U 8z7Sy6fc89Iq/Gr/CrMg6l2BGSs1Ww3Xiy66fG7QWgfeJpPdC+kgFWFUl0sjGPm6F0Rx d4WA== X-Received: by 10.180.84.193 with SMTP id b1mr10629209wiz.25.1412131725435; Tue, 30 Sep 2014 19:48:45 -0700 (PDT) Received: from [192.168.1.14] (177.Red-79-159-63.staticIP.rima-tde.net. [79.159.63.177]) by mx.google.com with ESMTPSA id ul1sm21090988wjc.9.2014.09.30.19.48.44 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 Sep 2014 19:48:44 -0700 (PDT) Sender: Carlos Robinson Message-ID: <542B6B8A.2060309@opensuse.org> Date: Wed, 01 Oct 2014 04:48:42 +0200 From: "Carlos E. R." User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.0 MIME-Version: 1.0 To: XFS mailing list Subject: Re: Happened again, 20140930 -- Got "Internal error XFS_WANT_CORRUPTED_GOTO". Filesystem needs reformatting to correct issue. References: <20141001004514.GH24490@dastard> X-ASG-Orig-Subj: Re: Happened again, 20140930 -- Got "Internal error XFS_WANT_CORRUPTED_GOTO". Filesystem needs reformatting to correct issue. In-Reply-To: <20141001004514.GH24490@dastard> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail-wi0-f175.google.com[209.85.212.175] X-Barracuda-Start-Time: 1412131726 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: http://192.48.176.15:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10082 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On 2014-10-01 02:45, Dave Chinner wrote: > On Wed, Oct 01, 2014 at 12:27:20AM +0200, Carlos E. R. wrote: > We've already got the fix in our upstream repository: > > 8018ec0 xfs: mark all internal workqueues as freezable > > It's currently in linux-next, queued for the next merge window. You > shoul dprobably talk to your distro about getting it backported. Wow, thanks. I'll tell them. Question: where does it apply, kernel, xfsprogs? They will know, but I don't, and I need that info for the bugzilla "component" field ;-) -- Cheers / Saludos, Carlos E. R. (from 13.1 x86_64 "Bottle" (Elessar)) From sandeen@sandeen.net Tue Sep 30 22:05:01 2014 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B08517F7C for ; Tue, 30 Sep 2014 22:05:01 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5B827AC00A for ; Tue, 30 Sep 2014 20:05:01 -0700 (PDT) X-ASG-Debug-ID: 1412132694-04bdf003a269cb10001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id 5thb7JkyvNnlo42x for ; Tue, 30 Sep 2014 20:04:54 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id E6FCF6567FBA; Tue, 30 Sep 2014 22:04:53 -0500 (CDT) Message-ID: <542B6F55.3090409@sandeen.net> Date: Tue, 30 Sep 2014 22:04:53 -0500 From: Eric Sandeen MIME-Version: 1.0 To: "Carlos E. R." , XFS mailing list Subject: Re: Happened again, 20140930 -- Got "Internal error XFS_WANT_CORRUPTED_GOTO". Filesystem needs reformatting to correct issue. References: <20141001004514.GH24490@dastard> <542B6B8A.2060309@opensuse.org> X-ASG-Orig-Subj: Re: Happened again, 20140930 -- Got "Internal error XFS_WANT_CORRUPTED_GOTO". Filesystem needs reformatting to correct issue. In-Reply-To: <542B6B8A.2060309@opensuse.org> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1412132694 X-Barracuda-URL: http://192.48.157.11:80/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.10083 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 9/30/14 9:48 PM, Carlos E. R. wrote: > On 2014-10-01 02:45, Dave Chinner wrote: >> On Wed, Oct 01, 2014 at 12:27:20AM +0200, Carlos E. R. wrote: > >> We've already got the fix in our upstream repository: >> >> 8018ec0 xfs: mark all internal workqueues as freezable >> >> It's currently in linux-next, queued for the next merge window. You >> shoul dprobably talk to your distro about getting it backported. > > Wow, thanks. I'll tell them. > > Question: where does it apply, kernel, xfsprogs? They will know, but I don't, and I need that info for the bugzilla "component" field ;-) > kernel -Eric