From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1a8dVe-00031F-QQ for mharc-grub-devel@gnu.org; Mon, 14 Dec 2015 19:30:30 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49701) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a8dVb-00030x-Bm for grub-devel@gnu.org; Mon, 14 Dec 2015 19:30:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a8dVX-0006K8-3E for grub-devel@gnu.org; Mon, 14 Dec 2015 19:30:27 -0500 Received: from mail.kernel.org ([198.145.29.136]:40447) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a8dVW-0006K0-Ra for grub-devel@gnu.org; Mon, 14 Dec 2015 19:30:23 -0500 Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7594F20351; Tue, 15 Dec 2015 00:30:20 +0000 (UTC) Received: from localhost (107-1-141-74-ip-static.hfc.comcastbusiness.net [107.1.141.74]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 6E152202BE; Tue, 15 Dec 2015 00:30:19 +0000 (UTC) Date: Mon, 14 Dec 2015 16:30:18 -0800 From: Jaegeuk Kim To: Andrei Borzenkov Subject: Re: [f2fs-dev] [PATCH v3] F2FS support Message-ID: <20151215003018.GC48918@jaegeuk.local> References: <1427185140-41120-1-git-send-email-jaegeuk@kernel.org> <20150403224908.GB25673@jaegeuk-mac02.mot.com> <20151119212824.GA11666@jaegeuk.local> <566E7DAA.4010202@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <566E7DAA.4010202@gmail.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Virus-Scanned: ClamAV using ClamSMTP Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 198.145.29.136 Cc: The development of GNU GRUB , linux-f2fs-devel@lists.sourceforge.net X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Dec 2015 00:30:29 -0000 Thank you for the review. On Mon, Dec 14, 2015 at 11:28:26AM +0300, Andrei Borzenkov wrote: > 20.11.2015 00:28, Jaegeuk Kim =D0=BF=D0=B8=D1=88=D0=B5=D1=82: > > Hello, > >=20 > > Change log from v2: > > o Enhance the code quality suggested by Andrei > >=20 > > Sorry for the long delay. > > Could you please check this patch? > >=20 > > Thank you so much, > >=20 >=20 > Thank you for continuing to work on it! >=20 > ... >=20 > > + > > +static inline int > > +grub_generic_test_bit (int nr, const grub_uint32_t *addr) > > +{ > > + return 1UL & (addr[nr / 32] >> (nr & 31)); > > +} > > + >=20 > As already discussed this code is wrong on big-endian platform. On-disk > bitmap is little-endian and kernel explicitly uses test_bit_le() here. Got it. >=20 > > +static inline char * > > +__inline_addr (struct grub_f2fs_inode *inode) > > +{ > > + return (char *)&inode->i_addr[1]; > > +} > > + > > +static inline grub_uint64_t > > +grub_f2fs_file_size (struct grub_f2fs_inode *inode) > > +{ > > + return grub_le_to_cpu64 (inode->i_size); > > +} > > + > > +static inline grub_uint32_t > > +__start_cp_addr (struct grub_f2fs_data *data) > > +{ > > + struct grub_f2fs_checkpoint *ckpt =3D &data->ckpt; > > + grub_uint64_t ckpt_version =3D grub_le_to_cpu64 (ckpt->checkpoint_= ver); > > + grub_uint32_t start_addr =3D data->cp_blkaddr; > > + > > + if (!(ckpt_version & 1)) >=20 > This can use grub_cpu_to_le64_compile_time (1) Done. >=20 > ... >=20 > > +static inline int > > +grub_f2fs_test_bit (grub_uint32_t nr, const char *p) > > +{ > > + int mask; > > + > > + p +=3D (nr >> 3); > > + mask =3D 1 << (7 - (nr & 0x07)); > > + return (mask & *p) !=3D 0; >=20 > This is really just "return mask & *p". Okay. >=20 > > +} > > + > > +static int > > +grub_f2fs_sanity_check_sb (struct grub_f2fs_superblock *sb) > > +{ > > + grub_uint32_t log_sectorsize, log_sectors_per_block; > > + > > + if (sb->magic !=3D grub_cpu_to_le32_compile_time (F2FS_SUPER_MAGIC= )) > > + return -1; > > + > > + if (sb->log_blocksize !=3D grub_cpu_to_le32_compile_time (F2FS_BLK= _BITS)) > > + return -1; > > + > > + log_sectorsize =3D grub_le_to_cpu32 (sb->log_sectorsize); > > + log_sectors_per_block =3D grub_le_to_cpu32 (sb->log_sectors_per_bl= ock); > > + > > + if (log_sectorsize > F2FS_MAX_LOG_SECTOR_SIZE) > > + return -1; > > + > > + if (log_sectorsize < F2FS_MIN_LOG_SECTOR_SIZE) > > + return -1; > > + > > + if (log_sectors_per_block + log_sectorsize !=3D F2FS_MAX_LOG_SECTO= R_SIZE) >=20 > This sounds like it should actually be F2FS_BLK_BITS; at least assuming > that F2FS_MAX_LOG_SECTOR_SIZE may differ from F2FS_BLK_BITS. >=20 Yup. In order to avoid confusion, I removed F2FS_MAX_LOG_SECTOR_SIZE. > ... >=20 > > + > > +static grub_ssize_t > > +grub_f2fs_read_file (grub_fshelp_node_t node, > > + grub_disk_read_hook_t read_hook, void *read_hook_data, > > + grub_off_t pos, grub_size_t len, char *buf) > > +{ > > + struct grub_f2fs_inode *inode =3D &node->inode.i; > > + grub_off_t filesize =3D grub_f2fs_file_size (inode); > > + char *inline_addr =3D __inline_addr (inode); > > + > > + if (inode->i_inline & F2FS_INLINE_DATA) > > + { > > + if (pos > filesize || filesize > MAX_INLINE_DATA) > > + { > > + grub_error (GRUB_ERR_BAD_FS, "corrupted inline_data: need = fsck"); >=20 >=20 > Sorry for confusion, my fault. pos > filesize was OK, but filesize > > MAX_INLINE_DATA not. If filesize is over MAX_INLINE_DATA, this file is corrupted as well. It will cause boundary violation during memcpy below. >=20 > ... >=20 > > + > > +/* TODO: mkfs.f2fs stores label in a wrong way. Should be fixed. */ > > +static void > > +grub_f2fs_unicode_to_ascii (grub_uint8_t *out_buf, grub_uint16_t *in= _buf) > > +{ > > + grub_uint16_t *pchTempPtr =3D in_buf; > > + grub_uint8_t *pwTempPtr =3D out_buf; > > + > > + while (*pchTempPtr !=3D '\0') > > + { > > + *pwTempPtr =3D (grub_uint8_t) *pchTempPtr; > > + pchTempPtr++; > > + pwTempPtr++; > > + } > > + *pwTempPtr =3D '\0'; > > + return; > > +} >=20 > Sorry, I do not see how it can work on both big and little endian > platforms. What byte order is used for on-disk label? Why cannot you us= e > grub_utf16_to_utf8 as I asked last time? >=20 > Also please add bundary check, do not rely on correct content. Got it. I refactored this here and in f2fs-tools as well. Could you check v4? Thanks, >=20 >=20 >=20 > -----------------------------------------------------------------------= ------- > _______________________________________________ > Linux-f2fs-devel mailing list > Linux-f2fs-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jaegeuk Kim Subject: Re: [PATCH v3] F2FS support Date: Mon, 14 Dec 2015 16:30:18 -0800 Message-ID: <20151215003018.GC48918@jaegeuk.local> References: <1427185140-41120-1-git-send-email-jaegeuk@kernel.org> <20150403224908.GB25673@jaegeuk-mac02.mot.com> <20151119212824.GA11666@jaegeuk.local> <566E7DAA.4010202@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from sog-mx-3.v43.ch3.sourceforge.com ([172.29.43.193] helo=mx.sourceforge.net) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1a8dVc-0004cN-N3 for linux-f2fs-devel@lists.sourceforge.net; Tue, 15 Dec 2015 00:30:28 +0000 Received: from mail.kernel.org ([198.145.29.136]) by sog-mx-3.v43.ch3.sourceforge.com with esmtp (Exim 4.76) id 1a8dVa-0002Yy-Tj for linux-f2fs-devel@lists.sourceforge.net; Tue, 15 Dec 2015 00:30:28 +0000 Content-Disposition: inline In-Reply-To: <566E7DAA.4010202@gmail.com> List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linux-f2fs-devel-bounces@lists.sourceforge.net To: Andrei Borzenkov Cc: The development of GNU GRUB , linux-f2fs-devel@lists.sourceforge.net VGhhbmsgeW91IGZvciB0aGUgcmV2aWV3LgoKT24gTW9uLCBEZWMgMTQsIDIwMTUgYXQgMTE6Mjg6 MjZBTSArMDMwMCwgQW5kcmVpIEJvcnplbmtvdiB3cm90ZToKPiAyMC4xMS4yMDE1IDAwOjI4LCBK YWVnZXVrIEtpbSDQv9C40YjQtdGCOgo+ID4gSGVsbG8sCj4gPiAKPiA+IENoYW5nZSBsb2cgZnJv bSB2MjoKPiA+ICBvIEVuaGFuY2UgdGhlIGNvZGUgcXVhbGl0eSBzdWdnZXN0ZWQgYnkgQW5kcmVp Cj4gPiAKPiA+IFNvcnJ5IGZvciB0aGUgbG9uZyBkZWxheS4KPiA+IENvdWxkIHlvdSBwbGVhc2Ug Y2hlY2sgdGhpcyBwYXRjaD8KPiA+IAo+ID4gVGhhbmsgeW91IHNvIG11Y2gsCj4gPiAKPiAKPiBU aGFuayB5b3UgZm9yIGNvbnRpbnVpbmcgdG8gd29yayBvbiBpdCEKPiAKPiAuLi4KPiAKPiA+ICsK PiA+ICtzdGF0aWMgaW5saW5lIGludAo+ID4gK2dydWJfZ2VuZXJpY190ZXN0X2JpdCAoaW50IG5y LCBjb25zdCBncnViX3VpbnQzMl90ICphZGRyKQo+ID4gK3sKPiA+ICsgIHJldHVybiAxVUwgJiAo YWRkcltuciAvIDMyXSA+PiAobnIgJiAzMSkpOwo+ID4gK30KPiA+ICsKPiAKPiBBcyBhbHJlYWR5 IGRpc2N1c3NlZCB0aGlzIGNvZGUgaXMgd3Jvbmcgb24gYmlnLWVuZGlhbiBwbGF0Zm9ybS4gT24t ZGlzawo+IGJpdG1hcCBpcyBsaXR0bGUtZW5kaWFuIGFuZCBrZXJuZWwgZXhwbGljaXRseSB1c2Vz IHRlc3RfYml0X2xlKCkgaGVyZS4KCkdvdCBpdC4KCj4gCj4gPiArc3RhdGljIGlubGluZSBjaGFy ICoKPiA+ICtfX2lubGluZV9hZGRyIChzdHJ1Y3QgZ3J1Yl9mMmZzX2lub2RlICppbm9kZSkKPiA+ ICt7Cj4gPiArICByZXR1cm4gKGNoYXIgKikmaW5vZGUtPmlfYWRkclsxXTsKPiA+ICt9Cj4gPiAr Cj4gPiArc3RhdGljIGlubGluZSBncnViX3VpbnQ2NF90Cj4gPiArZ3J1Yl9mMmZzX2ZpbGVfc2l6 ZSAoc3RydWN0IGdydWJfZjJmc19pbm9kZSAqaW5vZGUpCj4gPiArewo+ID4gKyAgcmV0dXJuIGdy dWJfbGVfdG9fY3B1NjQgKGlub2RlLT5pX3NpemUpOwo+ID4gK30KPiA+ICsKPiA+ICtzdGF0aWMg aW5saW5lIGdydWJfdWludDMyX3QKPiA+ICtfX3N0YXJ0X2NwX2FkZHIgKHN0cnVjdCBncnViX2Yy ZnNfZGF0YSAqZGF0YSkKPiA+ICt7Cj4gPiArICBzdHJ1Y3QgZ3J1Yl9mMmZzX2NoZWNrcG9pbnQg KmNrcHQgPSAmZGF0YS0+Y2twdDsKPiA+ICsgIGdydWJfdWludDY0X3QgY2twdF92ZXJzaW9uID0g Z3J1Yl9sZV90b19jcHU2NCAoY2twdC0+Y2hlY2twb2ludF92ZXIpOwo+ID4gKyAgZ3J1Yl91aW50 MzJfdCBzdGFydF9hZGRyID0gZGF0YS0+Y3BfYmxrYWRkcjsKPiA+ICsKPiA+ICsgIGlmICghKGNr cHRfdmVyc2lvbiAmIDEpKQo+IAo+IFRoaXMgY2FuIHVzZSBncnViX2NwdV90b19sZTY0X2NvbXBp bGVfdGltZSAoMSkKCkRvbmUuCgo+IAo+IC4uLgo+IAo+ID4gK3N0YXRpYyBpbmxpbmUgaW50Cj4g PiArZ3J1Yl9mMmZzX3Rlc3RfYml0IChncnViX3VpbnQzMl90IG5yLCBjb25zdCBjaGFyICpwKQo+ ID4gK3sKPiA+ICsgIGludCBtYXNrOwo+ID4gKwo+ID4gKyAgcCArPSAobnIgPj4gMyk7Cj4gPiAr ICBtYXNrID0gMSA8PCAoNyAtIChuciAmIDB4MDcpKTsKPiA+ICsgIHJldHVybiAobWFzayAmICpw KSAhPSAwOwo+IAo+IFRoaXMgaXMgcmVhbGx5IGp1c3QgInJldHVybiBtYXNrICYgKnAiLgoKT2th eS4KCj4gCj4gPiArfQo+ID4gKwo+ID4gK3N0YXRpYyBpbnQKPiA+ICtncnViX2YyZnNfc2FuaXR5 X2NoZWNrX3NiIChzdHJ1Y3QgZ3J1Yl9mMmZzX3N1cGVyYmxvY2sgKnNiKQo+ID4gK3sKPiA+ICsg IGdydWJfdWludDMyX3QgbG9nX3NlY3RvcnNpemUsIGxvZ19zZWN0b3JzX3Blcl9ibG9jazsKPiA+ ICsKPiA+ICsgIGlmIChzYi0+bWFnaWMgIT0gZ3J1Yl9jcHVfdG9fbGUzMl9jb21waWxlX3RpbWUg KEYyRlNfU1VQRVJfTUFHSUMpKQo+ID4gKyAgICByZXR1cm4gLTE7Cj4gPiArCj4gPiArICBpZiAo c2ItPmxvZ19ibG9ja3NpemUgIT0gZ3J1Yl9jcHVfdG9fbGUzMl9jb21waWxlX3RpbWUgKEYyRlNf QkxLX0JJVFMpKQo+ID4gKyAgICByZXR1cm4gLTE7Cj4gPiArCj4gPiArICBsb2dfc2VjdG9yc2l6 ZSA9IGdydWJfbGVfdG9fY3B1MzIgKHNiLT5sb2dfc2VjdG9yc2l6ZSk7Cj4gPiArICBsb2dfc2Vj dG9yc19wZXJfYmxvY2sgPSBncnViX2xlX3RvX2NwdTMyIChzYi0+bG9nX3NlY3RvcnNfcGVyX2Js b2NrKTsKPiA+ICsKPiA+ICsgIGlmIChsb2dfc2VjdG9yc2l6ZSA+IEYyRlNfTUFYX0xPR19TRUNU T1JfU0laRSkKPiA+ICsgICAgcmV0dXJuIC0xOwo+ID4gKwo+ID4gKyAgaWYgKGxvZ19zZWN0b3Jz aXplIDwgRjJGU19NSU5fTE9HX1NFQ1RPUl9TSVpFKQo+ID4gKyAgICByZXR1cm4gLTE7Cj4gPiAr Cj4gPiArICBpZiAobG9nX3NlY3RvcnNfcGVyX2Jsb2NrICsgbG9nX3NlY3RvcnNpemUgIT0gRjJG U19NQVhfTE9HX1NFQ1RPUl9TSVpFKQo+IAo+IFRoaXMgc291bmRzIGxpa2UgaXQgc2hvdWxkIGFj dHVhbGx5IGJlIEYyRlNfQkxLX0JJVFM7IGF0IGxlYXN0IGFzc3VtaW5nCj4gdGhhdCBGMkZTX01B WF9MT0dfU0VDVE9SX1NJWkUgbWF5IGRpZmZlciBmcm9tIEYyRlNfQkxLX0JJVFMuCj4gCgpZdXAu IEluIG9yZGVyIHRvIGF2b2lkIGNvbmZ1c2lvbiwgSSByZW1vdmVkIEYyRlNfTUFYX0xPR19TRUNU T1JfU0laRS4KCj4gLi4uCj4gCj4gPiArCj4gPiArc3RhdGljIGdydWJfc3NpemVfdAo+ID4gK2dy dWJfZjJmc19yZWFkX2ZpbGUgKGdydWJfZnNoZWxwX25vZGVfdCBub2RlLAo+ID4gKwkJZ3J1Yl9k aXNrX3JlYWRfaG9va190IHJlYWRfaG9vaywgdm9pZCAqcmVhZF9ob29rX2RhdGEsCj4gPiArCQln cnViX29mZl90IHBvcywgZ3J1Yl9zaXplX3QgbGVuLCBjaGFyICpidWYpCj4gPiArewo+ID4gKyAg c3RydWN0IGdydWJfZjJmc19pbm9kZSAqaW5vZGUgPSAmbm9kZS0+aW5vZGUuaTsKPiA+ICsgIGdy dWJfb2ZmX3QgZmlsZXNpemUgPSBncnViX2YyZnNfZmlsZV9zaXplIChpbm9kZSk7Cj4gPiArICBj aGFyICppbmxpbmVfYWRkciA9IF9faW5saW5lX2FkZHIgKGlub2RlKTsKPiA+ICsKPiA+ICsgIGlm IChpbm9kZS0+aV9pbmxpbmUgJiBGMkZTX0lOTElORV9EQVRBKQo+ID4gKyAgICB7Cj4gPiArICAg ICAgaWYgKHBvcyA+IGZpbGVzaXplIHx8IGZpbGVzaXplID4gTUFYX0lOTElORV9EQVRBKQo+ID4g KyAgICAgICAgewo+ID4gKyAgICAgICAgICBncnViX2Vycm9yIChHUlVCX0VSUl9CQURfRlMsICJj b3JydXB0ZWQgaW5saW5lX2RhdGE6IG5lZWQgZnNjayIpOwo+IAo+IAo+IFNvcnJ5IGZvciBjb25m dXNpb24sIG15IGZhdWx0LiBwb3MgPiBmaWxlc2l6ZSB3YXMgT0ssIGJ1dCBmaWxlc2l6ZSA+Cj4g TUFYX0lOTElORV9EQVRBIG5vdC4KCklmIGZpbGVzaXplIGlzIG92ZXIgTUFYX0lOTElORV9EQVRB LCB0aGlzIGZpbGUgaXMgY29ycnVwdGVkIGFzIHdlbGwuCkl0IHdpbGwgY2F1c2UgYm91bmRhcnkg dmlvbGF0aW9uIGR1cmluZyBtZW1jcHkgYmVsb3cuCgo+IAo+IC4uLgo+IAo+ID4gKwo+ID4gKy8q IFRPRE86IG1rZnMuZjJmcyBzdG9yZXMgbGFiZWwgaW4gYSB3cm9uZyB3YXkuIFNob3VsZCBiZSBm aXhlZC4gKi8KPiA+ICtzdGF0aWMgdm9pZAo+ID4gK2dydWJfZjJmc191bmljb2RlX3RvX2FzY2lp IChncnViX3VpbnQ4X3QgKm91dF9idWYsIGdydWJfdWludDE2X3QgKmluX2J1ZikKPiA+ICt7Cj4g PiArICBncnViX3VpbnQxNl90ICpwY2hUZW1wUHRyID0gaW5fYnVmOwo+ID4gKyAgZ3J1Yl91aW50 OF90ICpwd1RlbXBQdHIgPSBvdXRfYnVmOwo+ID4gKwo+ID4gKyAgd2hpbGUgKCpwY2hUZW1wUHRy ICE9ICdcMCcpCj4gPiArICAgIHsKPiA+ICsgICAgICAqcHdUZW1wUHRyID0gKGdydWJfdWludDhf dCkgKnBjaFRlbXBQdHI7Cj4gPiArICAgICAgcGNoVGVtcFB0cisrOwo+ID4gKyAgICAgIHB3VGVt cFB0cisrOwo+ID4gKyAgICB9Cj4gPiArICAqcHdUZW1wUHRyID0gJ1wwJzsKPiA+ICsgIHJldHVy bjsKPiA+ICt9Cj4gCj4gU29ycnksIEkgZG8gbm90IHNlZSBob3cgaXQgY2FuIHdvcmsgb24gYm90 aCBiaWcgYW5kIGxpdHRsZSBlbmRpYW4KPiBwbGF0Zm9ybXMuIFdoYXQgYnl0ZSBvcmRlciBpcyB1 c2VkIGZvciBvbi1kaXNrIGxhYmVsPyBXaHkgY2Fubm90IHlvdSB1c2UKPiBncnViX3V0ZjE2X3Rv X3V0ZjggYXMgSSBhc2tlZCBsYXN0IHRpbWU/Cj4gCj4gQWxzbyBwbGVhc2UgYWRkIGJ1bmRhcnkg Y2hlY2ssIGRvIG5vdCByZWx5IG9uIGNvcnJlY3QgY29udGVudC4KCkdvdCBpdC4gSSByZWZhY3Rv cmVkIHRoaXMgaGVyZSBhbmQgaW4gZjJmcy10b29scyBhcyB3ZWxsLgpDb3VsZCB5b3UgY2hlY2sg djQ/CgpUaGFua3MsCgo+IAo+IAo+IAo+IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQo+IF9fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCj4gTGludXgtZjJmcy1kZXZl bCBtYWlsaW5nIGxpc3QKPiBMaW51eC1mMmZzLWRldmVsQGxpc3RzLnNvdXJjZWZvcmdlLm5ldAo+ IGh0dHBzOi8vbGlzdHMuc291cmNlZm9yZ2UubmV0L2xpc3RzL2xpc3RpbmZvL2xpbnV4LWYyZnMt ZGV2ZWwKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpfX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fXwpMaW51eC1mMmZzLWRldmVsIG1haWxpbmcgbGlzdApMaW51eC1m MmZzLWRldmVsQGxpc3RzLnNvdXJjZWZvcmdlLm5ldApodHRwczovL2xpc3RzLnNvdXJjZWZvcmdl Lm5ldC9saXN0cy9saXN0aW5mby9saW51eC1mMmZzLWRldmVsCg==